Commit d0e95c7a authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[torque]: Class declarations

Class declarations support structured heap data that is a subtype of
HeapObject. Only fields of Object subtypes (both strong and weak)
are currently supported (no scalar fields yet).

With this CL, both the field list macro used with the C++
DEFINE_FIELD_OFFSET_CONSTANTS macro (to make field offset constants) as
well as the Torque "operator '.field'" macros are generated for the
classes declared in Torque. This is a first step to removing the
substantial amount of duplication and boilerplate code
needed to declare heap object classes.

As a proof of concept, and handful of class field definitions,
including those for non trivial classes like JSFunction, have been
moved to Torque.

Bug: v8:7793
Change-Id: I2fa0b53db65fa6f5fe078fb94e1db3418f908753
Reviewed-on: https://chromium-review.googlesource.com/c/1373971
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58704}
parent bb46048a
...@@ -17,7 +17,11 @@ type never; ...@@ -17,7 +17,11 @@ type never;
type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr'; type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr';
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi'; type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi';
type HeapObject extends Tagged generates 'TNode<HeapObject>';
class HeapObject extends Tagged {
map_untyped: 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';
...@@ -36,8 +40,6 @@ type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*'; ...@@ -36,8 +40,6 @@ 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>';
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>'; type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
type JSReceiver extends HeapObject generates 'TNode<JSReceiver>';
type Constructor extends JSReceiver generates 'TNode<JSReceiver>';
type Context extends HeapObject generates 'TNode<Context>'; type Context extends HeapObject generates 'TNode<Context>';
type NativeContext extends Context generates 'TNode<Context>'; type NativeContext extends Context generates 'TNode<Context>';
type String extends HeapObject generates 'TNode<String>'; type String extends HeapObject generates 'TNode<String>';
...@@ -46,12 +48,39 @@ type HeapNumber extends HeapObject generates 'TNode<HeapNumber>'; ...@@ -46,12 +48,39 @@ type HeapNumber extends HeapObject generates 'TNode<HeapNumber>';
type Number = Smi | HeapNumber; type Number = Smi | HeapNumber;
type BigInt extends HeapObject generates 'TNode<BigInt>'; type BigInt extends HeapObject generates 'TNode<BigInt>';
type Numeric = Number | BigInt; type Numeric = Number | BigInt;
type Map extends HeapObject generates 'TNode<Map>';
// The accessors for HeapObject's map cannot be declared before Map
// is declared because forward declarations are not (yet) supported.
// TODO(danno): Make circular references in classes possible. One way to do that
// would be to pre-process all class declarations and create bindings for them
// with an uninitialized class type, and then process them later properly
extern operator '.map' macro LoadMap(HeapObject): Map;
extern transitioning operator '.map=' macro StoreMap(HeapObject, Map);
type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>';
type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
type FixedDoubleArray extends FixedArrayBase
generates 'TNode<FixedDoubleArray>';
class JSReceiver extends HeapObject {
properties_or_hash: Object;
}
type Constructor extends JSReceiver generates 'TNode<JSReceiver>';
type JSProxy extends JSReceiver generates 'TNode<JSProxy>'; type JSProxy extends JSReceiver generates 'TNode<JSProxy>';
type JSObject extends JSReceiver generates 'TNode<JSObject>';
type JSArgumentsObjectWithLength extends JSObject class JSObject extends JSReceiver {
generates 'TNode<JSArgumentsObjectWithLength>'; elements: FixedArrayBase;
type JSArray extends JSArgumentsObjectWithLength }
generates 'TNode<JSArray>';
class JSArgumentsObjectWithLength extends JSObject {
length: Object;
}
class JSArray extends JSObject {
length: Number;
}
// A HeapObject with a JSArray map, and either fast packed elements, or fast // A HeapObject with a JSArray map, and either fast packed elements, or fast
// holey elements when the global NoElementsProtector is not invalidated. // holey elements when the global NoElementsProtector is not invalidated.
...@@ -69,19 +98,24 @@ transient type FastJSArrayWithNoCustomIteration extends FastJSArray ...@@ -69,19 +98,24 @@ transient type FastJSArrayWithNoCustomIteration extends FastJSArray
type SharedFunctionInfo extends HeapObject type SharedFunctionInfo extends HeapObject
generates 'TNode<SharedFunctionInfo>'; generates 'TNode<SharedFunctionInfo>';
type JSFunction extends JSObject generates 'TNode<JSFunction>'; class JSFunction extends JSObject {
extern operator '.shared_function_info' shared_function_info: SharedFunctionInfo;
macro LoadJSFunctionSharedFunctionInfo(JSFunction): SharedFunctionInfo; context: Context;
feedback_cell: Smi;
weak code: Code;
weak prototype_or_initial_map: JSReceiver | Map;
}
extern operator '.formal_parameter_count' extern operator '.formal_parameter_count'
macro LoadSharedFunctionInfoFormalParameterCount(SharedFunctionInfo): int32; macro LoadSharedFunctionInfoFormalParameterCount(SharedFunctionInfo): int32;
type JSBoundFunction extends JSObject generates 'TNode<JSBoundFunction>'; class JSBoundFunction extends JSObject {
bound_target_function: JSReceiver;
bound_this: Object;
bound_arguments: FixedArray;
}
type Callable = JSFunction | JSBoundFunction | JSProxy; type Callable = JSFunction | JSBoundFunction | JSProxy;
type Map extends HeapObject generates 'TNode<Map>';
type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>';
type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
type FixedDoubleArray extends FixedArrayBase
generates 'TNode<FixedDoubleArray>';
type FixedTypedArrayBase extends FixedArrayBase type FixedTypedArrayBase extends FixedArrayBase
generates 'TNode<FixedTypedArrayBase>'; generates 'TNode<FixedTypedArrayBase>';
type FixedTypedArray extends FixedTypedArrayBase type FixedTypedArray extends FixedTypedArrayBase
...@@ -520,8 +554,6 @@ extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool; ...@@ -520,8 +554,6 @@ extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool;
extern operator '!' macro Word32BinaryNot(bool): bool; extern operator '!' macro Word32BinaryNot(bool): bool;
extern operator '!' macro IsFalse(Boolean): bool; extern operator '!' macro IsFalse(Boolean): bool;
extern operator '.map' macro LoadMap(HeapObject): Map;
extern transitioning operator '.map=' macro StoreMap(HeapObject, Map);
extern operator '.instanceType' macro LoadInstanceType(HeapObject): extern operator '.instanceType' macro LoadInstanceType(HeapObject):
InstanceType; InstanceType;
...@@ -1018,15 +1050,8 @@ extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind; ...@@ -1018,15 +1050,8 @@ extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind;
extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray): extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray):
ElementsKind; ElementsKind;
extern operator '.elements' macro LoadElements(JSObject): FixedArrayBase;
extern operator '.elements=' macro StoreElements(JSObject, FixedArrayBase);
extern operator '.length' macro LoadJSTypedArrayLength(JSTypedArray): Smi; extern operator '.length' macro LoadJSTypedArrayLength(JSTypedArray): Smi;
extern operator '.length' macro LoadJSArrayLength(JSArray): Number;
extern operator '.length' macro LoadJSArgumentsObjectWithLength(
JSArgumentsObjectWithLength): Object;
extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi; extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi;
extern operator '.length=' macro StoreJSArrayLength(JSArray, Smi);
extern operator '.length' macro LoadFixedArrayBaseLength(FixedArrayBase): Smi; extern operator '.length' macro LoadFixedArrayBaseLength(FixedArrayBase): Smi;
extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength( extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength(
...@@ -1055,9 +1080,6 @@ extern macro StoreFixedArrayElementSmi( ...@@ -1055,9 +1080,6 @@ extern macro StoreFixedArrayElementSmi(
extern operator '.instance_type' macro LoadMapInstanceType(Map): int32; extern operator '.instance_type' macro LoadMapInstanceType(Map): int32;
extern operator '.prototype_or_initial_map' macro
LoadJSFunctionPrototypeOrInitialMap(JSFunction): Object;
extern macro LoadFixedDoubleArrayElement(FixedDoubleArray, Smi): float64; extern macro LoadFixedDoubleArrayElement(FixedDoubleArray, Smi): float64;
extern macro Float64SilenceNaN(float64): float64; extern macro Float64SilenceNaN(float64): float64;
......
...@@ -1462,8 +1462,7 @@ TNode<BoolT> CodeStubAssembler::TaggedDoesntHaveInstanceType( ...@@ -1462,8 +1462,7 @@ TNode<BoolT> CodeStubAssembler::TaggedDoesntHaveInstanceType(
TNode<HeapObject> CodeStubAssembler::LoadFastProperties( TNode<HeapObject> CodeStubAssembler::LoadFastProperties(
SloppyTNode<JSObject> object) { SloppyTNode<JSObject> object) {
CSA_SLOW_ASSERT(this, Word32BinaryNot(IsDictionaryMap(LoadMap(object)))); CSA_SLOW_ASSERT(this, Word32BinaryNot(IsDictionaryMap(LoadMap(object))));
TNode<Object> properties = TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object);
LoadObjectField(object, JSObject::kPropertiesOrHashOffset);
return Select<HeapObject>(TaggedIsSmi(properties), return Select<HeapObject>(TaggedIsSmi(properties),
[=] { return EmptyFixedArrayConstant(); }, [=] { return EmptyFixedArrayConstant(); },
[=] { return CAST(properties); }); [=] { return CAST(properties); });
...@@ -1472,18 +1471,12 @@ TNode<HeapObject> CodeStubAssembler::LoadFastProperties( ...@@ -1472,18 +1471,12 @@ TNode<HeapObject> CodeStubAssembler::LoadFastProperties(
TNode<HeapObject> CodeStubAssembler::LoadSlowProperties( TNode<HeapObject> CodeStubAssembler::LoadSlowProperties(
SloppyTNode<JSObject> object) { SloppyTNode<JSObject> object) {
CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object))); CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object)));
TNode<Object> properties = TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object);
LoadObjectField(object, JSObject::kPropertiesOrHashOffset);
return Select<HeapObject>(TaggedIsSmi(properties), return Select<HeapObject>(TaggedIsSmi(properties),
[=] { return EmptyPropertyDictionaryConstant(); }, [=] { return EmptyPropertyDictionaryConstant(); },
[=] { return CAST(properties); }); [=] { return CAST(properties); });
} }
TNode<FixedArrayBase> CodeStubAssembler::LoadElements(
SloppyTNode<JSObject> object) {
return CAST(LoadObjectField(object, JSObject::kElementsOffset));
}
TNode<Number> CodeStubAssembler::LoadJSArrayLength(SloppyTNode<JSArray> array) { TNode<Number> CodeStubAssembler::LoadJSArrayLength(SloppyTNode<JSArray> array) {
CSA_ASSERT(this, IsJSArray(array)); CSA_ASSERT(this, IsJSArray(array));
return CAST(LoadObjectField(array, JSArray::kLengthOffset)); return CAST(LoadObjectField(array, JSArray::kLengthOffset));
......
...@@ -843,7 +843,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -843,7 +843,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSObject> object); TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSObject> object);
TNode<HeapObject> LoadFastProperties(SloppyTNode<JSObject> object); TNode<HeapObject> LoadFastProperties(SloppyTNode<JSObject> object);
// Load the elements backing store of a JSObject. // Load the elements backing store of a JSObject.
TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object); TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object) {
return LoadJSObjectElements(object);
}
// Load the length of a JSArray instance. // Load the length of a JSArray instance.
TNode<Object> LoadJSArgumentsObjectWithLength( TNode<Object> LoadJSArgumentsObjectWithLength(
SloppyTNode<JSArgumentsObjectWithLength> array); SloppyTNode<JSArgumentsObjectWithLength> array);
...@@ -1167,17 +1169,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -1167,17 +1169,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray( TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray(
SloppyTNode<SharedFunctionInfo> shared); SloppyTNode<SharedFunctionInfo> shared);
TNode<Object> LoadJSFunctionPrototypeOrInitialMap(
TNode<JSFunction> function) {
return LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
}
TNode<SharedFunctionInfo> LoadJSFunctionSharedFunctionInfo(
TNode<JSFunction> function) {
return CAST(
LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset));
}
TNode<Int32T> LoadSharedFunctionInfoFormalParameterCount( TNode<Int32T> LoadSharedFunctionInfoFormalParameterCount(
TNode<SharedFunctionInfo> function) { TNode<SharedFunctionInfo> function) {
return TNode<Int32T>::UncheckedCast(LoadObjectField( return TNode<Int32T>::UncheckedCast(LoadObjectField(
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/js-objects.h" #include "src/objects/js-objects.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"
...@@ -35,7 +36,7 @@ class JSArgumentsObjectWithLength : public JSArgumentsObject { ...@@ -35,7 +36,7 @@ class JSArgumentsObjectWithLength : public JSArgumentsObject {
V(kSize, 0) V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
JS_ARGUMENTS_OBJECT_WITH_LENGTH_FIELDS) JSARGUMENTS_OBJECT_WITH_LENGTH_FIELDS)
#undef JS_ARGUMENTS_OBJECT_WITH_LENGTH_FIELDS #undef JS_ARGUMENTS_OBJECT_WITH_LENGTH_FIELDS
// Indices of in-object properties. // Indices of in-object properties.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/objects/allocation-site.h" #include "src/objects/allocation-site.h"
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/js-objects.h" #include "src/objects/js-objects.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"
...@@ -104,13 +105,7 @@ class JSArray : public JSObject { ...@@ -104,13 +105,7 @@ class JSArray : public JSObject {
// Number of element slots to pre-allocate for an empty array. // Number of element slots to pre-allocate for an empty array.
static const int kPreallocatedArrayElements = 4; static const int kPreallocatedArrayElements = 4;
// Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JSARRAY_FIELDS)
#define JS_ARRAY_FIELDS(V) \
V(kLengthOffset, kTaggedSize) \
/* Header size. */ \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_ARRAY_FIELDS)
#undef JS_ARRAY_FIELDS #undef JS_ARRAY_FIELDS
static const int kLengthDescriptorIndex = 0; static const int kLengthDescriptorIndex = 0;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/objects.h" #include "src/objects.h"
#include "src/objects/embedder-data-slot.h" #include "src/objects/embedder-data-slot.h"
#include "src/objects/property-array.h" #include "src/objects/property-array.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"
...@@ -256,14 +257,8 @@ class JSReceiver : public HeapObject { ...@@ -256,14 +257,8 @@ class JSReceiver : public HeapObject {
static const int kHashMask = PropertyArray::HashField::kMask; static const int kHashMask = PropertyArray::HashField::kMask;
// Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, JSRECEIVER_FIELDS)
#define JS_RECEIVER_FIELDS(V) \ static const int kHeaderSize = kSize;
V(kPropertiesOrHashOffset, kTaggedSize) \
/* Header size. */ \
V(kHeaderSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, JS_RECEIVER_FIELDS)
#undef JS_RECEIVER_FIELDS
bool HasProxyInPrototype(Isolate* isolate); bool HasProxyInPrototype(Isolate* isolate);
...@@ -936,15 +931,7 @@ class JSBoundFunction : public JSObject { ...@@ -936,15 +931,7 @@ class JSBoundFunction : public JSObject {
static Handle<String> ToString(Handle<JSBoundFunction> function); static Handle<String> ToString(Handle<JSBoundFunction> function);
// Layout description. // Layout description.
#define JS_BOUND_FUNCTION_FIELDS(V) \ DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JSBOUND_FUNCTION_FIELDS)
V(kBoundTargetFunctionOffset, kTaggedSize) \
V(kBoundThisOffset, kTaggedSize) \
V(kBoundArgumentsOffset, kTaggedSize) \
/* Header size. */ \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_BOUND_FUNCTION_FIELDS)
#undef JS_BOUND_FUNCTION_FIELDS
OBJECT_CONSTRUCTORS(JSBoundFunction, JSObject); OBJECT_CONSTRUCTORS(JSBoundFunction, JSObject);
}; };
...@@ -1137,22 +1124,10 @@ class JSFunction : public JSObject { ...@@ -1137,22 +1124,10 @@ class JSFunction : public JSObject {
// ES6 section 19.2.3.5 Function.prototype.toString ( ). // ES6 section 19.2.3.5 Function.prototype.toString ( ).
static Handle<String> ToString(Handle<JSFunction> function); static Handle<String> ToString(Handle<JSFunction> function);
// Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JSFUNCTION_FIELDS)
#define JS_FUNCTION_FIELDS(V) \
/* Pointer fields. */ \ static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
V(kSharedFunctionInfoOffset, kTaggedSize) \ static constexpr int kSizeWithPrototype = kSize;
V(kContextOffset, kTaggedSize) \
V(kFeedbackCellOffset, kTaggedSize) \
V(kEndOfStrongFieldsOffset, 0) \
V(kCodeOffset, kTaggedSize) \
/* Size of JSFunction object without prototype field. */ \
V(kSizeWithoutPrototype, 0) \
V(kPrototypeOrInitialMapOffset, kTaggedSize) \
/* Size of JSFunction object with prototype field. */ \
V(kSizeWithPrototype, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_FUNCTION_FIELDS)
#undef JS_FUNCTION_FIELDS
OBJECT_CONSTRUCTORS(JSFunction, JSObject); OBJECT_CONSTRUCTORS(JSFunction, JSObject);
}; };
......
...@@ -19,6 +19,8 @@ namespace torque { ...@@ -19,6 +19,8 @@ namespace torque {
#define AST_EXPRESSION_NODE_KIND_LIST(V) \ #define AST_EXPRESSION_NODE_KIND_LIST(V) \
V(CallExpression) \ V(CallExpression) \
V(LoadObjectFieldExpression) \
V(StoreObjectFieldExpression) \
V(IntrinsicCallExpression) \ V(IntrinsicCallExpression) \
V(StructExpression) \ V(StructExpression) \
V(LogicalOrExpression) \ V(LogicalOrExpression) \
...@@ -63,6 +65,7 @@ namespace torque { ...@@ -63,6 +65,7 @@ namespace torque {
V(GenericDeclaration) \ V(GenericDeclaration) \
V(SpecializationDeclaration) \ V(SpecializationDeclaration) \
V(ExternConstDeclaration) \ V(ExternConstDeclaration) \
V(ClassDeclaration) \
V(StructDeclaration) \ V(StructDeclaration) \
V(NamespaceDeclaration) \ V(NamespaceDeclaration) \
V(ConstDeclaration) \ V(ConstDeclaration) \
...@@ -204,6 +207,31 @@ struct IdentifierExpression : LocationExpression { ...@@ -204,6 +207,31 @@ struct IdentifierExpression : LocationExpression {
std::vector<TypeExpression*> generic_arguments; std::vector<TypeExpression*> generic_arguments;
}; };
struct LoadObjectFieldExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(LoadObjectFieldExpression)
LoadObjectFieldExpression(SourcePosition pos, Expression* base,
std::string field_name)
: Expression(kKind, pos),
base(std::move(base)),
field_name(std::move(field_name)) {}
Expression* base;
std::string field_name;
};
struct StoreObjectFieldExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(StoreObjectFieldExpression)
StoreObjectFieldExpression(SourcePosition pos, Expression* base,
std::string field_name, Expression* value)
: Expression(kKind, pos),
base(std::move(base)),
field_name(std::move(field_name)),
value(std::move(value)) {}
Expression* base;
std::string field_name;
Expression* value;
size_t offset;
};
struct IntrinsicCallExpression : Expression { struct IntrinsicCallExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(IntrinsicCallExpression) DEFINE_AST_NODE_LEAF_BOILERPLATE(IntrinsicCallExpression)
IntrinsicCallExpression(SourcePosition pos, std::string name, IntrinsicCallExpression(SourcePosition pos, std::string name,
...@@ -629,6 +657,11 @@ struct NameAndTypeExpression { ...@@ -629,6 +657,11 @@ struct NameAndTypeExpression {
TypeExpression* type; TypeExpression* type;
}; };
struct ClassFieldExpression {
NameAndTypeExpression name_and_type;
bool weak;
};
struct LabelAndTypes { struct LabelAndTypes {
std::string name; std::string name;
std::vector<TypeExpression*> types; std::vector<TypeExpression*> types;
...@@ -826,6 +859,25 @@ struct StructDeclaration : Declaration { ...@@ -826,6 +859,25 @@ struct StructDeclaration : Declaration {
std::vector<NameAndTypeExpression> fields; std::vector<NameAndTypeExpression> fields;
}; };
struct ClassDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration)
ClassDeclaration(SourcePosition pos, std::string name, bool transient,
base::Optional<std::string> extends,
base::Optional<std::string> generates,
std::vector<ClassFieldExpression> fields)
: Declaration(kKind, pos),
name(std::move(name)),
transient(transient),
extends(std::move(extends)),
generates(std::move(generates)),
fields(std::move(fields)) {}
std::string name;
bool transient;
base::Optional<std::string> extends;
base::Optional<std::string> generates;
std::vector<ClassFieldExpression> fields;
};
struct CppIncludeDeclaration : Declaration { struct CppIncludeDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(CppIncludeDeclaration) DEFINE_AST_NODE_LEAF_BOILERPLATE(CppIncludeDeclaration)
CppIncludeDeclaration(SourcePosition pos, std::string include_path) CppIncludeDeclaration(SourcePosition pos, std::string include_path)
...@@ -857,6 +909,14 @@ inline bool IsDeferred(Statement* stmt) { ...@@ -857,6 +909,14 @@ inline bool IsDeferred(Statement* stmt) {
return false; return false;
} }
DECLARE_CONTEXTUAL_VARIABLE(CurrentAst, Ast);
template <class T, class... Args>
T* MakeNode(Args... args) {
return CurrentAst::Get().AddNode(std::unique_ptr<T>(
new T(CurrentSourcePosition::Get(), std::move(args)...)));
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -657,6 +657,36 @@ void CSAGenerator::EmitInstruction(const UnsafeCastInstruction& instruction, ...@@ -657,6 +657,36 @@ void CSAGenerator::EmitInstruction(const UnsafeCastInstruction& instruction,
">(" + stack->Top() + ")"); ">(" + stack->Top() + ")");
} }
void CSAGenerator::EmitInstruction(
const LoadObjectFieldInstruction& instruction, Stack<std::string>* stack) {
const Field& field =
instruction.class_type->LookupField(instruction.field_name);
std::string result_name = FreshNodeName();
std::string type_string =
field.name_and_type.type->IsSubtypeOf(TypeOracle::GetSmiType())
? "MachineType::TaggedSigned()"
: "MachineType::AnyTagged()";
out_ << field.name_and_type.type->GetGeneratedTypeName() << " " << result_name
<< " = "
<< "ca_.UncheckedCast<"
<< field.name_and_type.type->GetGeneratedTNodeTypeName()
<< ">(CodeStubAssembler(state_).LoadObjectField("
<< stack->Top() + ", " + std::to_string(field.offset) + ", "
<< type_string + "));\n";
stack->Poke(stack->AboveTop() - 1, result_name);
}
void CSAGenerator::EmitInstruction(
const StoreObjectFieldInstruction& instruction, Stack<std::string>* stack) {
auto value = stack->Pop();
auto object = stack->Pop();
stack->Push(value);
const Field& field =
instruction.class_type->LookupField(instruction.field_name);
out_ << " CodeStubAssembler(state_).StoreObjectField(" + object + ", " +
std::to_string(field.offset) + ", " + value + ");\n";
}
// static // static
void CSAGenerator::EmitCSAValue(VisitResult result, void CSAGenerator::EmitCSAValue(VisitResult result,
const Stack<std::string>& values, const Stack<std::string>& values,
...@@ -671,7 +701,8 @@ void CSAGenerator::EmitCSAValue(VisitResult result, ...@@ -671,7 +701,8 @@ void CSAGenerator::EmitCSAValue(VisitResult result,
out << ", "; out << ", ";
} }
first = false; first = false;
EmitCSAValue(ProjectStructField(result, field.name), values, out); EmitCSAValue(ProjectStructField(result, field.name_and_type.name), values,
out);
} }
out << "}"; out << "}";
} else { } else {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/torque/declaration-visitor.h" #include "src/torque/declaration-visitor.h"
#include "src/torque/ast.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -229,14 +230,124 @@ void DeclarationVisitor::Visit(ExternConstDeclaration* decl) { ...@@ -229,14 +230,124 @@ void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
} }
void DeclarationVisitor::Visit(StructDeclaration* decl) { void DeclarationVisitor::Visit(StructDeclaration* decl) {
std::vector<NameAndType> fields; std::vector<Field> fields;
for (auto& field : decl->fields) { for (auto& field : decl->fields) {
const Type* field_type = Declarations::GetType(field.type); const Type* field_type = Declarations::GetType(field.type);
fields.push_back({field.name, field_type}); fields.push_back({{field.name, field_type}, 0, false});
} }
Declarations::DeclareStruct(decl->name, fields); Declarations::DeclareStruct(decl->name, fields);
} }
void DeclarationVisitor::Visit(ClassDeclaration* decl) {
// Compute the offset of the class' first member. If the class extends
// another class, it's the size of the extended class, otherwise zero.
size_t first_field_offset = 0;
if (decl->extends) {
const Type* extends_type = Declarations::LookupType(*decl->extends);
if (extends_type != TypeOracle::GetTaggedType()) {
if (!extends_type->IsClassType()) {
ReportError(
"class \"", decl->name,
"\" must extend either Tagged or an already declared class");
}
first_field_offset = ClassType::DynamicCast(extends_type)->size();
}
}
// The generates clause must create a TNode<>
std::string generates = decl->name;
if (decl->generates) {
if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
generates.substr(generates.length() - 1, 1) != ">") {
ReportError("generated type \"", generates,
"\" should be of the form \"TNode<...>\"");
}
generates = generates.substr(6, generates.length() - 7);
}
std::vector<Field> fields;
size_t offset = first_field_offset;
bool seen_strong = false;
bool seen_weak = false;
for (ClassFieldExpression& field : decl->fields) {
const Type* field_type = Declarations::GetType(field.name_and_type.type);
if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
if (field.weak) {
seen_weak = true;
} else {
if (seen_weak) {
ReportError("cannot declare strong field \"",
field.name_and_type.name,
"\" after weak Tagged references");
}
seen_strong = true;
}
} else {
if (seen_strong || seen_weak) {
ReportError("cannot declare scalar field \"", field.name_and_type.name,
"\" after strong or weak Tagged references");
}
}
if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
ReportError(
"field \"", field.name_and_type.name, "\" of class \"", decl->name,
"\" must be a subtype of Tagged (other types not yet supported)");
}
fields.push_back(
{{field.name_and_type.name, field_type}, offset, field.weak});
offset += kTaggedSize;
}
auto new_class = Declarations::DeclareClass(
decl->extends, decl->name, decl->transient, generates, fields, offset);
// For each field, construct AST snippits that implement a CSA accessor
// function and define a corresponding '.field' operator. The
// implementation iterator will turn the snippits into code.
for (auto& field : fields) {
CurrentSourcePosition::Scope source_position(decl->pos);
IdentifierExpression* parameter = MakeNode<IdentifierExpression>(
std::vector<std::string>{}, std::string{"o"});
// Load accessor
std::string load_macro_name =
"Load" + decl->name + CamelifyString(field.name_and_type.name);
std::string get_operator_name = "." + field.name_and_type.name;
Signature load_signature;
load_signature.parameter_names.push_back("o");
load_signature.parameter_types.types.push_back(new_class);
load_signature.parameter_types.var_args = false;
load_signature.return_type = field.name_and_type.type;
Statement* load_body =
MakeNode<ReturnStatement>(MakeNode<LoadObjectFieldExpression>(
parameter, field.name_and_type.name));
Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature,
false, load_body, get_operator_name);
// Store accessor
IdentifierExpression* value = MakeNode<IdentifierExpression>(
std::vector<std::string>{}, std::string{"v"});
std::string store_macro_name =
"Store" + decl->name + CamelifyString(field.name_and_type.name);
std::string store_operator_name = "." + field.name_and_type.name + "=";
Signature store_signature;
store_signature.parameter_names.push_back("o");
store_signature.parameter_names.push_back("v");
store_signature.parameter_types.types.push_back(new_class);
store_signature.parameter_types.types.push_back(field.name_and_type.type);
store_signature.parameter_types.var_args = false;
// TODO(danno): Store macros probably should return their value argument
store_signature.return_type = TypeOracle::GetVoidType();
Statement* store_body =
MakeNode<ExpressionStatement>(MakeNode<StoreObjectFieldExpression>(
parameter, field.name_and_type.name, value));
Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature,
false, store_body, store_operator_name);
}
GlobalContext::RegisterClass(decl->name, new_class);
}
void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) { void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) {
GlobalContext::AddCppInclude(decl->include_path); GlobalContext::AddCppInclude(decl->include_path);
} }
......
...@@ -44,6 +44,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -44,6 +44,7 @@ class DeclarationVisitor : public FileVisitor {
} }
void Visit(TypeDeclaration* decl); void Visit(TypeDeclaration* decl);
void Visit(ClassDeclaration* decl);
void Visit(TypeAliasDeclaration* decl) { void Visit(TypeAliasDeclaration* decl) {
const Type* type = Declarations::GetType(decl->type); const Type* type = Declarations::GetType(decl->type);
......
...@@ -168,11 +168,24 @@ void Declarations::DeclareType(const std::string& name, const Type* type, ...@@ -168,11 +168,24 @@ void Declarations::DeclareType(const std::string& name, const Type* type,
} }
void Declarations::DeclareStruct(const std::string& name, void Declarations::DeclareStruct(const std::string& name,
const std::vector<NameAndType>& fields) { const std::vector<Field>& fields) {
const StructType* new_type = TypeOracle::GetStructType(name, fields); const StructType* new_type = TypeOracle::GetStructType(name, fields);
DeclareType(name, new_type, false); DeclareType(name, new_type, false);
} }
const ClassType* Declarations::DeclareClass(
base::Optional<std::string> parent, const std::string& name, bool transient,
const std::string& generates, std::vector<Field> fields, size_t size) {
const Type* parent_type = nullptr;
if (parent) {
parent_type = LookupType(QualifiedName{*parent});
}
const ClassType* new_type = TypeOracle::GetClassType(
parent_type, name, transient, generates, std::move(fields), size);
DeclareType(name, new_type, false);
return new_type;
}
Macro* Declarations::CreateMacro( Macro* Declarations::CreateMacro(
std::string external_name, std::string readable_name, std::string external_name, std::string readable_name,
base::Optional<std::string> external_assembler_name, Signature signature, base::Optional<std::string> external_assembler_name, Signature signature,
......
...@@ -82,7 +82,12 @@ class Declarations { ...@@ -82,7 +82,12 @@ class Declarations {
bool redeclaration); bool redeclaration);
static void DeclareStruct(const std::string& name, static void DeclareStruct(const std::string& name,
const std::vector<NameAndType>& fields); const std::vector<Field>& fields);
static const ClassType* DeclareClass(base::Optional<std::string> parent,
const std::string& name, bool transient,
const std::string& generates,
std::vector<Field> fields, size_t size);
static Macro* CreateMacro(std::string external_name, static Macro* CreateMacro(std::string external_name,
std::string readable_name, std::string readable_name,
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef V8_TORQUE_GLOBAL_CONTEXT_H_ #ifndef V8_TORQUE_GLOBAL_CONTEXT_H_
#define V8_TORQUE_GLOBAL_CONTEXT_H_ #define V8_TORQUE_GLOBAL_CONTEXT_H_
#include <map>
#include "src/torque/declarable.h" #include "src/torque/declarable.h"
#include "src/torque/declarations.h" #include "src/torque/declarations.h"
#include "src/torque/type-oracle.h" #include "src/torque/type-oracle.h"
...@@ -44,6 +46,15 @@ class GlobalContext : public ContextualClass<GlobalContext> { ...@@ -44,6 +46,15 @@ class GlobalContext : public ContextualClass<GlobalContext> {
return result; return result;
} }
static void RegisterClass(const std::string& name,
const ClassType* new_class) {
Get().classes_[name] = new_class;
}
static const std::map<std::string, const ClassType*>& GetClasses() {
return Get().classes_;
}
static void AddCppInclude(std::string include_path) { static void AddCppInclude(std::string include_path) {
Get().cpp_includes_.push_back(std::move(include_path)); Get().cpp_includes_.push_back(std::move(include_path));
} }
...@@ -61,6 +72,7 @@ class GlobalContext : public ContextualClass<GlobalContext> { ...@@ -61,6 +72,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_;
}; };
template <class T> template <class T>
......
...@@ -152,8 +152,8 @@ void ImplementationVisitor::Visit(TypeAlias* alias) { ...@@ -152,8 +152,8 @@ void ImplementationVisitor::Visit(TypeAlias* alias) {
const std::string& name = struct_type->name(); const std::string& name = struct_type->name();
header_out() << " struct " << name << " {\n"; header_out() << " struct " << name << " {\n";
for (auto& field : struct_type->fields()) { for (auto& field : struct_type->fields()) {
header_out() << " " << field.type->GetGeneratedTypeName(); header_out() << " " << field.name_and_type.type->GetGeneratedTypeName();
header_out() << " " << field.name << ";\n"; header_out() << " " << field.name_and_type.name << ";\n";
} }
header_out() << "\n std::tuple<"; header_out() << "\n std::tuple<";
bool first = true; bool first = true;
...@@ -172,10 +172,10 @@ void ImplementationVisitor::Visit(TypeAlias* alias) { ...@@ -172,10 +172,10 @@ void ImplementationVisitor::Visit(TypeAlias* alias) {
header_out() << ", "; header_out() << ", ";
} }
first = false; first = false;
if (field.type->IsStructType()) { if (field.name_and_type.type->IsStructType()) {
header_out() << field.name << ".Flatten()"; header_out() << field.name_and_type.name << ".Flatten()";
} else { } else {
header_out() << "std::make_tuple(" << field.name << ")"; header_out() << "std::make_tuple(" << field.name_and_type.name << ")";
} }
} }
header_out() << ");\n"; header_out() << ");\n";
...@@ -1466,10 +1466,10 @@ VisitResult ImplementationVisitor::Visit(StructExpression* decl) { ...@@ -1466,10 +1466,10 @@ VisitResult ImplementationVisitor::Visit(StructExpression* decl) {
} }
StackRange stack_range = assembler().TopRange(0); StackRange stack_range = assembler().TopRange(0);
for (size_t i = 0; i < struct_type->fields().size(); ++i) { for (size_t i = 0; i < struct_type->fields().size(); ++i) {
const NameAndType& field = struct_type->fields()[i]; const Field& field = struct_type->fields()[i];
StackScope scope(this); StackScope scope(this);
VisitResult value = Visit(decl->expressions[i]); VisitResult value = Visit(decl->expressions[i]);
value = GenerateImplicitConvert(field.type, value); value = GenerateImplicitConvert(field.name_and_type.type, value);
stack_range.Extend(scope.Yield(value).stack_range()); stack_range.Extend(scope.Yield(value).stack_range());
} }
return VisitResult(struct_type, stack_range); return VisitResult(struct_type, stack_range);
...@@ -1908,6 +1908,35 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr, ...@@ -1908,6 +1908,35 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
} }
} }
VisitResult ImplementationVisitor::Visit(LoadObjectFieldExpression* expr) {
VisitResult result = Visit(expr->base);
auto class_type = ClassType::DynamicCast(result.type());
if (!class_type) {
ReportError(
"base expression for a LoadObjectFieldExpression is not a class type "
"but instead ",
*result.type());
}
assembler().Emit(LoadObjectFieldInstruction{class_type, expr->field_name});
const Field& field = class_type->LookupField(expr->field_name);
result.SetType(field.name_and_type.type);
return result;
}
VisitResult ImplementationVisitor::Visit(StoreObjectFieldExpression* expr) {
VisitResult base_result = Visit(expr->base);
auto class_type = ClassType::DynamicCast(base_result.type());
if (!class_type) {
ReportError(
"base expression for a StoreObjectFieldExpression is not a class type "
"but instead ",
*base_result.type());
}
VisitResult value = Visit(expr->value);
assembler().Emit(StoreObjectFieldInstruction{class_type, expr->field_name});
return VisitResult(value.type(), assembler().TopRange(0));
}
VisitResult ImplementationVisitor::Visit(IntrinsicCallExpression* expr) { VisitResult ImplementationVisitor::Visit(IntrinsicCallExpression* expr) {
StackScope scope(this); StackScope scope(this);
Arguments arguments; Arguments arguments;
...@@ -1997,7 +2026,8 @@ StackRange ImplementationVisitor::LowerParameter( ...@@ -1997,7 +2026,8 @@ StackRange ImplementationVisitor::LowerParameter(
StackRange range = lowered_parameters->TopRange(0); StackRange range = lowered_parameters->TopRange(0);
for (auto& field : struct_type->fields()) { for (auto& field : struct_type->fields()) {
StackRange parameter_range = LowerParameter( StackRange parameter_range = LowerParameter(
field.type, parameter_name + "." + field.name, lowered_parameters); field.name_and_type.type,
parameter_name + "." + field.name_and_type.name, lowered_parameters);
range.Extend(parameter_range); range.Extend(parameter_range);
} }
return range; return range;
...@@ -2170,6 +2200,50 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(std::string& file_name) { ...@@ -2170,6 +2200,50 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(std::string& file_name) {
ReplaceFileContentsIfDifferent(file_name, new_contents); ReplaceFileContentsIfDifferent(file_name, new_contents);
} }
void ImplementationVisitor::GenerateClassDefinitions(std::string& file_name) {
std::stringstream new_contents_stream;
new_contents_stream << "#ifndef V8_CLASS_BUILTIN_DEFINITIONS_FROM_DSL_H_\n"
"#define V8_CLASS_BUILTIN_DEFINITIONS_FROM_DSL_H_\n"
"\n\n";
for (auto i : GlobalContext::GetClasses()) {
// TODO(danno): Ideally (and we've got several core V8 dev's feedback
// supporting this), Torque should generate the constants for the offsets
// directly and not go through the existing layer of macros, which actually
// currently just serves to additionally obfuscate where these values come
// from.
new_contents_stream << "#define ";
new_contents_stream << CapifyStringWithUnderscores(i.first)
<< "_FIELDS(V) \\\n";
const ClassType* type = i.second;
std::vector<Field> fields = type->fields();
new_contents_stream << "V(kStartOfStrongFieldsOffset, 0) \\\n";
for (auto f : fields) {
if (!f.is_weak) {
new_contents_stream << "V(k" << CamelifyString(f.name_and_type.name)
<< "Offset, kTaggedSize) \\\n";
}
}
new_contents_stream << "V(kEndOfStrongFieldsOffset, 0) \\\n";
new_contents_stream << "V(kStartOfWeakFieldsOffset, 0) \\\n";
for (auto f : fields) {
if (f.is_weak) {
new_contents_stream << "V(k" << CamelifyString(f.name_and_type.name)
<< "Offset, kTaggedSize) \\\n";
}
}
new_contents_stream << "V(kEndOfWeakFieldsOffset, 0) \\\n";
new_contents_stream << "V(kSize, 0) \\\n";
new_contents_stream << "\n";
}
new_contents_stream
<< "\n#endif // V8_CLASS_BUILTIN_DEFINITIONS_FROM_DSL_H_\n";
std::string new_contents(new_contents_stream.str());
ReplaceFileContentsIfDifferent(file_name, new_contents);
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -200,6 +200,7 @@ bool IsCompatibleSignature(const Signature& sig, const TypeVector& types, ...@@ -200,6 +200,7 @@ bool IsCompatibleSignature(const Signature& sig, const TypeVector& types,
class ImplementationVisitor : public FileVisitor { class ImplementationVisitor : public FileVisitor {
public: public:
void GenerateBuiltinDefinitions(std::string& file_name); void GenerateBuiltinDefinitions(std::string& file_name);
void GenerateClassDefinitions(std::string& file_name);
VisitResult Visit(Expression* expr); VisitResult Visit(Expression* expr);
const Type* Visit(Statement* stmt); const Type* Visit(Statement* stmt);
...@@ -237,6 +238,8 @@ class ImplementationVisitor : public FileVisitor { ...@@ -237,6 +238,8 @@ class ImplementationVisitor : public FileVisitor {
VisitResult Visit(CallExpression* expr, bool is_tail = false); VisitResult Visit(CallExpression* expr, bool is_tail = false);
VisitResult Visit(IntrinsicCallExpression* intrinsic); VisitResult Visit(IntrinsicCallExpression* intrinsic);
VisitResult Visit(LoadObjectFieldExpression* intrinsic);
VisitResult Visit(StoreObjectFieldExpression* intrinsic);
const Type* Visit(TailCallStatement* stmt); const Type* Visit(TailCallStatement* stmt);
VisitResult Visit(ConditionalExpression* expr); VisitResult Visit(ConditionalExpression* expr);
......
...@@ -281,6 +281,41 @@ void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack, ...@@ -281,6 +281,41 @@ void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack,
stack->Poke(stack->AboveTop() - 1, destination_type); stack->Poke(stack->AboveTop() - 1, destination_type);
} }
void LoadObjectFieldInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {
const ClassType* stack_class_type = ClassType::DynamicCast(stack->Top());
if (!stack_class_type) {
ReportError(
"first argument to a LoadObjectFieldInstruction instruction isn't a "
"class");
}
if (stack_class_type != class_type) {
ReportError(
"first argument to a LoadObjectFieldInstruction doesn't match "
"instruction's type");
}
const Field& field = class_type->LookupField(field_name);
stack->Poke(stack->AboveTop() - 1, field.name_and_type.type);
}
void StoreObjectFieldInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {
auto value = stack->Pop();
const ClassType* stack_class_type = ClassType::DynamicCast(stack->Top());
if (!stack_class_type) {
ReportError(
"first argument to a StoreObjectFieldInstruction instruction isn't a "
"class");
}
if (stack_class_type != class_type) {
ReportError(
"first argument to a StoreObjectFieldInstruction doesn't match "
"instruction's type");
}
stack->Pop();
stack->Push(value);
}
bool CallRuntimeInstruction::IsBlockTerminator() const { bool CallRuntimeInstruction::IsBlockTerminator() const {
return is_tailcall || runtime_function->signature().return_type == return is_tailcall || runtime_function->signature().return_type ==
TypeOracle::GetNeverType(); TypeOracle::GetNeverType();
......
...@@ -30,6 +30,8 @@ class RuntimeFunction; ...@@ -30,6 +30,8 @@ class RuntimeFunction;
V(DeleteRangeInstruction) \ V(DeleteRangeInstruction) \
V(PushUninitializedInstruction) \ V(PushUninitializedInstruction) \
V(PushBuiltinPointerInstruction) \ V(PushBuiltinPointerInstruction) \
V(LoadObjectFieldInstruction) \
V(StoreObjectFieldInstruction) \
V(CallCsaMacroInstruction) \ V(CallCsaMacroInstruction) \
V(CallIntrinsicInstruction) \ V(CallIntrinsicInstruction) \
V(NamespaceConstantInstruction) \ V(NamespaceConstantInstruction) \
...@@ -109,9 +111,10 @@ class Instruction { ...@@ -109,9 +111,10 @@ class Instruction {
return nullptr; return nullptr;
} }
Instruction(const Instruction& other) Instruction(const Instruction& other) V8_NOEXCEPT
: kind_(other.kind_), instruction_(other.instruction_->Clone()) {} : kind_(other.kind_),
Instruction& operator=(const Instruction& other) { instruction_(other.instruction_->Clone()) {}
Instruction& operator=(const Instruction& other) V8_NOEXCEPT {
if (kind_ == other.kind_) { if (kind_ == other.kind_) {
instruction_->Assign(*other.instruction_); instruction_->Assign(*other.instruction_);
} else { } else {
...@@ -189,6 +192,30 @@ struct NamespaceConstantInstruction : InstructionBase { ...@@ -189,6 +192,30 @@ struct NamespaceConstantInstruction : InstructionBase {
NamespaceConstant* constant; NamespaceConstant* constant;
}; };
struct LoadObjectFieldInstruction : InstructionBase {
TORQUE_INSTRUCTION_BOILERPLATE()
LoadObjectFieldInstruction(const ClassType* class_type,
std::string field_name)
: class_type(class_type) {
// The normal way to write this triggers a bug in Clang on Windows.
this->field_name = std::move(field_name);
}
const ClassType* class_type;
std::string field_name;
};
struct StoreObjectFieldInstruction : InstructionBase {
TORQUE_INSTRUCTION_BOILERPLATE()
StoreObjectFieldInstruction(const ClassType* class_type,
std::string field_name)
: class_type(class_type) {
// The normal way to write this triggers a bug in Clang on Windows.
this->field_name = std::move(field_name);
}
const ClassType* class_type;
std::string field_name;
};
struct CallIntrinsicInstruction : InstructionBase { struct CallIntrinsicInstruction : InstructionBase {
TORQUE_INSTRUCTION_BOILERPLATE() TORQUE_INSTRUCTION_BOILERPLATE()
CallIntrinsicInstruction(Intrinsic* intrinsic, CallIntrinsicInstruction(Intrinsic* intrinsic,
......
...@@ -41,7 +41,9 @@ enum class ParseResultHolderBase::TypeId { ...@@ -41,7 +41,9 @@ enum class ParseResultHolderBase::TypeId {
kLabelBlockPtr, kLabelBlockPtr,
kOptionalLabelBlockPtr, kOptionalLabelBlockPtr,
kNameAndTypeExpression, kNameAndTypeExpression,
kClassFieldExpression,
kStdVectorOfNameAndTypeExpression, kStdVectorOfNameAndTypeExpression,
kStdVectorOfClassFieldExpression,
kIncrementDecrementOperator, kIncrementDecrementOperator,
kOptionalStdString, kOptionalStdString,
kStdVectorOfStatementPtr, kStdVectorOfStatementPtr,
...@@ -101,10 +103,18 @@ V8_EXPORT_PRIVATE const ParseResultTypeId ...@@ -101,10 +103,18 @@ V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<NameAndTypeExpression>::id = ParseResultHolder<NameAndTypeExpression>::id =
ParseResultTypeId::kNameAndTypeExpression; ParseResultTypeId::kNameAndTypeExpression;
template <> template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<ClassFieldExpression>::id =
ParseResultTypeId::kClassFieldExpression;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<std::vector<NameAndTypeExpression>>::id = ParseResultHolder<std::vector<NameAndTypeExpression>>::id =
ParseResultTypeId::kStdVectorOfNameAndTypeExpression; ParseResultTypeId::kStdVectorOfNameAndTypeExpression;
template <> template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<std::vector<ClassFieldExpression>>::id =
ParseResultTypeId::kStdVectorOfClassFieldExpression;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<IncrementDecrementOperator>::id = ParseResultHolder<IncrementDecrementOperator>::id =
ParseResultTypeId::kIncrementDecrementOperator; ParseResultTypeId::kIncrementDecrementOperator;
...@@ -182,12 +192,6 @@ base::Optional<ParseResult> AddGlobalDeclaration( ...@@ -182,12 +192,6 @@ base::Optional<ParseResult> AddGlobalDeclaration(
return base::nullopt; return base::nullopt;
} }
template <class T, class... Args>
T* MakeNode(Args... args) {
return CurrentAst::Get().AddNode(std::unique_ptr<T>(
new T(CurrentSourcePosition::Get(), std::move(args)...)));
}
void LintGenericParameters(const GenericParameters& parameters) { void LintGenericParameters(const GenericParameters& parameters) {
for (const std::string& parameter : parameters) { for (const std::string& parameter : parameters) {
if (!IsUpperCamelCase(parameter)) { if (!IsUpperCamelCase(parameter)) {
...@@ -309,6 +313,7 @@ base::Optional<ParseResult> MakeParameterListFromTypes( ...@@ -309,6 +313,7 @@ base::Optional<ParseResult> MakeParameterListFromTypes(
} }
return ParseResult{std::move(result)}; return ParseResult{std::move(result)};
} }
template <bool has_varargs> template <bool has_varargs>
base::Optional<ParseResult> MakeParameterListFromNameAndTypeList( base::Optional<ParseResult> MakeParameterListFromNameAndTypeList(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
...@@ -516,6 +521,22 @@ base::Optional<ParseResult> MakeTypeDeclaration( ...@@ -516,6 +521,22 @@ base::Optional<ParseResult> MakeTypeDeclaration(
return ParseResult{result}; return ParseResult{result};
} }
base::Optional<ParseResult> MakeClassDeclaration(
ParseResultIterator* child_results) {
auto transient = child_results->NextAs<bool>();
auto name = child_results->NextAs<std::string>();
if (!IsValidTypeName(name)) {
NamingConventionError("Type", name, "UpperCamelCase");
}
auto extends = child_results->NextAs<base::Optional<std::string>>();
auto generates = child_results->NextAs<base::Optional<std::string>>();
auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
Declaration* result =
MakeNode<ClassDeclaration>(std::move(name), transient, std::move(extends),
std::move(generates), fields);
return ParseResult{result};
}
base::Optional<ParseResult> MakeNamespaceDeclaration( base::Optional<ParseResult> MakeNamespaceDeclaration(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto name = child_results->NextAs<std::string>(); auto name = child_results->NextAs<std::string>();
...@@ -1036,6 +1057,13 @@ base::Optional<ParseResult> MakeNameAndType( ...@@ -1036,6 +1057,13 @@ base::Optional<ParseResult> MakeNameAndType(
return ParseResult{NameAndTypeExpression{std::move(name), type}}; return ParseResult{NameAndTypeExpression{std::move(name), type}};
} }
base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
auto weak = child_results->NextAs<bool>();
auto name = child_results->NextAs<std::string>();
auto type = child_results->NextAs<TypeExpression*>();
return ParseResult{ClassFieldExpression{{std::move(name), type}, weak}};
}
base::Optional<ParseResult> ExtractAssignmentOperator( base::Optional<ParseResult> ExtractAssignmentOperator(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto op = child_results->NextAs<std::string>(); auto op = child_results->NextAs<std::string>();
...@@ -1222,6 +1250,10 @@ struct TorqueGrammar : Grammar { ...@@ -1222,6 +1250,10 @@ struct TorqueGrammar : Grammar {
Symbol nameAndType = { Symbol nameAndType = {
Rule({&identifier, Token(":"), &type}, MakeNameAndType)}; Rule({&identifier, Token(":"), &type}, MakeNameAndType)};
Symbol classField = {
Rule({CheckIf(Token("weak")), &identifier, Token(":"), &type, Token(";")},
MakeClassField)};
// Result: ParameterList // Result: ParameterList
Symbol parameterListNoVararg = { Symbol parameterListNoVararg = {
Rule({optionalImplicitParameterList, Token("("), Rule({optionalImplicitParameterList, Token("("),
...@@ -1480,6 +1512,12 @@ struct TorqueGrammar : Grammar { ...@@ -1480,6 +1512,12 @@ struct TorqueGrammar : Grammar {
Rule({Token("const"), &identifier, Token(":"), &type, Token("generates"), Rule({Token("const"), &identifier, Token(":"), &type, Token("generates"),
&externalString, Token(";")}, &externalString, Token(";")},
MakeExternConstDeclaration), MakeExternConstDeclaration),
Rule({CheckIf(Token("transient")), Token("class"), &identifier,
Optional<std::string>(Sequence({Token("extends"), &identifier})),
Optional<std::string>(
Sequence({Token("generates"), &externalString})),
Token("{"), List<ClassFieldExpression>(&classField), Token("}")},
MakeClassDeclaration),
Rule({CheckIf(Token("transient")), Token("type"), &identifier, Rule({CheckIf(Token("transient")), Token("type"), &identifier,
Optional<std::string>(Sequence({Token("extends"), &identifier})), Optional<std::string>(Sequence({Token("extends"), &identifier})),
Optional<std::string>( Optional<std::string>(
......
...@@ -11,8 +11,6 @@ namespace v8 { ...@@ -11,8 +11,6 @@ namespace v8 {
namespace internal { namespace internal {
namespace torque { namespace torque {
DECLARE_CONTEXTUAL_VARIABLE(CurrentAst, Ast);
// Adds the parsed input to {CurrentAst} // Adds the parsed input to {CurrentAst}
void ParseTorque(const std::string& input); void ParseTorque(const std::string& input);
......
...@@ -68,6 +68,9 @@ int WrappedMain(int argc, const char** argv) { ...@@ -68,6 +68,9 @@ int WrappedMain(int argc, const char** argv) {
output_header_path += "/builtin-definitions-from-dsl.h"; output_header_path += "/builtin-definitions-from-dsl.h";
visitor.GenerateBuiltinDefinitions(output_header_path); visitor.GenerateBuiltinDefinitions(output_header_path);
output_header_path = output_directory + "/class-definitions-from-dsl.h";
visitor.GenerateClassDefinitions(output_header_path);
for (Namespace* n : GlobalContext::Get().GetNamespaces()) { for (Namespace* n : GlobalContext::Get().GetNamespaces()) {
visitor.EndNamespaceFile(n); visitor.EndNamespaceFile(n);
visitor.GenerateImplementation(output_directory, n); visitor.GenerateImplementation(output_directory, n);
......
...@@ -28,13 +28,24 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -28,13 +28,24 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return result; return result;
} }
static const StructType* GetStructType( static const StructType* GetStructType(const std::string& name,
const std::string& name, const std::vector<NameAndType>& fields) { const std::vector<Field>& fields) {
StructType* result = new StructType(CurrentNamespace(), name, fields); StructType* result = new StructType(CurrentNamespace(), name, fields);
Get().struct_types_.push_back(std::unique_ptr<StructType>(result)); Get().struct_types_.push_back(std::unique_ptr<StructType>(result));
return result; return result;
} }
static const ClassType* GetClassType(const Type* parent,
const std::string& name, bool transient,
const std::string& generates,
const std::vector<Field>& fields,
size_t size) {
ClassType* result = new ClassType(parent, CurrentNamespace(), name,
transient, generates, fields, size);
Get().struct_types_.push_back(std::unique_ptr<ClassType>(result));
return result;
}
static const BuiltinPointerType* GetBuiltinPointerType( static const BuiltinPointerType* GetBuiltinPointerType(
TypeVector argument_types, const Type* return_type) { TypeVector argument_types, const Type* return_type) {
TypeOracle& self = Get(); TypeOracle& self = Get();
......
...@@ -78,6 +78,8 @@ std::string AbstractType::GetGeneratedTNodeTypeName() const { ...@@ -78,6 +78,8 @@ 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 (";
...@@ -182,16 +184,36 @@ const Type* SubtractType(const Type* a, const Type* b) { ...@@ -182,16 +184,36 @@ const Type* SubtractType(const Type* a, const Type* b) {
return TypeOracle::GetUnionType(result); return TypeOracle::GetUnionType(result);
} }
const Field& NameAndTypeListType::LookupField(const std::string& name) const {
for (auto& field : fields_) {
if (field.name_and_type.name == name) return field;
}
if (parent() != nullptr) {
if (auto parent_class = ClassType::DynamicCast(parent())) {
return parent_class->LookupField(name);
}
}
ReportError("no field ", name, "found");
}
std::string StructType::GetGeneratedTypeName() const {
return nspace()->ExternalName() + "::" + name();
}
std::string StructType::ToExplicitString() const { std::string StructType::ToExplicitString() const {
std::stringstream result; std::stringstream result;
result << "{"; result << "struct " << name() << "{";
PrintCommaSeparatedList(result, fields_); PrintCommaSeparatedList(result, fields());
result << "}"; result << "}";
return result.str(); return result.str();
} }
std::string StructType::GetGeneratedTypeName() const { std::string ClassType::ToExplicitString() const {
return namespace_->ExternalName() + "::" + GetStructName(); std::stringstream result;
result << "class " << name() << "{";
PrintCommaSeparatedList(result, fields());
result << "}";
return result.str();
} }
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) { void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
...@@ -234,6 +256,14 @@ std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) { ...@@ -234,6 +256,14 @@ std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) {
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const Field& field) {
os << field.name_and_type;
if (field.is_weak) {
os << " (weak)";
}
return os;
}
std::ostream& operator<<(std::ostream& os, const Signature& sig) { std::ostream& operator<<(std::ostream& os, const Signature& sig) {
PrintSignature(os, sig, true); PrintSignature(os, sig, true);
return os; return os;
...@@ -294,9 +324,9 @@ VisitResult ProjectStructField(VisitResult structure, ...@@ -294,9 +324,9 @@ VisitResult ProjectStructField(VisitResult structure,
BottomOffset begin = structure.stack_range().begin(); BottomOffset begin = structure.stack_range().begin();
const StructType* type = StructType::cast(structure.type()); const StructType* type = StructType::cast(structure.type());
for (auto& field : type->fields()) { for (auto& field : type->fields()) {
BottomOffset end = begin + LoweredSlotCount(field.type); BottomOffset end = begin + LoweredSlotCount(field.name_and_type.type);
if (field.name == fieldname) { if (field.name_and_type.name == fieldname) {
return VisitResult(field.type, StackRange{begin, end}); return VisitResult(field.name_and_type.type, StackRange{begin, end});
} }
begin = end; begin = end;
} }
...@@ -309,8 +339,8 @@ void AppendLoweredTypes(const Type* type, std::vector<const Type*>* result) { ...@@ -309,8 +339,8 @@ void AppendLoweredTypes(const Type* type, std::vector<const Type*>* result) {
if (type->IsConstexpr()) return; if (type->IsConstexpr()) return;
if (type == TypeOracle::GetVoidType()) return; if (type == TypeOracle::GetVoidType()) return;
if (auto* s = StructType::DynamicCast(type)) { if (auto* s = StructType::DynamicCast(type)) {
for (const NameAndType& field : s->fields()) { for (const Field& field : s->fields()) {
AppendLoweredTypes(field.type, result); AppendLoweredTypes(field.name_and_type.type, result);
} }
} else { } else {
result->push_back(type); result->push_back(type);
......
...@@ -50,7 +50,8 @@ class TypeBase { ...@@ -50,7 +50,8 @@ class TypeBase {
kAbstractType, kAbstractType,
kBuiltinPointerType, kBuiltinPointerType,
kUnionType, kUnionType,
kStructType kStructType,
kClassType
}; };
virtual ~TypeBase() = default; virtual ~TypeBase() = default;
bool IsTopType() const { return kind() == Kind::kTopType; } bool IsTopType() const { return kind() == Kind::kTopType; }
...@@ -60,6 +61,7 @@ class TypeBase { ...@@ -60,6 +61,7 @@ class TypeBase {
} }
bool IsUnionType() const { return kind() == Kind::kUnionType; } bool IsUnionType() const { return kind() == Kind::kUnionType; }
bool IsStructType() const { return kind() == Kind::kStructType; } bool IsStructType() const { return kind() == Kind::kStructType; }
bool IsClassType() const { return kind() == Kind::kClassType; }
protected: protected:
explicit TypeBase(Kind kind) : kind_(kind) {} explicit TypeBase(Kind kind) : kind_(kind) {}
...@@ -143,6 +145,14 @@ struct NameAndType { ...@@ -143,6 +145,14 @@ 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 {
NameAndType name_and_type;
size_t offset;
bool is_weak;
};
std::ostream& operator<<(std::ostream& os, const Field& name_and_type);
class TopType final : public Type { class TopType final : public Type {
public: public:
DECLARE_TYPE_BOILERPLATE(TopType); DECLARE_TYPE_BOILERPLATE(TopType);
...@@ -366,44 +376,71 @@ class UnionType final : public Type { ...@@ -366,44 +376,71 @@ class UnionType final : public Type {
const Type* SubtractType(const Type* a, const Type* b); const Type* SubtractType(const Type* a, const Type* b);
class StructType final : public Type { class NameAndTypeListType : public Type {
public: public:
DECLARE_TYPE_BOILERPLATE(StructType);
std::string ToExplicitString() const override;
std::string MangledName() const override { return name_; } std::string MangledName() const override { return name_; }
std::string GetGeneratedTypeName() const override; std::string GetGeneratedTypeName() const override { UNREACHABLE(); };
std::string GetGeneratedTNodeTypeName() const override { UNREACHABLE(); } std::string GetGeneratedTNodeTypeName() const override { UNREACHABLE(); }
const Type* NonConstexprVersion() const override { return this; } const Type* NonConstexprVersion() const override { return this; }
bool IsConstexpr() const override { return false; } bool IsConstexpr() const override { return false; }
const std::vector<NameAndType>& fields() const { return fields_; } void SetFields(std::vector<Field> fields) { fields_ = std::move(fields); }
const Type* GetFieldType(const std::string& fieldname) const { const std::vector<Field>& fields() const { return fields_; }
for (const NameAndType& field : fields()) { const Field& LookupField(const std::string& name) const;
if (field.name == fieldname) return field.type;
}
std::stringstream s;
s << "\"" << fieldname << "\" is not a field of struct type \"" << name()
<< "\"";
ReportError(s.str());
}
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
Namespace* nspace() const { return namespace_; } Namespace* nspace() const { return namespace_; }
protected:
NameAndTypeListType(Kind kind, const Type* parent, Namespace* nspace,
const std::string& name, const std::vector<Field>& fields)
: Type(kind, parent), namespace_(nspace), name_(name), fields_(fields) {}
private:
Namespace* namespace_;
std::string name_;
std::vector<Field> fields_;
};
class StructType final : public NameAndTypeListType {
public:
DECLARE_TYPE_BOILERPLATE(StructType);
std::string ToExplicitString() const override;
std::string GetGeneratedTypeName() const override;
private: private:
friend class TypeOracle; friend class TypeOracle;
StructType(Namespace* nspace, const std::string& name, StructType(Namespace* nspace, const std::string& name,
const std::vector<NameAndType>& fields) const std::vector<Field>& fields)
: Type(Kind::kStructType, nullptr), : NameAndTypeListType(Kind::kStructType, nullptr, nspace, name, fields) {}
namespace_(nspace),
name_(name),
fields_(fields) {}
const std::string& GetStructName() const { return name_; } const std::string& GetStructName() const { return name(); }
};
Namespace* namespace_; class ClassType final : public NameAndTypeListType {
std::string name_; public:
std::vector<NameAndType> fields_; DECLARE_TYPE_BOILERPLATE(ClassType);
std::string ToExplicitString() const override;
std::string GetGeneratedTypeName() const override {
return IsConstexpr() ? generates_ : "compiler::TNode<" + generates_ + ">";
}
std::string GetGeneratedTNodeTypeName() const override;
bool IsTransient() const override { return transient_; }
size_t size() const { return size_; }
private:
friend class TypeOracle;
ClassType(const Type* parent, Namespace* nspace, const std::string& name,
bool transient, const std::string& generates,
const std::vector<Field>& fields, size_t size)
: NameAndTypeListType(Kind::kClassType, parent, nspace, name, fields),
transient_(transient),
size_(size),
generates_(generates) {}
bool transient_;
size_t size_;
const std::string generates_;
}; };
inline std::ostream& operator<<(std::ostream& os, const Type& t) { inline std::ostream& operator<<(std::ostream& os, const Type& t) {
......
...@@ -163,6 +163,19 @@ bool IsValidTypeName(const std::string& s) { ...@@ -163,6 +163,19 @@ bool IsValidTypeName(const std::string& s) {
return IsUpperCamelCase(s); return IsUpperCamelCase(s);
} }
std::string CapifyStringWithUnderscores(const std::string& camellified_string) {
std::string result;
bool previousWasLower = false;
for (auto current : camellified_string) {
if (previousWasLower && isupper(current)) {
result += "_";
}
result += toupper(current);
previousWasLower = (islower(current));
}
return result;
}
std::string CamelifyString(const std::string& underscore_string) { std::string CamelifyString(const std::string& underscore_string) {
std::string result; std::string result;
bool word_beginning = true; bool word_beginning = true;
......
...@@ -53,6 +53,7 @@ template <class... Args> ...@@ -53,6 +53,7 @@ template <class... Args>
ReportErrorString(s.str()); ReportErrorString(s.str());
} }
std::string CapifyStringWithUnderscores(const std::string& camellified_string);
std::string CamelifyString(const std::string& underscore_string); std::string CamelifyString(const std::string& underscore_string);
std::string DashifyString(const std::string& underscore_string); std::string DashifyString(const std::string& underscore_string);
...@@ -263,6 +264,8 @@ class ToString { ...@@ -263,6 +264,8 @@ class ToString {
std::stringstream s_; std::stringstream s_;
}; };
constexpr int kTaggedSize = sizeof(void*);
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -50,6 +50,7 @@ def postprocess(output): ...@@ -50,6 +50,7 @@ def postprocess(output):
output = re.sub(r'% RawPointerCast', r'%RawPointerCast', output) output = re.sub(r'% RawPointerCast', r'%RawPointerCast', output)
output = re.sub(r'% RawConstexprCast', r'%RawConstexprCast', output) output = re.sub(r'% RawConstexprCast', r'%RawConstexprCast', output)
output = re.sub(r'% FromConstexpr', r'%FromConstexpr', output) output = re.sub(r'% FromConstexpr', r'%FromConstexpr', output)
output = re.sub(r'% Allocate', r'%Allocate ', output)
output = re.sub(r'\/\*COxp\*\/', r'constexpr', output) output = re.sub(r'\/\*COxp\*\/', r'constexpr', output)
output = re.sub(r'(\S+)\s*: type([,>])', r'\1: type\2', output) output = re.sub(r'(\S+)\s*: type([,>])', r'\1: type\2', output)
output = re.sub(r'(\n\s*)labels( [A-Z])', r'\1 labels\2', output) output = re.sub(r'(\n\s*)labels( [A-Z])', r'\1 labels\2', output)
......
...@@ -30,14 +30,14 @@ syn keyword torqueFunction macro builtin runtime intrinsic ...@@ -30,14 +30,14 @@ syn keyword torqueFunction macro builtin runtime intrinsic
syn keyword torqueKeyword cast convert from_constexpr min max unsafe_cast syn keyword torqueKeyword cast convert from_constexpr min max unsafe_cast
syn keyword torqueLabel case syn keyword torqueLabel case
syn keyword torqueMatching try label catch syn keyword torqueMatching try label catch
syn keyword torqueModifier extern javascript constexpr transitioning transient syn keyword torqueModifier extern javascript constexpr transitioning transient weak
syn match torqueNumber /\v<[0-9]+(\.[0-9]*)?>/ syn match torqueNumber /\v<[0-9]+(\.[0-9]*)?>/
syn match torqueNumber /\v<0x[0-9a-fA-F]+>/ syn match torqueNumber /\v<0x[0-9a-fA-F]+>/
syn keyword torqueOperator operator syn keyword torqueOperator operator
syn keyword torqueRel extends generates labels syn keyword torqueRel extends generates labels
syn keyword torqueRepeat while for of syn keyword torqueRepeat while for of
syn keyword torqueStatement return tail syn keyword torqueStatement return tail
syn keyword torqueStructure module struct type syn keyword torqueStructure module struct type class
syn keyword torqueVariable const let syn keyword torqueVariable const let
syn match torqueType /\v(\<)@<=([A-Za-z][0-9A-Za-z_]*)(>)@=/ syn match torqueType /\v(\<)@<=([A-Za-z][0-9A-Za-z_]*)(>)@=/
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
}, },
{ {
"name": "keyword.other.torque", "name": "keyword.other.torque",
"match": "\\b(constexpr|module|macro|builtin|runtime|intrinsic|javascript|implicit|deferred|label|labels|tail|let|generates|type|extends|extern|const|typeswitch|case|transient|transitioning)\\b" "match": "\\b(constexpr|module|macro|builtin|runtime|intrinsic|javascript|implicit|deferred|label|labels|tail|let|generates|type|class|weak|extends|extern|const|typeswitch|case|transient|transitioning)\\b"
}, },
{ {
"name": "keyword.operator.torque", "name": "keyword.operator.torque",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment