[torque] Support non-tagged fields in classes
In the process add missing base Torque functionality for 8-bit and 16-bit integers and Cast<> operators to make them easy to use. As a poster child, port the field declarations of SharedFunctionInfo to the class definition in base.tq. As a drive by: Add the missing GN dependency on class-definitions-from-dsl.h Bug: v8:7793 Change-Id: I76a41c2e81ffd1cbb90ac7a4ef8d4003ac86e8dc Reviewed-on: https://chromium-review.googlesource.com/c/1445882 Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Daniel Clifford <danno@chromium.org> Cr-Commit-Position: refs/heads/master@{#59321}
This commit is contained in:
parent
dc4c8bdb05
commit
a177078acd
1
BUILD.gn
1
BUILD.gn
@ -930,6 +930,7 @@ action("run_torque") {
|
|||||||
|
|
||||||
outputs = [
|
outputs = [
|
||||||
"$target_gen_dir/torque-generated/builtin-definitions-from-dsl.h",
|
"$target_gen_dir/torque-generated/builtin-definitions-from-dsl.h",
|
||||||
|
"$target_gen_dir/torque-generated/class-definitions-from-dsl.h",
|
||||||
]
|
]
|
||||||
foreach(namespace, torque_namespaces) {
|
foreach(namespace, torque_namespaces) {
|
||||||
outputs += [
|
outputs += [
|
||||||
|
@ -28,7 +28,7 @@ namespace arguments {
|
|||||||
|
|
||||||
const shared: SharedFunctionInfo = f.shared_function_info;
|
const shared: SharedFunctionInfo = f.shared_function_info;
|
||||||
const formalParameterCount: bint =
|
const formalParameterCount: bint =
|
||||||
Convert<bint>(shared.formal_parameter_count);
|
Convert<bint>(Convert<int32>(shared.formal_parameter_count));
|
||||||
let argumentCount: bint = formalParameterCount;
|
let argumentCount: bint = formalParameterCount;
|
||||||
|
|
||||||
const adaptor: ArgumentsAdaptorFrame =
|
const adaptor: ArgumentsAdaptorFrame =
|
||||||
|
@ -28,6 +28,17 @@ class HeapObject extends Tagged {
|
|||||||
type Object = Smi | HeapObject;
|
type Object = Smi | HeapObject;
|
||||||
type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
|
type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
|
||||||
type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t';
|
type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t';
|
||||||
|
type int31 extends int32
|
||||||
|
generates 'TNode<Int32T>' constexpr 'int31_t';
|
||||||
|
type uint31 extends uint32
|
||||||
|
generates 'TNode<Uint32T>' constexpr 'uint31_t';
|
||||||
|
type int16 extends int31
|
||||||
|
generates 'TNode<Int32T>' constexpr 'int16_t';
|
||||||
|
type uint16 extends uint31
|
||||||
|
generates 'TNode<Uint32T>' constexpr 'uint16_t';
|
||||||
|
type int8 extends int16 generates 'TNode<Int32T>' constexpr 'int8_t';
|
||||||
|
type uint8 extends uint16
|
||||||
|
generates 'TNode<Uint32T>' constexpr 'uint8_t';
|
||||||
type int64 generates 'TNode<Int64T>' constexpr 'int64_t';
|
type int64 generates 'TNode<Int64T>' constexpr 'int64_t';
|
||||||
type intptr generates 'TNode<IntPtrT>' constexpr 'intptr_t';
|
type intptr generates 'TNode<IntPtrT>' constexpr 'intptr_t';
|
||||||
type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t';
|
type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t';
|
||||||
@ -37,8 +48,6 @@ type bool generates 'TNode<BoolT>' constexpr 'bool';
|
|||||||
type bint generates 'TNode<BInt>' constexpr 'BInt';
|
type bint generates 'TNode<BInt>' constexpr 'BInt';
|
||||||
type string constexpr 'const char*';
|
type string constexpr 'const char*';
|
||||||
|
|
||||||
type int31 extends int32
|
|
||||||
generates 'TNode<Int32T>' constexpr 'int31_t';
|
|
||||||
type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
|
type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
|
||||||
type AbstractCode extends HeapObject generates 'TNode<AbstractCode>';
|
type AbstractCode extends HeapObject generates 'TNode<AbstractCode>';
|
||||||
type Code extends AbstractCode generates 'TNode<Code>';
|
type Code extends AbstractCode generates 'TNode<Code>';
|
||||||
@ -124,8 +133,28 @@ transient type FastJSArrayForCopy extends FastJSArray
|
|||||||
transient type FastJSArrayWithNoCustomIteration extends FastJSArray
|
transient type FastJSArrayWithNoCustomIteration extends FastJSArray
|
||||||
generates 'TNode<JSArray>';
|
generates 'TNode<JSArray>';
|
||||||
|
|
||||||
type SharedFunctionInfo extends HeapObject
|
type NoSharedNameSentinel extends Smi;
|
||||||
generates 'TNode<SharedFunctionInfo>';
|
type Script extends HeapObject;
|
||||||
|
type DebugInfo extends HeapObject;
|
||||||
|
|
||||||
|
type ScopeInfo extends Object generates 'TNode<ScopeInfo>';
|
||||||
|
|
||||||
|
class SharedFunctionInfo extends HeapObject {
|
||||||
|
weak function_data: Object;
|
||||||
|
name_or_scope_info: String | NoSharedNameSentinel | ScopeInfo;
|
||||||
|
outer_scope_info_or_feedback_metadata: HeapObject;
|
||||||
|
script_or_debug_info: Script | DebugInfo;
|
||||||
|
length: int16;
|
||||||
|
formal_parameter_count: uint16;
|
||||||
|
expected_nof_properties: int8;
|
||||||
|
builtin_function_id: int8;
|
||||||
|
function_token_offset: int16;
|
||||||
|
flags: int32;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SharedFunctionInfoWithID extends SharedFunctionInfo {
|
||||||
|
unique_id: int32;
|
||||||
|
}
|
||||||
|
|
||||||
class JSFunction extends JSObject {
|
class JSFunction extends JSObject {
|
||||||
shared_function_info: SharedFunctionInfo;
|
shared_function_info: SharedFunctionInfo;
|
||||||
@ -135,9 +164,6 @@ class JSFunction extends JSObject {
|
|||||||
weak prototype_or_initial_map: JSReceiver | Map;
|
weak prototype_or_initial_map: JSReceiver | Map;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern operator '.formal_parameter_count'
|
|
||||||
macro LoadSharedFunctionInfoFormalParameterCount(SharedFunctionInfo): int32;
|
|
||||||
|
|
||||||
class JSBoundFunction extends JSObject {
|
class JSBoundFunction extends JSObject {
|
||||||
bound_target_function: JSReceiver;
|
bound_target_function: JSReceiver;
|
||||||
bound_this: Object;
|
bound_this: Object;
|
||||||
@ -870,9 +896,13 @@ extern macro ChangeUint32ToTagged(uint32): Number;
|
|||||||
extern macro ChangeUintPtrToFloat64(uintptr): float64;
|
extern macro ChangeUintPtrToFloat64(uintptr): float64;
|
||||||
extern macro ChangeUintPtrToTagged(uintptr): Number;
|
extern macro ChangeUintPtrToTagged(uintptr): Number;
|
||||||
extern macro Unsigned(int32): uint32;
|
extern macro Unsigned(int32): uint32;
|
||||||
|
extern macro Unsigned(int16): uint16;
|
||||||
|
extern macro Unsigned(int8): uint8;
|
||||||
extern macro Unsigned(intptr): uintptr;
|
extern macro Unsigned(intptr): uintptr;
|
||||||
extern macro Unsigned(RawPtr): uintptr;
|
extern macro Unsigned(RawPtr): uintptr;
|
||||||
extern macro Signed(uint32): int32;
|
extern macro Signed(uint32): int32;
|
||||||
|
extern macro Signed(uint16): int16;
|
||||||
|
extern macro Signed(uint8): int8;
|
||||||
extern macro Signed(uintptr): intptr;
|
extern macro Signed(uintptr): intptr;
|
||||||
extern macro Signed(RawPtr): intptr;
|
extern macro Signed(RawPtr): intptr;
|
||||||
extern macro TruncateIntPtrToInt32(intptr): int32;
|
extern macro TruncateIntPtrToInt32(intptr): int32;
|
||||||
@ -1020,6 +1050,15 @@ Convert<Smi, uint32>(ui: uint32): Smi {
|
|||||||
Convert<uintptr, uint32>(ui: uint32): uintptr {
|
Convert<uintptr, uint32>(ui: uint32): uintptr {
|
||||||
return ChangeUint32ToWord(ui);
|
return ChangeUint32ToWord(ui);
|
||||||
}
|
}
|
||||||
|
Convert<int32, uint8>(i: uint8): int32 {
|
||||||
|
return Signed(Convert<uint32>(i));
|
||||||
|
}
|
||||||
|
Convert<int32, uint16>(i: uint16): int32 {
|
||||||
|
return Signed(Convert<uint32>(i));
|
||||||
|
}
|
||||||
|
Convert<int32, uint31>(i: uint31): int32 {
|
||||||
|
return Signed(Convert<uint32>(i));
|
||||||
|
}
|
||||||
Convert<int32, intptr>(i: intptr): int32 {
|
Convert<int32, intptr>(i: intptr): int32 {
|
||||||
return TruncateIntPtrToInt32(i);
|
return TruncateIntPtrToInt32(i);
|
||||||
}
|
}
|
||||||
|
@ -1180,13 +1180,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray(
|
TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray(
|
||||||
SloppyTNode<SharedFunctionInfo> shared);
|
SloppyTNode<SharedFunctionInfo> shared);
|
||||||
|
|
||||||
TNode<Int32T> LoadSharedFunctionInfoFormalParameterCount(
|
|
||||||
TNode<SharedFunctionInfo> function) {
|
|
||||||
return TNode<Int32T>::UncheckedCast(LoadObjectField(
|
|
||||||
function, SharedFunctionInfo::kFormalParameterCountOffset,
|
|
||||||
MachineType::Uint16()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoreObjectByteNoWriteBarrier(TNode<HeapObject> object, int offset,
|
void StoreObjectByteNoWriteBarrier(TNode<HeapObject> object, int offset,
|
||||||
TNode<Word32T> value);
|
TNode<Word32T> value);
|
||||||
|
|
||||||
|
@ -3675,7 +3675,8 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
|||||||
}
|
}
|
||||||
share->set_script_or_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
|
share->set_script_or_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||||
#if V8_SFI_HAS_UNIQUE_ID
|
#if V8_SFI_HAS_UNIQUE_ID
|
||||||
share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
|
Handle<SharedFunctionInfoWithID>::cast(share)->set_unique_id(
|
||||||
|
isolate()->GetNextUniqueSharedFunctionInfoId());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set integer fields (smi or int, depending on the architecture).
|
// Set integer fields (smi or int, depending on the architecture).
|
||||||
|
@ -496,8 +496,13 @@ bool Heap::CreateInitialMaps() {
|
|||||||
ALLOCATE_MAP(UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
|
ALLOCATE_MAP(UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
|
||||||
UncompiledDataWithPreparseData::kSize,
|
UncompiledDataWithPreparseData::kSize,
|
||||||
uncompiled_data_with_preparse_data)
|
uncompiled_data_with_preparse_data)
|
||||||
|
#if V8_SFI_HAS_UNIQUE_ID
|
||||||
|
ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE,
|
||||||
|
SharedFunctionInfoWithID::kAlignedSize, shared_function_info)
|
||||||
|
#else
|
||||||
ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
|
ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
|
||||||
shared_function_info)
|
shared_function_info)
|
||||||
|
#endif
|
||||||
|
|
||||||
ALLOCATE_MAP(CODE_DATA_CONTAINER_TYPE, CodeDataContainer::kSize,
|
ALLOCATE_MAP(CODE_DATA_CONTAINER_TYPE, CodeDataContainer::kSize,
|
||||||
code_data_container)
|
code_data_container)
|
||||||
|
@ -1664,7 +1664,7 @@ void Logger::MapEvent(const char* type, Map from, Map to, const char* reason,
|
|||||||
SharedFunctionInfo sfi = SharedFunctionInfo::cast(name_or_sfi);
|
SharedFunctionInfo sfi = SharedFunctionInfo::cast(name_or_sfi);
|
||||||
msg << sfi->DebugName();
|
msg << sfi->DebugName();
|
||||||
#if V8_SFI_HAS_UNIQUE_ID
|
#if V8_SFI_HAS_UNIQUE_ID
|
||||||
msg << " " << sfi->unique_id();
|
msg << " " << SharedFunctionInfoWithID::cast(sfi)->unique_id();
|
||||||
#endif // V8_SFI_HAS_UNIQUE_ID
|
#endif // V8_SFI_HAS_UNIQUE_ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,8 +247,7 @@ class SharedFunctionInfo::BodyDescriptor final : public BodyDescriptorBase {
|
|||||||
static inline void IterateBody(Map map, HeapObject obj, int object_size,
|
static inline void IterateBody(Map map, HeapObject obj, int object_size,
|
||||||
ObjectVisitor* v) {
|
ObjectVisitor* v) {
|
||||||
IterateCustomWeakPointer(obj, kFunctionDataOffset, v);
|
IterateCustomWeakPointer(obj, kFunctionDataOffset, v);
|
||||||
IteratePointers(obj,
|
IteratePointers(obj, SharedFunctionInfo::kStartOfStrongFieldsOffset,
|
||||||
SharedFunctionInfo::kStartOfAlwaysStrongPointerFieldsOffset,
|
|
||||||
SharedFunctionInfo::kEndOfTaggedFieldsOffset, v);
|
SharedFunctionInfo::kEndOfTaggedFieldsOffset, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,15 +124,13 @@ ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
|
|||||||
ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
|
ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
|
||||||
kScriptOrDebugInfoOffset)
|
kScriptOrDebugInfoOffset)
|
||||||
|
|
||||||
#if V8_SFI_HAS_UNIQUE_ID
|
|
||||||
INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
|
|
||||||
#endif
|
|
||||||
UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
|
UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
|
||||||
UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
|
UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
|
||||||
kFormalParameterCountOffset)
|
kFormalParameterCountOffset)
|
||||||
UINT8_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
|
UINT8_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
|
||||||
kExpectedNofPropertiesOffset)
|
kExpectedNofPropertiesOffset)
|
||||||
UINT8_ACCESSORS(SharedFunctionInfo, raw_builtin_function_id, kBuiltinFunctionId)
|
UINT8_ACCESSORS(SharedFunctionInfo, raw_builtin_function_id,
|
||||||
|
kBuiltinFunctionIdOffset)
|
||||||
UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
|
UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
|
||||||
kFunctionTokenOffsetOffset)
|
kFunctionTokenOffsetOffset)
|
||||||
RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
|
RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
|
||||||
@ -633,6 +631,10 @@ void SharedFunctionInfo::ClearPreparseData() {
|
|||||||
DCHECK(HasUncompiledDataWithoutPreparseData());
|
DCHECK(HasUncompiledDataWithoutPreparseData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfoWithID, SharedFunctionInfo)
|
||||||
|
CAST_ACCESSOR(SharedFunctionInfoWithID)
|
||||||
|
INT_ACCESSORS(SharedFunctionInfoWithID, unique_id, kUniqueIdOffset)
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void UncompiledData::Initialize(
|
void UncompiledData::Initialize(
|
||||||
UncompiledData data, String inferred_name, int start_position,
|
UncompiledData data, String inferred_name, int start_position,
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "src/objects/script.h"
|
#include "src/objects/script.h"
|
||||||
#include "src/objects/smi.h"
|
#include "src/objects/smi.h"
|
||||||
#include "src/objects/struct.h"
|
#include "src/objects/struct.h"
|
||||||
|
#include "torque-generated/class-definitions-from-dsl.h"
|
||||||
|
|
||||||
// Has to be the last include (doesn't have include guards):
|
// Has to be the last include (doesn't have include guards):
|
||||||
#include "src/objects/object-macros.h"
|
#include "src/objects/object-macros.h"
|
||||||
@ -322,12 +323,6 @@ class SharedFunctionInfo : public HeapObject {
|
|||||||
// function. The value is only reliable when the function has been compiled.
|
// function. The value is only reliable when the function has been compiled.
|
||||||
DECL_UINT8_ACCESSORS(expected_nof_properties)
|
DECL_UINT8_ACCESSORS(expected_nof_properties)
|
||||||
|
|
||||||
#if V8_SFI_HAS_UNIQUE_ID
|
|
||||||
// [unique_id] - For --trace-maps purposes, an identifier that's persistent
|
|
||||||
// even if the GC moves this SharedFunctionInfo.
|
|
||||||
DECL_INT_ACCESSORS(unique_id)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [function data]: This field holds some additional data for function.
|
// [function data]: This field holds some additional data for function.
|
||||||
// Currently it has one of:
|
// Currently it has one of:
|
||||||
// - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
|
// - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
|
||||||
@ -647,37 +642,8 @@ class SharedFunctionInfo : public HeapObject {
|
|||||||
static const uint16_t kFunctionTokenOutOfRange = static_cast<uint16_t>(-1);
|
static const uint16_t kFunctionTokenOutOfRange = static_cast<uint16_t>(-1);
|
||||||
STATIC_ASSERT(kMaximumFunctionTokenOffset + 1 == kFunctionTokenOutOfRange);
|
STATIC_ASSERT(kMaximumFunctionTokenOffset + 1 == kFunctionTokenOutOfRange);
|
||||||
|
|
||||||
#if V8_SFI_HAS_UNIQUE_ID
|
|
||||||
static const int kUniqueIdFieldSize = kInt32Size;
|
|
||||||
#else
|
|
||||||
// Just to not break the postmortrem support with conditional offsets
|
|
||||||
static const int kUniqueIdFieldSize = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Layout description.
|
|
||||||
#define SHARED_FUNCTION_INFO_FIELDS(V) \
|
|
||||||
/* Pointer fields. */ \
|
|
||||||
V(kStartOfPointerFieldsOffset, 0) \
|
|
||||||
V(kFunctionDataOffset, kTaggedSize) \
|
|
||||||
V(kStartOfAlwaysStrongPointerFieldsOffset, 0) \
|
|
||||||
V(kNameOrScopeInfoOffset, kTaggedSize) \
|
|
||||||
V(kOuterScopeInfoOrFeedbackMetadataOffset, kTaggedSize) \
|
|
||||||
V(kScriptOrDebugInfoOffset, kTaggedSize) \
|
|
||||||
V(kEndOfTaggedFieldsOffset, 0) \
|
|
||||||
/* Raw data fields. */ \
|
|
||||||
V(kUniqueIdOffset, kUniqueIdFieldSize) \
|
|
||||||
V(kLengthOffset, kUInt16Size) \
|
|
||||||
V(kFormalParameterCountOffset, kUInt16Size) \
|
|
||||||
V(kExpectedNofPropertiesOffset, kUInt8Size) \
|
|
||||||
V(kBuiltinFunctionId, kUInt8Size) \
|
|
||||||
V(kFunctionTokenOffsetOffset, kUInt16Size) \
|
|
||||||
V(kFlagsOffset, kInt32Size) \
|
|
||||||
/* Total size. */ \
|
|
||||||
V(kSize, 0)
|
|
||||||
|
|
||||||
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
|
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
|
||||||
SHARED_FUNCTION_INFO_FIELDS)
|
SHARED_FUNCTION_INFO_FIELDS)
|
||||||
#undef SHARED_FUNCTION_INFO_FIELDS
|
|
||||||
|
|
||||||
static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
|
static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
|
||||||
|
|
||||||
@ -720,6 +686,14 @@ class SharedFunctionInfo : public HeapObject {
|
|||||||
// This is needed to set up the [[HomeObject]] on the function instance.
|
// This is needed to set up the [[HomeObject]] on the function instance.
|
||||||
inline bool needs_home_object() const;
|
inline bool needs_home_object() const;
|
||||||
|
|
||||||
|
V8_INLINE bool IsSharedFunctionInfoWithID() const {
|
||||||
|
#if V8_SFI_HAS_UNIQUE_ID
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// [name_or_scope_info]: Function name string, kNoSharedNameSentinel or
|
// [name_or_scope_info]: Function name string, kNoSharedNameSentinel or
|
||||||
// ScopeInfo.
|
// ScopeInfo.
|
||||||
@ -746,6 +720,22 @@ class SharedFunctionInfo : public HeapObject {
|
|||||||
OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
|
OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SharedFunctionInfoWithID : public SharedFunctionInfo {
|
||||||
|
public:
|
||||||
|
// [unique_id] - For --trace-maps purposes, an identifier that's persistent
|
||||||
|
// even if the GC moves this SharedFunctionInfo.
|
||||||
|
DECL_INT_ACCESSORS(unique_id)
|
||||||
|
|
||||||
|
DECL_CAST(SharedFunctionInfoWithID)
|
||||||
|
|
||||||
|
DEFINE_FIELD_OFFSET_CONSTANTS(SharedFunctionInfo::kSize,
|
||||||
|
SHARED_FUNCTION_INFO_WITH_ID_FIELDS)
|
||||||
|
|
||||||
|
static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
|
||||||
|
|
||||||
|
OBJECT_CONSTRUCTORS(SharedFunctionInfoWithID, SharedFunctionInfo)
|
||||||
|
};
|
||||||
|
|
||||||
// Printing support.
|
// Printing support.
|
||||||
struct SourceCodeOf {
|
struct SourceCodeOf {
|
||||||
explicit SourceCodeOf(SharedFunctionInfo v, int max = -1)
|
explicit SourceCodeOf(SharedFunctionInfo v, int max = -1)
|
||||||
|
@ -683,17 +683,21 @@ void CSAGenerator::EmitInstruction(
|
|||||||
const Field& field =
|
const Field& field =
|
||||||
instruction.class_type->LookupField(instruction.field_name);
|
instruction.class_type->LookupField(instruction.field_name);
|
||||||
std::string result_name = FreshNodeName();
|
std::string result_name = FreshNodeName();
|
||||||
std::string type_string =
|
|
||||||
field.name_and_type.type->IsSubtypeOf(TypeOracle::GetSmiType())
|
size_t field_size;
|
||||||
? "MachineType::TaggedSigned()"
|
std::string size_string;
|
||||||
: "MachineType::AnyTagged()";
|
std::string machine_type;
|
||||||
|
std::tie(field_size, size_string, machine_type) =
|
||||||
|
field.GetFieldSizeInformation();
|
||||||
|
|
||||||
out_ << field.name_and_type.type->GetGeneratedTypeName() << " " << result_name
|
out_ << field.name_and_type.type->GetGeneratedTypeName() << " " << result_name
|
||||||
<< " = "
|
<< " = "
|
||||||
<< "ca_.UncheckedCast<"
|
<< "ca_.UncheckedCast<"
|
||||||
<< field.name_and_type.type->GetGeneratedTNodeTypeName()
|
<< field.name_and_type.type->GetGeneratedTNodeTypeName()
|
||||||
<< ">(CodeStubAssembler(state_).LoadObjectField("
|
<< ">(CodeStubAssembler(state_).LoadObjectField("
|
||||||
<< stack->Top() + ", " + std::to_string(field.offset) + ", "
|
<< stack->Top() + ", " + field.aggregate->GetGeneratedTNodeTypeName() +
|
||||||
<< type_string + "));\n";
|
"::k" + CamelifyString(field.name_and_type.name) + "Offset, "
|
||||||
|
<< machine_type + "));\n";
|
||||||
stack->Poke(stack->AboveTop() - 1, result_name);
|
stack->Poke(stack->AboveTop() - 1, result_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "src/torque/declarable.h"
|
#include "src/torque/declarable.h"
|
||||||
|
#include "src/torque/global-context.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -95,6 +96,12 @@ base::Optional<TypeVector> Generic::InferSpecializationTypes(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Namespace::IsDefaultNamespace() const {
|
||||||
|
return this == GlobalContext::GetDefaultNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Namespace::IsTestNamespace() const { return name() == kTestNamespaceName; }
|
||||||
|
|
||||||
} // namespace torque
|
} // namespace torque
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -158,6 +158,8 @@ class Namespace : public Scope {
|
|||||||
std::string ExternalName() const {
|
std::string ExternalName() const {
|
||||||
return CamelifyString(name()) + "BuiltinsFromDSLAssembler";
|
return CamelifyString(name()) + "BuiltinsFromDSLAssembler";
|
||||||
}
|
}
|
||||||
|
bool IsDefaultNamespace() const;
|
||||||
|
bool IsTestNamespace() const;
|
||||||
std::ostream& source_stream() { return source_stream_; }
|
std::ostream& source_stream() { return source_stream_; }
|
||||||
std::ostream& header_stream() { return header_stream_; }
|
std::ostream& header_stream() { return header_stream_; }
|
||||||
std::string source() { return source_stream_.str(); }
|
std::string source() { return source_stream_.str(); }
|
||||||
|
@ -515,6 +515,7 @@ void DeclarationVisitor::FinalizeStructFieldsAndMethods(
|
|||||||
for (auto& field : struct_declaration->fields) {
|
for (auto& field : struct_declaration->fields) {
|
||||||
const Type* field_type = Declarations::GetType(field.name_and_type.type);
|
const Type* field_type = Declarations::GetType(field.name_and_type.type);
|
||||||
struct_type->RegisterField({field.name_and_type.type->pos,
|
struct_type->RegisterField({field.name_and_type.type->pos,
|
||||||
|
struct_type,
|
||||||
{field.name_and_type.name, field_type},
|
{field.name_and_type.name, field_type},
|
||||||
offset,
|
offset,
|
||||||
false});
|
false});
|
||||||
@ -528,40 +529,29 @@ void DeclarationVisitor::FinalizeClassFieldsAndMethods(
|
|||||||
ClassType* class_type, ClassDeclaration* class_declaration) {
|
ClassType* class_type, ClassDeclaration* class_declaration) {
|
||||||
const ClassType* super_class = class_type->GetSuperClass();
|
const ClassType* super_class = class_type->GetSuperClass();
|
||||||
size_t class_offset = super_class ? super_class->size() : 0;
|
size_t class_offset = super_class ? super_class->size() : 0;
|
||||||
bool seen_strong = false;
|
for (ClassFieldExpression& field_expression : class_declaration->fields) {
|
||||||
bool seen_weak = false;
|
|
||||||
for (ClassFieldExpression& field : class_declaration->fields) {
|
|
||||||
CurrentSourcePosition::Scope position_activator(
|
CurrentSourcePosition::Scope position_activator(
|
||||||
field.name_and_type.type->pos);
|
field_expression.name_and_type.type->pos);
|
||||||
const Type* field_type = Declarations::GetType(field.name_and_type.type);
|
const Type* field_type =
|
||||||
if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
Declarations::GetType(field_expression.name_and_type.type);
|
||||||
if (field.weak) {
|
const Field& field = class_type->RegisterField(
|
||||||
seen_weak = true;
|
{field_expression.name_and_type.type->pos,
|
||||||
} else {
|
class_type,
|
||||||
if (seen_weak) {
|
{field_expression.name_and_type.name, field_type},
|
||||||
ReportError("cannot declare strong field \"",
|
class_offset,
|
||||||
field.name_and_type.name,
|
field_expression.weak});
|
||||||
"\" after weak Tagged references");
|
size_t field_size;
|
||||||
}
|
std::string size_string;
|
||||||
seen_strong = true;
|
std::string machine_type;
|
||||||
}
|
std::tie(field_size, size_string, machine_type) =
|
||||||
} else {
|
field.GetFieldSizeInformation();
|
||||||
if (seen_strong || seen_weak) {
|
size_t aligned_offset = class_offset & ~(field_size - 1);
|
||||||
ReportError("cannot declare scalar field \"", field.name_and_type.name,
|
if (class_offset != aligned_offset) {
|
||||||
"\" after strong or weak Tagged references");
|
ReportError("field ", field_expression.name_and_type.name,
|
||||||
}
|
" is not aligned to its size (", aligned_offset, " vs ",
|
||||||
|
class_offset, " for field size ", field_size, ")");
|
||||||
}
|
}
|
||||||
if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
class_offset += field_size;
|
||||||
ReportError(
|
|
||||||
"field \"", field.name_and_type.name, "\" of class \"",
|
|
||||||
class_declaration->name,
|
|
||||||
"\" must be a subtype of Tagged (other types not yet supported)");
|
|
||||||
}
|
|
||||||
class_type->RegisterField({field.name_and_type.type->pos,
|
|
||||||
{field.name_and_type.name, field_type},
|
|
||||||
class_offset,
|
|
||||||
field.weak});
|
|
||||||
class_offset += kTaggedSize;
|
|
||||||
}
|
}
|
||||||
class_type->SetSize(class_offset);
|
class_type->SetSize(class_offset);
|
||||||
|
|
||||||
@ -579,6 +569,7 @@ void DeclarationVisitor::FinalizeClassFieldsAndMethods(
|
|||||||
super_struct_type = super_class->struct_type();
|
super_struct_type = super_class->struct_type();
|
||||||
this_struct_type->RegisterField(
|
this_struct_type->RegisterField(
|
||||||
{CurrentSourcePosition::Get(),
|
{CurrentSourcePosition::Get(),
|
||||||
|
super_struct_type,
|
||||||
{kConstructorStructSuperFieldName, super_struct_type},
|
{kConstructorStructSuperFieldName, super_struct_type},
|
||||||
struct_offset,
|
struct_offset,
|
||||||
false});
|
false});
|
||||||
@ -587,6 +578,7 @@ void DeclarationVisitor::FinalizeClassFieldsAndMethods(
|
|||||||
for (auto& field : class_type->fields()) {
|
for (auto& field : class_type->fields()) {
|
||||||
const Type* field_type = field.name_and_type.type;
|
const Type* field_type = field.name_and_type.type;
|
||||||
this_struct_type->RegisterField({field.pos,
|
this_struct_type->RegisterField({field.pos,
|
||||||
|
class_type,
|
||||||
{field.name_and_type.name, field_type},
|
{field.name_and_type.name, field_type},
|
||||||
struct_offset,
|
struct_offset,
|
||||||
false});
|
false});
|
||||||
|
@ -22,7 +22,7 @@ class GlobalContext : public ContextualClass<GlobalContext> {
|
|||||||
CurrentSourcePosition::Scope current_source_position(
|
CurrentSourcePosition::Scope current_source_position(
|
||||||
SourcePosition{CurrentSourceFile::Get(), -1, -1});
|
SourcePosition{CurrentSourceFile::Get(), -1, -1});
|
||||||
default_namespace_ =
|
default_namespace_ =
|
||||||
RegisterDeclarable(base::make_unique<Namespace>("base"));
|
RegisterDeclarable(base::make_unique<Namespace>(kBaseNamespaceName));
|
||||||
}
|
}
|
||||||
static Namespace* GetDefaultNamespace() { return Get().default_namespace_; }
|
static Namespace* GetDefaultNamespace() { return Get().default_namespace_; }
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -46,12 +46,11 @@ class GlobalContext : public ContextualClass<GlobalContext> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RegisterClass(const std::string& name,
|
static void RegisterClass(const std::string& name, ClassType* new_class) {
|
||||||
const ClassType* new_class) {
|
|
||||||
Get().classes_[name] = new_class;
|
Get().classes_[name] = new_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::map<std::string, const ClassType*>& GetClasses() {
|
static const std::map<std::string, ClassType*>& GetClasses() {
|
||||||
return Get().classes_;
|
return Get().classes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +71,7 @@ class GlobalContext : public ContextualClass<GlobalContext> {
|
|||||||
Ast ast_;
|
Ast ast_;
|
||||||
std::vector<std::unique_ptr<Declarable>> declarables_;
|
std::vector<std::unique_ptr<Declarable>> declarables_;
|
||||||
std::vector<std::string> cpp_includes_;
|
std::vector<std::string> cpp_includes_;
|
||||||
std::map<std::string, const ClassType*> classes_;
|
std::map<std::string, ClassType*> classes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -74,6 +74,8 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) {
|
|||||||
if (nspace != GlobalContext::GetDefaultNamespace()) {
|
if (nspace != GlobalContext::GetDefaultNamespace()) {
|
||||||
header << "#include \"src/code-stub-assembler.h\"\n";
|
header << "#include \"src/code-stub-assembler.h\"\n";
|
||||||
}
|
}
|
||||||
|
header << "#include \"src/utils.h\"\n";
|
||||||
|
header << "#include \"torque-generated/class-definitions-from-dsl.h\"\n";
|
||||||
header << "\n";
|
header << "\n";
|
||||||
|
|
||||||
header << "namespace v8 {\n"
|
header << "namespace v8 {\n"
|
||||||
@ -147,6 +149,32 @@ void ImplementationVisitor::Visit(NamespaceConstant* decl) {
|
|||||||
|
|
||||||
void ImplementationVisitor::Visit(TypeAlias* alias) {
|
void ImplementationVisitor::Visit(TypeAlias* alias) {
|
||||||
if (alias->IsRedeclaration()) return;
|
if (alias->IsRedeclaration()) return;
|
||||||
|
const ClassType* class_type = ClassType::DynamicCast(alias->type());
|
||||||
|
if (class_type) {
|
||||||
|
// Classes that are in the default namespace are defined in the C++
|
||||||
|
// world and all of their fields and methods are declared explicitly.
|
||||||
|
// Internal classes (e.g. ones used for testing that are not in the default
|
||||||
|
// name space) need to be defined by Torque.
|
||||||
|
// TODO(danno): This is a pretty cheesy hack for now. There should be a more
|
||||||
|
// robust mechanism for this, e.g. declaring classes 'extern' or something.
|
||||||
|
if (class_type->nspace()->IsTestNamespace()) {
|
||||||
|
std::string class_name{
|
||||||
|
class_type->GetSuperClass()->GetGeneratedTNodeTypeName()};
|
||||||
|
header_out() << " class " << class_type->name() << " : public "
|
||||||
|
<< class_name << " {\n";
|
||||||
|
header_out() << " public:\n";
|
||||||
|
header_out() << " DEFINE_FIELD_OFFSET_CONSTANTS(" << class_name
|
||||||
|
<< "::kSize, "
|
||||||
|
<< CapifyStringWithUnderscores(class_type->name())
|
||||||
|
<< "_FIELDS)\n";
|
||||||
|
header_out() << " };\n";
|
||||||
|
} else if (!class_type->nspace()->IsDefaultNamespace()) {
|
||||||
|
ReportError(
|
||||||
|
"classes are currently only supported in the default and test "
|
||||||
|
"namespaces");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
const StructType* struct_type = StructType::DynamicCast(alias->type());
|
const StructType* struct_type = StructType::DynamicCast(alias->type());
|
||||||
if (!struct_type) return;
|
if (!struct_type) return;
|
||||||
const std::string& name = struct_type->name();
|
const std::string& name = struct_type->name();
|
||||||
@ -1224,6 +1252,12 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
|
|||||||
"\" is not");
|
"\" is not");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!class_type->AllowInstantiation()) {
|
||||||
|
// Classes that are only used for testing should never be instantiated.
|
||||||
|
ReportError(*class_type,
|
||||||
|
" cannot be allocated with new (it's used for testing)");
|
||||||
|
}
|
||||||
|
|
||||||
// In order to ensure "atomicity" of object allocation, a class' constructors
|
// In order to ensure "atomicity" of object allocation, a class' constructors
|
||||||
// operate on a per-class internal struct rather than the class directly until
|
// operate on a per-class internal struct rather than the class directly until
|
||||||
// the constructor has successfully completed and all class members are
|
// the constructor has successfully completed and all class members are
|
||||||
@ -2510,6 +2544,79 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(std::string& file_name) {
|
|||||||
ReplaceFileContentsIfDifferent(file_name, new_contents);
|
ReplaceFileContentsIfDifferent(file_name, new_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
enum class FieldSectionType {
|
||||||
|
kNoSection = 0,
|
||||||
|
kWeakSection,
|
||||||
|
kStrongSection,
|
||||||
|
kScalarSection
|
||||||
|
};
|
||||||
|
|
||||||
|
void PossiblyStartTagged(FieldSectionType* section,
|
||||||
|
std::set<FieldSectionType>* completed_sections,
|
||||||
|
std::stringstream* o) {
|
||||||
|
if (completed_sections->count(FieldSectionType::kWeakSection) == 0 &&
|
||||||
|
completed_sections->count(FieldSectionType::kStrongSection) == 0 &&
|
||||||
|
*section != FieldSectionType::kWeakSection &&
|
||||||
|
*section != FieldSectionType::kStrongSection) {
|
||||||
|
*o << "V(kStartOfPointerFieldsOffset, 0) \\\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PossiblyEndTagged(FieldSectionType* section,
|
||||||
|
std::set<FieldSectionType>* completed_sections,
|
||||||
|
std::stringstream* o) {
|
||||||
|
if (completed_sections->count(FieldSectionType::kWeakSection) != 0 &&
|
||||||
|
completed_sections->count(FieldSectionType::kStrongSection) != 0) {
|
||||||
|
*o << "V(kEndOfTaggedFieldsOffset, 0) \\\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessFieldInSection(FieldSectionType* section,
|
||||||
|
std::set<FieldSectionType>* completed_sections,
|
||||||
|
FieldSectionType field_section,
|
||||||
|
std::stringstream* o) {
|
||||||
|
if (*section != FieldSectionType::kNoSection) {
|
||||||
|
if (*section != field_section) {
|
||||||
|
if (completed_sections->count(field_section) != 0) {
|
||||||
|
ReportError("reopening of weak, strong or scalar field section");
|
||||||
|
}
|
||||||
|
completed_sections->insert(*section);
|
||||||
|
if (*section == FieldSectionType::kWeakSection) {
|
||||||
|
*o << "V(kEndOfWeakFieldsOffset, 0) \\\n";
|
||||||
|
PossiblyEndTagged(section, completed_sections, o);
|
||||||
|
} else if (*section == FieldSectionType::kStrongSection) {
|
||||||
|
*o << "V(kEndOfStrongFieldsOffset, 0) \\\n";
|
||||||
|
PossiblyEndTagged(section, completed_sections, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*section != field_section) {
|
||||||
|
if (field_section == FieldSectionType::kWeakSection) {
|
||||||
|
PossiblyStartTagged(section, completed_sections, o);
|
||||||
|
*o << "V(kStartOfWeakFieldsOffset, 0) \\\n";
|
||||||
|
} else if (field_section == FieldSectionType::kStrongSection) {
|
||||||
|
PossiblyStartTagged(section, completed_sections, o);
|
||||||
|
*o << "V(kStartOfStrongFieldsOffset, 0) \\\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*section = field_section;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompleteFieldSection(FieldSectionType* section,
|
||||||
|
std::set<FieldSectionType>* completed_sections,
|
||||||
|
FieldSectionType field_section,
|
||||||
|
std::stringstream* o) {
|
||||||
|
if (completed_sections->count(field_section) == 0) {
|
||||||
|
ProcessFieldInSection(section, completed_sections, field_section, o);
|
||||||
|
ProcessFieldInSection(section, completed_sections,
|
||||||
|
FieldSectionType::kNoSection, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void ImplementationVisitor::GenerateClassDefinitions(std::string& file_name) {
|
void ImplementationVisitor::GenerateClassDefinitions(std::string& file_name) {
|
||||||
std::stringstream new_contents_stream;
|
std::stringstream new_contents_stream;
|
||||||
new_contents_stream << "#ifndef V8_CLASS_BUILTIN_DEFINITIONS_FROM_DSL_H_\n"
|
new_contents_stream << "#ifndef V8_CLASS_BUILTIN_DEFINITIONS_FROM_DSL_H_\n"
|
||||||
@ -2525,24 +2632,44 @@ void ImplementationVisitor::GenerateClassDefinitions(std::string& file_name) {
|
|||||||
new_contents_stream << "#define ";
|
new_contents_stream << "#define ";
|
||||||
new_contents_stream << CapifyStringWithUnderscores(i.first)
|
new_contents_stream << CapifyStringWithUnderscores(i.first)
|
||||||
<< "_FIELDS(V) \\\n";
|
<< "_FIELDS(V) \\\n";
|
||||||
const ClassType* type = i.second;
|
ClassType* type = i.second;
|
||||||
std::vector<Field> fields = type->fields();
|
std::vector<Field> fields = type->fields();
|
||||||
new_contents_stream << "V(kStartOfStrongFieldsOffset, 0) \\\n";
|
FieldSectionType section = FieldSectionType::kNoSection;
|
||||||
|
std::set<FieldSectionType> completed_sections;
|
||||||
for (auto f : fields) {
|
for (auto f : fields) {
|
||||||
if (!f.is_weak) {
|
CurrentSourcePosition::Scope scope(f.pos);
|
||||||
new_contents_stream << "V(k" << CamelifyString(f.name_and_type.name)
|
if (f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
||||||
<< "Offset, kTaggedSize) \\\n";
|
if (f.is_weak) {
|
||||||
|
ProcessFieldInSection(§ion, &completed_sections,
|
||||||
|
FieldSectionType::kWeakSection,
|
||||||
|
&new_contents_stream);
|
||||||
|
} else {
|
||||||
|
ProcessFieldInSection(§ion, &completed_sections,
|
||||||
|
FieldSectionType::kStrongSection,
|
||||||
|
&new_contents_stream);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ProcessFieldInSection(§ion, &completed_sections,
|
||||||
|
FieldSectionType::kScalarSection,
|
||||||
|
&new_contents_stream);
|
||||||
}
|
}
|
||||||
|
size_t field_size;
|
||||||
|
std::string size_string;
|
||||||
|
std::string machine_type;
|
||||||
|
std::tie(field_size, size_string, machine_type) =
|
||||||
|
f.GetFieldSizeInformation();
|
||||||
|
new_contents_stream << "V(k" << CamelifyString(f.name_and_type.name)
|
||||||
|
<< "Offset, " << size_string << ") \\\n";
|
||||||
}
|
}
|
||||||
new_contents_stream << "V(kEndOfStrongFieldsOffset, 0) \\\n";
|
|
||||||
new_contents_stream << "V(kStartOfWeakFieldsOffset, 0) \\\n";
|
ProcessFieldInSection(§ion, &completed_sections,
|
||||||
for (auto f : fields) {
|
FieldSectionType::kNoSection, &new_contents_stream);
|
||||||
if (f.is_weak) {
|
CompleteFieldSection(§ion, &completed_sections,
|
||||||
new_contents_stream << "V(k" << CamelifyString(f.name_and_type.name)
|
FieldSectionType::kWeakSection, &new_contents_stream);
|
||||||
<< "Offset, kTaggedSize) \\\n";
|
CompleteFieldSection(§ion, &completed_sections,
|
||||||
}
|
FieldSectionType::kStrongSection,
|
||||||
}
|
&new_contents_stream);
|
||||||
new_contents_stream << "V(kEndOfWeakFieldsOffset, 0) \\\n";
|
|
||||||
new_contents_stream << "V(kSize, 0) \\\n";
|
new_contents_stream << "V(kSize, 0) \\\n";
|
||||||
new_contents_stream << "\n";
|
new_contents_stream << "\n";
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,26 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
|||||||
return Get().GetBuiltinType(INT32_TYPE_STRING);
|
return Get().GetBuiltinType(INT32_TYPE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Type* GetUint32Type() {
|
||||||
|
return Get().GetBuiltinType(UINT32_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Type* GetInt16Type() {
|
||||||
|
return Get().GetBuiltinType(INT16_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Type* GetUint16Type() {
|
||||||
|
return Get().GetBuiltinType(UINT16_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Type* GetInt8Type() {
|
||||||
|
return Get().GetBuiltinType(INT8_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Type* GetUint8Type() {
|
||||||
|
return Get().GetBuiltinType(UINT8_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
static const Type* GetNeverType() {
|
static const Type* GetNeverType() {
|
||||||
return Get().GetBuiltinType(NEVER_TYPE_STRING);
|
return Get().GetBuiltinType(NEVER_TYPE_STRING);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "src/globals.h"
|
||||||
#include "src/torque/declarable.h"
|
#include "src/torque/declarable.h"
|
||||||
#include "src/torque/type-oracle.h"
|
#include "src/torque/type-oracle.h"
|
||||||
#include "src/torque/types.h"
|
#include "src/torque/types.h"
|
||||||
@ -78,8 +79,6 @@ std::string AbstractType::GetGeneratedTNodeTypeName() const {
|
|||||||
return generated_type_;
|
return generated_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ClassType::GetGeneratedTNodeTypeName() const { return generates_; }
|
|
||||||
|
|
||||||
std::string BuiltinPointerType::ToExplicitString() const {
|
std::string BuiltinPointerType::ToExplicitString() const {
|
||||||
std::stringstream result;
|
std::stringstream result;
|
||||||
result << "builtin (";
|
result << "builtin (";
|
||||||
@ -262,6 +261,18 @@ std::string StructType::ToExplicitString() const {
|
|||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ClassType::GetGeneratedTNodeTypeName() const {
|
||||||
|
std::string prefix = nspace()->IsDefaultNamespace()
|
||||||
|
? std::string{}
|
||||||
|
: (nspace()->ExternalName() + "::");
|
||||||
|
return prefix + generates_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ClassType::GetGeneratedTypeName() const {
|
||||||
|
return IsConstexpr() ? GetGeneratedTNodeTypeName()
|
||||||
|
: "compiler::TNode<" + GetGeneratedTNodeTypeName() + ">";
|
||||||
|
}
|
||||||
|
|
||||||
std::string ClassType::ToExplicitString() const {
|
std::string ClassType::ToExplicitString() const {
|
||||||
std::stringstream result;
|
std::stringstream result;
|
||||||
result << "class " << name() << "{";
|
result << "class " << name() << "{";
|
||||||
@ -270,6 +281,10 @@ std::string ClassType::ToExplicitString() const {
|
|||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClassType::AllowInstantiation() const {
|
||||||
|
return nspace()->IsDefaultNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
|
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
|
||||||
os << "(";
|
os << "(";
|
||||||
for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
|
for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
|
||||||
@ -469,6 +484,60 @@ VisitResult VisitResult::NeverResult() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<size_t, std::string, std::string> Field::GetFieldSizeInformation()
|
||||||
|
const {
|
||||||
|
std::string size_string = "#no size";
|
||||||
|
std::string machine_type = "#no machine type";
|
||||||
|
const Type* field_type = this->name_and_type.type;
|
||||||
|
size_t field_size = 0;
|
||||||
|
if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
||||||
|
field_size = kTaggedSize;
|
||||||
|
size_string = "kTaggedSize";
|
||||||
|
machine_type = field_type->IsSubtypeOf(TypeOracle::GetSmiType())
|
||||||
|
? "MachineType::TaggedSigned()"
|
||||||
|
: "MachineType::AnyTagged()";
|
||||||
|
} else if (field_type->IsSubtypeOf(TypeOracle::GetRawPtrType())) {
|
||||||
|
field_size = kSystemPointerSize;
|
||||||
|
size_string = "kSystemPointerSize";
|
||||||
|
machine_type = "MachineType::Pointer()";
|
||||||
|
} else if (field_type == TypeOracle::GetInt32Type()) {
|
||||||
|
field_size = kInt32Size;
|
||||||
|
size_string = "kInt32Size";
|
||||||
|
machine_type = "MachineType::Int32()";
|
||||||
|
} else if (field_type == TypeOracle::GetUint32Type()) {
|
||||||
|
field_size = kInt32Size;
|
||||||
|
size_string = "kInt32Size";
|
||||||
|
machine_type = "MachineType::Uint32()";
|
||||||
|
} else if (field_type == TypeOracle::GetInt16Type()) {
|
||||||
|
field_size = kUInt16Size;
|
||||||
|
size_string = "kUInt16Size";
|
||||||
|
machine_type = "MachineType::Int16()";
|
||||||
|
} else if (field_type == TypeOracle::GetUint16Type()) {
|
||||||
|
field_size = kUInt16Size;
|
||||||
|
size_string = "kUInt16Size";
|
||||||
|
machine_type = "MachineType::Uint16()";
|
||||||
|
} else if (field_type == TypeOracle::GetInt8Type()) {
|
||||||
|
field_size = kUInt8Size;
|
||||||
|
size_string = "kUInt8Size";
|
||||||
|
machine_type = "MachineType::Int8()";
|
||||||
|
} else if (field_type == TypeOracle::GetUint8Type()) {
|
||||||
|
field_size = kUInt8Size;
|
||||||
|
size_string = "kUInt8Size";
|
||||||
|
machine_type = "MachineType::Uint8()";
|
||||||
|
} else if (field_type == TypeOracle::GetIntPtrType()) {
|
||||||
|
field_size = kIntptrSize;
|
||||||
|
size_string = "kIntptrSize";
|
||||||
|
machine_type = "MachineType::IntPtr()";
|
||||||
|
} else if (field_type == TypeOracle::GetUIntPtrType()) {
|
||||||
|
field_size = kIntptrSize;
|
||||||
|
size_string = "kIntptrSize";
|
||||||
|
machine_type = "MachineType::IntPtr()";
|
||||||
|
} else {
|
||||||
|
ReportError("fields of type ", *field_type, " are not (yet) supported");
|
||||||
|
}
|
||||||
|
return std::make_tuple(field_size, size_string, machine_type);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace torque
|
} // namespace torque
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -39,10 +39,16 @@ static const char* const BUILTIN_POINTER_TYPE_STRING = "BuiltinPtr";
|
|||||||
static const char* const INTPTR_TYPE_STRING = "intptr";
|
static const char* const INTPTR_TYPE_STRING = "intptr";
|
||||||
static const char* const UINTPTR_TYPE_STRING = "uintptr";
|
static const char* const UINTPTR_TYPE_STRING = "uintptr";
|
||||||
static const char* const INT32_TYPE_STRING = "int32";
|
static const char* const INT32_TYPE_STRING = "int32";
|
||||||
|
static const char* const UINT32_TYPE_STRING = "uint32";
|
||||||
|
static const char* const INT16_TYPE_STRING = "int16";
|
||||||
|
static const char* const UINT16_TYPE_STRING = "uint16";
|
||||||
|
static const char* const INT8_TYPE_STRING = "int8";
|
||||||
|
static const char* const UINT8_TYPE_STRING = "uint8";
|
||||||
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
|
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
|
||||||
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
|
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
|
||||||
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
|
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
|
||||||
|
|
||||||
|
class AggregateType;
|
||||||
class Macro;
|
class Macro;
|
||||||
class Method;
|
class Method;
|
||||||
class StructType;
|
class StructType;
|
||||||
@ -154,7 +160,10 @@ struct NameAndType {
|
|||||||
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type);
|
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type);
|
||||||
|
|
||||||
struct Field {
|
struct Field {
|
||||||
|
std::tuple<size_t, std::string, std::string> GetFieldSizeInformation() const;
|
||||||
|
|
||||||
SourcePosition pos;
|
SourcePosition pos;
|
||||||
|
const AggregateType* aggregate;
|
||||||
NameAndType name_and_type;
|
NameAndType name_and_type;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
bool is_weak;
|
bool is_weak;
|
||||||
@ -402,7 +411,10 @@ class AggregateType : public Type {
|
|||||||
return "_method_" + name_ + "_" + name;
|
return "_method_" + name_ + "_" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterField(Field field) { fields_.push_back(field); }
|
const Field& RegisterField(Field field) {
|
||||||
|
fields_.push_back(field);
|
||||||
|
return fields_.back();
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterMethod(Method* method) { methods_.push_back(method); }
|
void RegisterMethod(Method* method) { methods_.push_back(method); }
|
||||||
std::vector<Method*> Constructors() const;
|
std::vector<Method*> Constructors() const;
|
||||||
@ -454,9 +466,7 @@ class ClassType final : public AggregateType {
|
|||||||
public:
|
public:
|
||||||
DECLARE_TYPE_BOILERPLATE(ClassType);
|
DECLARE_TYPE_BOILERPLATE(ClassType);
|
||||||
std::string ToExplicitString() const override;
|
std::string ToExplicitString() const override;
|
||||||
std::string GetGeneratedTypeName() const override {
|
std::string GetGeneratedTypeName() const override;
|
||||||
return IsConstexpr() ? generates_ : "compiler::TNode<" + generates_ + ">";
|
|
||||||
}
|
|
||||||
std::string GetGeneratedTNodeTypeName() const override;
|
std::string GetGeneratedTNodeTypeName() const override;
|
||||||
bool IsTransient() const override { return transient_; }
|
bool IsTransient() const override { return transient_; }
|
||||||
size_t size() const { return size_; }
|
size_t size() const { return size_; }
|
||||||
@ -467,6 +477,7 @@ class ClassType final : public AggregateType {
|
|||||||
}
|
}
|
||||||
void SetSize(size_t size) { size_ = size; }
|
void SetSize(size_t size) { size_ = size; }
|
||||||
void SetThisStruct(StructType* this_struct) { this_struct_ = this_struct; }
|
void SetThisStruct(StructType* this_struct) { this_struct_ = this_struct; }
|
||||||
|
bool AllowInstantiation() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class TypeOracle;
|
friend class TypeOracle;
|
||||||
|
@ -125,8 +125,9 @@ bool IsKeywordLikeName(const std::string& s) {
|
|||||||
// naming convention and are those exempt from the normal type convention.
|
// naming convention and are those exempt from the normal type convention.
|
||||||
bool IsMachineType(const std::string& s) {
|
bool IsMachineType(const std::string& s) {
|
||||||
static const char* const machine_types[]{
|
static const char* const machine_types[]{
|
||||||
"void", "never", "int32", "uint32", "int64", "intptr", "uintptr",
|
"void", "never", "int8", "uint8", "int16", "uint16",
|
||||||
"float32", "float64", "bool", "string", "bint", "int31"};
|
"int31", "uint31", "int32", "uint32", "int64", "intptr",
|
||||||
|
"uintptr", "float32", "float64", "bool", "string", "bint"};
|
||||||
|
|
||||||
return std::find(std::begin(machine_types), std::end(machine_types), s) !=
|
return std::find(std::begin(machine_types), std::end(machine_types), s) !=
|
||||||
std::end(machine_types);
|
std::end(machine_types);
|
||||||
|
@ -272,6 +272,8 @@ class ToString {
|
|||||||
|
|
||||||
constexpr int kTaggedSize = sizeof(void*);
|
constexpr int kTaggedSize = sizeof(void*);
|
||||||
|
|
||||||
|
static const char* const kBaseNamespaceName = "base";
|
||||||
|
static const char* const kTestNamespaceName = "test";
|
||||||
static const char* const kConstructMethodName = "constructor";
|
static const char* const kConstructMethodName = "constructor";
|
||||||
static const char* const kSuperMethodName = "super";
|
static const char* const kSuperMethodName = "super";
|
||||||
static const char* const kConstructorStructSuperFieldName = "_super";
|
static const char* const kConstructorStructSuperFieldName = "_super";
|
||||||
|
@ -768,4 +768,18 @@ namespace test {
|
|||||||
assert(w.c == 1);
|
assert(w.c == 1);
|
||||||
assert(w.d == 2);
|
assert(w.d == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestClassWithAllTypes extends JSObject {
|
||||||
|
a: int8;
|
||||||
|
b: uint8;
|
||||||
|
b2: uint8;
|
||||||
|
b3: uint8;
|
||||||
|
c: int16;
|
||||||
|
d: uint16;
|
||||||
|
e: int32;
|
||||||
|
f: uint32;
|
||||||
|
g: RawPtr;
|
||||||
|
h: intptr;
|
||||||
|
i: uintptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user