Commit 0dc9b63e authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] explicit exports of macros to CSA

Macros are now inaccessible from CSA except if their declaration is
marked with the "export" keyword. The implicit field accessors for class
fields are always exported.

In this CL, unwarranted access from CSA is prevented by appending a
pseudo-random suffix to non-exported names. This is to be replaced by
something more principled, namely by not including these macros at all in
the headers included from CSA.

Bug: v8:7793
Change-Id: I3ffb2e91a616623f81b4b4508e001ad0cf65d2c2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1615258
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61672}
parent 42fee61a
......@@ -31,6 +31,7 @@ namespace arguments {
// It is difficult to actually check/assert this, since interpreted or JITted
// frames are StandardFrames, but so are hand-written builtins. Doing that
// more refined check would be prohibitively expensive.
@export
macro GetArgumentsFrameAndCount(implicit context: Context)(f: JSFunction):
ArgumentsInfo {
let frame: Frame = LoadParentFramePointer();
......
......@@ -2725,8 +2725,6 @@ extern macro IsJSArrayMap(Map): bool;
extern macro IsExtensibleMap(Map): bool;
extern macro IsJSValue(HeapObject): bool;
extern macro IsCustomElementsReceiverInstanceType(int32): bool;
extern macro IsFastJSArrayWithNoCustomIteration(implicit context: Context)(
Object): bool;
extern macro Typeof(Object): Object;
// Return true iff number is NaN.
......@@ -2815,6 +2813,7 @@ struct KeyValuePair {
// Macro definitions for compatibility that expose functionality to the CSA
// using "legacy" APIs. In Torque code, these should not be used.
@export
macro IsFastJSArray(o: Object, context: Context): bool {
try {
// Long-term, it's likely not a good idea to have this slow-path test here,
......@@ -2828,16 +2827,18 @@ macro IsFastJSArray(o: Object, context: Context): bool {
return Is<FastJSArray>(o);
}
macro BranchIfFastJSArray(o: Object, context: Context): never
labels True, False {
@export
macro BranchIfFastJSArray(o: Object, context: Context): never labels True,
False {
// Long-term, it's likely not a good idea to have this slow-path test here,
// since it fundamentally breaks the type system.
GotoIfForceSlowPath() otherwise False;
BranchIf<FastJSArray>(o) otherwise True, False;
}
macro BranchIfFastJSArrayForRead(o: Object, context: Context): never
labels True, False {
@export
macro BranchIfFastJSArrayForRead(o: Object, context: Context):
never labels True, False {
// Long-term, it's likely not a good idea to have this slow-path test here,
// since it fundamentally breaks the type system.
GotoIfForceSlowPath() otherwise False;
......@@ -2857,6 +2858,7 @@ macro BranchIfFastJSArrayForCopy(o: Object, context: Context): never
BranchIf<FastJSArrayForCopy>(o) otherwise True, False;
}
@export
macro IsFastJSArrayWithNoCustomIteration(context: Context, o: Object): bool {
return Is<FastJSArrayWithNoCustomIteration>(o);
}
......@@ -2914,6 +2916,7 @@ transitioning builtin FastCreateDataProperty(implicit context: Context)(
return Undefined;
}
@export
transitioning macro ToStringImpl(context: Context, o: Object): String {
let result: Object = o;
while (true) {
......
......@@ -5,9 +5,9 @@
#include 'src/builtins/builtins-collections-gen.h'
namespace collections {
@export
macro LoadKeyValuePairNoSideEffects(implicit context: Context)(o: Object):
KeyValuePair
labels MayHaveSideEffects {
KeyValuePair labels MayHaveSideEffects {
typeswitch (o) {
case (a: FastJSArray): {
const length: Smi = a.length;
......@@ -42,6 +42,7 @@ namespace collections {
}
}
@export
transitioning macro LoadKeyValuePair(implicit context: Context)(o: Object):
KeyValuePair {
try {
......
......@@ -141,6 +141,7 @@ Cast<ArgumentsAdaptorFrame>(implicit context: Context)(f: Frame):
// beginning of builtin code while the target value is still in the register
// and the former should be used in slow paths in order to reduce register
// pressure on the fast path.
@export
macro LoadTargetFromFrame(): JSFunction {
return LoadFramePointer().function;
}
......@@ -374,6 +374,7 @@ namespace typed_array_createtypedarray {
}
}
@export
transitioning macro TypedArraySpeciesCreateByLength(implicit context:
Context)(
methodName: constexpr string, exemplar: JSTypedArray,
......
......@@ -801,10 +801,12 @@ struct TorqueMacroDeclaration : MacroDeclaration {
TorqueMacroDeclaration(SourcePosition pos, bool transitioning,
std::string name, base::Optional<std::string> op,
ParameterList parameters, TypeExpression* return_type,
const LabelAndTypesVector& labels)
const LabelAndTypesVector& labels, bool export_to_csa)
: MacroDeclaration(kKind, pos, transitioning, std::move(name),
std::move(op), std::move(parameters), return_type,
labels) {}
labels),
export_to_csa(export_to_csa) {}
bool export_to_csa;
};
struct BuiltinDeclaration : CallableNode {
......
......@@ -320,15 +320,18 @@ class Macro : public Callable {
const std::string& external_assembler_name() const {
return external_assembler_name_;
}
bool IsAccessibleFromCSA() const { return accessible_from_csa_; }
protected:
Macro(Declarable::Kind kind, std::string external_name,
std::string readable_name, std::string external_assembler_name,
const Signature& signature, bool transitioning,
base::Optional<Statement*> body, bool is_user_defined)
base::Optional<Statement*> body, bool is_user_defined,
bool accessible_from_csa)
: Callable(kind, std::move(external_name), std::move(readable_name),
signature, transitioning, body),
external_assembler_name_(std::move(external_assembler_name)) {
external_assembler_name_(std::move(external_assembler_name)),
accessible_from_csa_(accessible_from_csa) {
SetIsUserDefined(is_user_defined);
if (signature.parameter_types.var_args) {
ReportError("Varargs are not supported for macros.");
......@@ -340,12 +343,13 @@ class Macro : public Callable {
Macro(std::string external_name, std::string readable_name,
std::string external_assembler_name, const Signature& signature,
bool transitioning, base::Optional<Statement*> body,
bool is_user_defined)
bool is_user_defined, bool accessible_from_csa)
: Macro(Declarable::kMacro, std::move(external_name),
std::move(readable_name), external_assembler_name, signature,
transitioning, body, is_user_defined) {}
transitioning, body, is_user_defined, accessible_from_csa) {}
std::string external_assembler_name_;
bool accessible_from_csa_;
};
class Method : public Macro {
......@@ -366,7 +370,7 @@ class Method : public Macro {
const Signature& signature, bool transitioning, Statement* body)
: Macro(Declarable::kMethod, std::move(external_name),
std::move(readable_name), std::move(external_assembler_name),
signature, transitioning, body, true),
signature, transitioning, body, true, false),
aggregate_type_(aggregate_type) {}
AggregateType* aggregate_type_;
};
......
......@@ -163,7 +163,7 @@ void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl,
const Signature& signature,
base::Optional<Statement*> body) {
Declarations::DeclareMacro(decl->name, decl->external_assembler_name,
Declarations::DeclareMacro(decl->name, true, decl->external_assembler_name,
signature, decl->transitioning, body, decl->op);
}
......@@ -177,9 +177,9 @@ void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl,
void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
const Signature& signature,
base::Optional<Statement*> body) {
Macro* macro =
Declarations::DeclareMacro(decl->name, base::nullopt, signature,
decl->transitioning, body, decl->op);
Macro* macro = Declarations::DeclareMacro(
decl->name, decl->export_to_csa, base::nullopt, signature,
decl->transitioning, body, decl->op);
// TODO(szuend): Set identifier_position to decl->name->pos once all callable
// names are changed from std::string to Identifier*.
macro->SetPosition(decl->pos);
......@@ -369,8 +369,8 @@ Callable* DeclarationVisitor::Specialize(
Callable* callable;
if (MacroDeclaration::DynamicCast(declaration) != nullptr) {
callable = Declarations::CreateMacro(
generated_name, readable_name.str(), base::nullopt, type_signature,
declaration->transitioning, *body, true);
generated_name, readable_name.str(), false, base::nullopt,
type_signature, declaration->transitioning, *body, true);
} else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) {
callable = Declarations::CreateIntrinsic(declaration->name, type_signature);
} else {
......
......@@ -154,19 +154,25 @@ const TypeAlias* Declarations::PredeclareTypeAlias(const Identifier* name,
Macro* Declarations::CreateMacro(
std::string external_name, std::string readable_name,
bool accessible_from_csa,
base::Optional<std::string> external_assembler_name, Signature signature,
bool transitioning, base::Optional<Statement*> body, bool is_user_defined) {
if (!accessible_from_csa) {
// TODO(tebbi): Switch to more predictable names to improve incremental
// compilation.
external_name += "_" + std::to_string(GlobalContext::FreshId());
}
if (!external_assembler_name) {
external_assembler_name = CurrentNamespace()->ExternalName();
}
return RegisterDeclarable(std::unique_ptr<Macro>(
new Macro(std::move(external_name), std::move(readable_name),
std::move(*external_assembler_name), std::move(signature),
transitioning, body, is_user_defined)));
transitioning, body, is_user_defined, accessible_from_csa)));
}
Macro* Declarations::DeclareMacro(
const std::string& name,
const std::string& name, bool accessible_from_csa,
base::Optional<std::string> external_assembler_name,
const Signature& signature, bool transitioning,
base::Optional<Statement*> body, base::Optional<std::string> op,
......@@ -175,8 +181,9 @@ Macro* Declarations::DeclareMacro(
ReportError("cannot redeclare macro ", name,
" with identical explicit parameters");
}
Macro* macro = CreateMacro(name, name, std::move(external_assembler_name),
signature, transitioning, body, is_user_defined);
Macro* macro = CreateMacro(name, name, accessible_from_csa,
std::move(external_assembler_name), signature,
transitioning, body, is_user_defined);
Declare(name, macro);
if (op) {
if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
......
......@@ -78,13 +78,13 @@ class Declarations {
TypeDeclaration* type,
bool redeclaration);
static Macro* CreateMacro(std::string external_name,
std::string readable_name,
std::string readable_name, bool accessible_from_csa,
base::Optional<std::string> external_assembler_name,
Signature signature, bool transitioning,
base::Optional<Statement*> body,
bool is_user_defined);
static Macro* DeclareMacro(
const std::string& name,
const std::string& name, bool accessible_from_csa,
base::Optional<std::string> external_assembler_name,
const Signature& signature, bool transitioning,
base::Optional<Statement*> body, base::Optional<std::string> op = {},
......
......@@ -80,6 +80,7 @@ class GlobalContext : public ContextualClass<GlobalContext> {
return Get().force_assert_statements_;
}
static Ast* ast() { return &Get().ast_; }
static size_t FreshId() { return Get().fresh_id_++; }
private:
bool collect_language_server_data_;
......@@ -89,6 +90,7 @@ class GlobalContext : public ContextualClass<GlobalContext> {
std::vector<std::unique_ptr<Declarable>> declarables_;
std::vector<std::string> cpp_includes_;
GlobalClassList classes_;
size_t fresh_id_ = 0;
friend class LanguageServerData;
};
......
......@@ -491,7 +491,8 @@ base::Optional<ParseResult> MakeIntrinsicDeclaration(
CallableNode* callable = nullptr;
if (body) {
callable = MakeNode<TorqueMacroDeclaration>(
false, name, base::Optional<std::string>{}, args, return_type, labels);
false, name, base::Optional<std::string>{}, args, return_type, labels,
false);
} else {
callable = MakeNode<IntrinsicDeclaration>(name, args, return_type);
}
......@@ -506,6 +507,7 @@ base::Optional<ParseResult> MakeIntrinsicDeclaration(
base::Optional<ParseResult> MakeTorqueMacroDeclaration(
ParseResultIterator* child_results) {
auto export_to_csa = child_results->NextAs<bool>();
auto transitioning = child_results->NextAs<bool>();
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
auto name = child_results->NextAs<std::string>();
......@@ -520,13 +522,15 @@ base::Optional<ParseResult> MakeTorqueMacroDeclaration(
auto return_type = child_results->NextAs<TypeExpression*>();
auto labels = child_results->NextAs<LabelAndTypesVector>();
auto body = child_results->NextAs<base::Optional<Statement*>>();
MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
transitioning, name, operator_name, args, return_type, labels);
MacroDeclaration* macro =
MakeNode<TorqueMacroDeclaration>(transitioning, name, operator_name, args,
return_type, labels, export_to_csa);
Declaration* result;
if (generic_parameters.empty()) {
if (!body) ReportError("A non-generic declaration needs a body.");
result = MakeNode<StandardDeclaration>(macro, *body);
} else {
if (export_to_csa) ReportError("Cannot export generics to CSA.");
result = MakeNode<GenericDeclaration>(macro, generic_parameters, body);
}
return ParseResult{result};
......@@ -641,7 +645,7 @@ base::Optional<ParseResult> MakeMethodDeclaration(
auto labels = child_results->NextAs<LabelAndTypesVector>();
auto body = child_results->NextAs<Statement*>();
MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
transitioning, name, operator_name, args, return_type, labels);
transitioning, name, operator_name, args, return_type, labels, false);
Declaration* result = MakeNode<StandardDeclaration>(macro, body);
return ParseResult{result};
}
......@@ -1880,7 +1884,7 @@ struct TorqueGrammar : Grammar {
{Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
&identifier, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
AsSingletonVector<Declaration*, MakeExternalRuntime>()),
Rule({CheckIf(Token("transitioning")),
Rule({CheckIf(Token("@export")), CheckIf(Token("transitioning")),
Optional<std::string>(
Sequence({Token("operator"), &externalString})),
Token("macro"), &identifier,
......
......@@ -393,8 +393,9 @@ void ClassType::GenerateAccessors() {
Statement* load_body =
MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
parameter, MakeNode<Identifier>(field.name_and_type.name)));
Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature,
false, load_body, base::nullopt, false);
Declarations::DeclareMacro(load_macro_name, true, base::nullopt,
load_signature, false, load_body, base::nullopt,
false);
// Store accessor
IdentifierExpression* value = MakeNode<IdentifierExpression>(
......@@ -413,8 +414,9 @@ void ClassType::GenerateAccessors() {
MakeNode<FieldAccessExpression>(
parameter, MakeNode<Identifier>(field.name_and_type.name)),
value));
Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature,
false, store_body, base::nullopt, false);
Declarations::DeclareMacro(store_macro_name, true, base::nullopt,
store_signature, false, store_body,
base::nullopt, false);
}
}
......
......@@ -34,16 +34,19 @@ namespace test {
goto Label3(Null, 7);
}
@export
macro TestConstexpr1() {
check(FromConstexpr<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS)));
}
@export
macro TestConstexprIf() {
check(ElementsKindTestHelper1(UINT8_ELEMENTS));
check(ElementsKindTestHelper1(UINT16_ELEMENTS));
check(!ElementsKindTestHelper1(UINT32_ELEMENTS));
}
@export
macro TestConstexprReturn() {
check(FromConstexpr<bool>(ElementsKindTestHelper3(UINT8_ELEMENTS)));
check(FromConstexpr<bool>(ElementsKindTestHelper3(UINT16_ELEMENTS)));
......@@ -51,6 +54,7 @@ namespace test {
check(FromConstexpr<bool>(!ElementsKindTestHelper3(UINT32_ELEMENTS)));
}
@export
macro TestGotoLabel(): Boolean {
try {
LabelTestHelper1() otherwise Label1;
......@@ -60,6 +64,7 @@ namespace test {
}
}
@export
macro TestGotoLabelWithOneParameter(): Boolean {
try {
LabelTestHelper2() otherwise Label2;
......@@ -70,6 +75,7 @@ namespace test {
}
}
@export
macro TestGotoLabelWithTwoParameters(): Boolean {
try {
LabelTestHelper3() otherwise Label3;
......@@ -89,6 +95,7 @@ namespace test {
return param;
}
@export
macro TestBuiltinSpecialization(c: Context) {
check(GenericBuiltinTest<Smi>(c, 0) == Null);
check(GenericBuiltinTest<Smi>(c, 1) == Null);
......@@ -117,6 +124,7 @@ namespace test {
}
}
@export
macro TestPartiallyUnusedLabel(): Boolean {
let r1: bool = CallLabelTestHelper4(true);
let r2: bool = CallLabelTestHelper4(false);
......@@ -146,6 +154,7 @@ namespace test {
return Cast<Smi>(param2) otherwise Y;
}
@export
macro TestMacroSpecialization() {
try {
const smi0: Smi = 0;
......@@ -173,6 +182,7 @@ namespace test {
return x + 2;
}
@export
macro TestFunctionPointers(implicit context: Context)(): Boolean {
let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1;
check(fptr(context, 42) == 43);
......@@ -181,17 +191,20 @@ namespace test {
return True;
}
@export
macro TestVariableRedeclaration(implicit context: Context)(): Boolean {
let var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
let var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
return True;
}
@export
macro TestTernaryOperator(x: Smi): Smi {
let b: bool = x < 0 ? true : false;
return b ? x - 10 : x + 100;
}
@export
macro TestFunctionPointerToGeneric(c: Context) {
let fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>;
let fptr2: builtin(Context, Object) => Object = GenericBuiltinTest<Object>;
......@@ -203,10 +216,12 @@ namespace test {
}
type ObjectToObject = builtin(Context, Object) => Object;
@export
macro TestTypeAlias(x: ObjectToObject): BuiltinPtr {
return x;
}
@export
macro TestUnsafeCast(implicit context: Context)(n: Number): Boolean {
if (TaggedIsSmi(n)) {
let m: Smi = UnsafeCast<Smi>(n);
......@@ -217,16 +232,19 @@ namespace test {
return False;
}
@export
macro TestHexLiteral() {
check(Convert<intptr>(0xffff) + 1 == 0x10000);
check(Convert<intptr>(-0xffff) == -65535);
}
@export
macro TestLargeIntegerLiterals(implicit c: Context)() {
let x: int32 = 0x40000000;
let y: int32 = 0x7fffffff;
}
@export
macro TestMultilineAssert() {
let someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5;
check(
......@@ -234,6 +252,7 @@ namespace test {
someVeryLongVariableNameThatWillCauseLineBreaks < 10);
}
@export
macro TestNewlineInString() {
Print('Hello, World!\n');
}
......@@ -242,12 +261,14 @@ namespace test {
const kIntptrConst: intptr = 4;
const kSmiConst: Smi = 3;
@export
macro TestModuleConstBindings() {
check(kConstexprConst == Int32Constant(5));
check(kIntptrConst == 4);
check(kSmiConst == 3);
}
@export
macro TestLocalConstBindings() {
const x: constexpr int31 = 3;
const xSmi: Smi = x;
......@@ -273,10 +294,12 @@ namespace test {
y: Smi;
}
@export
macro TestStruct1(i: TestStructA): Smi {
return i.i;
}
@export
macro TestStruct2(implicit context: Context)(): TestStructA {
return TestStructA{
indexes: UnsafeCast<FixedArray>(kEmptyFixedArray),
......@@ -285,6 +308,7 @@ namespace test {
};
}
@export
macro TestStruct3(implicit context: Context)(): TestStructA {
let a: TestStructA =
TestStructA{indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), i: 13, k: 5};
......@@ -310,12 +334,14 @@ namespace test {
y: TestStructA;
}
@export
macro TestStruct4(implicit context: Context)(): TestStructC {
return TestStructC{x: TestStruct2(), y: TestStruct2()};
}
macro TestStructInLabel(implicit context: Context)(): never
labels Foo(TestStructA) {
@export
macro TestStructInLabel(implicit context: Context)(): never labels
Foo(TestStructA) {
goto Foo(TestStruct2());
}
macro CallTestStructInLabel(implicit context: Context)() {
......@@ -327,6 +353,7 @@ namespace test {
// This macro tests different versions of the for-loop where some parts
// are (not) present.
@export
macro TestForLoop() {
let sum: Smi = 0;
for (let i: Smi = 0; i < 5; ++i) sum += i;
......@@ -426,6 +453,7 @@ namespace test {
}
}
@export
macro TestSubtyping(x: Smi) {
const foo: Object = x;
}
......@@ -471,6 +499,7 @@ namespace test {
return result;
}
@export
macro TestTypeswitch(implicit context: Context)() {
check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26);
const a: FixedArray = AllocateZeroedFixedArray(3);
......@@ -478,6 +507,7 @@ namespace test {
check(TypeswitchExample(FromConstexpr<Number>(0.5)) == 27);
}
@export
macro TestTypeswitchAsanLsanFailure(implicit context: Context)(obj: Object) {
typeswitch (obj) {
case (o: Smi): {
......@@ -498,6 +528,7 @@ namespace test {
return o + 1;
}
@export
macro TestGenericOverload(implicit context: Context)() {
const xSmi: Smi = 5;
const xObject: Object = xSmi;
......@@ -505,6 +536,7 @@ namespace test {
check(UnsafeCast<Smi>(ExampleGenericOverload<Object>(xObject)) == 5);
}
@export
macro TestEquality(implicit context: Context)() {
const notEqual: bool =
AllocateHeapNumberWithValue(0.5) != AllocateHeapNumberWithValue(0.5);
......@@ -523,30 +555,37 @@ namespace test {
}
}
@export
macro TestOrAnd1(x: bool, y: bool, z: bool): bool {
return BoolToBranch(x) || y && z ? true : false;
}
@export
macro TestOrAnd2(x: bool, y: bool, z: bool): bool {
return x || BoolToBranch(y) && z ? true : false;
}
@export
macro TestOrAnd3(x: bool, y: bool, z: bool): bool {
return x || y && BoolToBranch(z) ? true : false;
}
@export
macro TestAndOr1(x: bool, y: bool, z: bool): bool {
return BoolToBranch(x) && y || z ? true : false;
}
@export
macro TestAndOr2(x: bool, y: bool, z: bool): bool {
return x && BoolToBranch(y) || z ? true : false;
}
@export
macro TestAndOr3(x: bool, y: bool, z: bool): bool {
return x && y || BoolToBranch(z) ? true : false;
}
@export
macro TestLogicalOperators() {
check(TestAndOr1(true, true, true));
check(TestAndOr2(true, true, true));
......@@ -598,12 +637,13 @@ namespace test {
check(!TestOrAnd3(false, false, false));
}
macro TestCall(i: Smi): Smi
labels A {
@export
macro TestCall(i: Smi): Smi labels A {
if (i < 5) return i;
goto A;
}
@export
macro TestOtherwiseWithCode1() {
let v: Smi = 0;
let s: Smi = 1;
......@@ -616,6 +656,7 @@ namespace test {
assert(v == 2);
}
@export
macro TestOtherwiseWithCode2() {
let s: Smi = 0;
for (let i: Smi = 0; i < 10; ++i) {
......@@ -625,6 +666,7 @@ namespace test {
assert(s == 5);
}
@export
macro TestOtherwiseWithCode3() {
let s: Smi = 0;
for (let i: Smi = 0; i < 10; ++i) {
......@@ -633,6 +675,7 @@ namespace test {
assert(s == 10);
}
@export
macro TestForwardLabel() {
try {
goto A;
......@@ -645,11 +688,13 @@ namespace test {
}
}
@export
macro TestQualifiedAccess(implicit context: Context)() {
let s: Smi = 0;
check(!array::IsJSArray(s));
}
@export
macro TestCatch1(implicit context: Context)(): Smi {
let r: Smi = 0;
try {
......@@ -660,10 +705,12 @@ namespace test {
}
}
@export
macro TestCatch2Wrapper(implicit context: Context)(): never {
ThrowTypeError(kInvalidArrayLength);
}
@export
macro TestCatch2(implicit context: Context)(): Smi {
let r: Smi = 0;
try {
......@@ -674,11 +721,13 @@ namespace test {
}
}
macro TestCatch3WrapperWithLabel(implicit context: Context)(): never
labels Abort {
@export
macro TestCatch3WrapperWithLabel(implicit context: Context)():
never labels Abort {
ThrowTypeError(kInvalidArrayLength);
}
@export
macro TestCatch3(implicit context: Context)(): Smi {
let r: Smi = 0;
try {
......@@ -697,6 +746,7 @@ namespace test {
// it's only purpose is to make sure tha the CSA macros in the
// IteratorBuiltinsAssembler match the signatures provided in
// iterator.tq.
@export
macro TestIterator(implicit context: Context)(o: Object, map: Map) {
try {
const t1: Object = iterator::GetIteratorMethod(o);
......@@ -715,6 +765,7 @@ namespace test {
label Fail {}
}
@export
macro TestFrame1(implicit context: Context)() {
const f: Frame = LoadFramePointer();
const frameType: FrameType =
......@@ -733,6 +784,7 @@ namespace test {
}
}
@export
macro TestNew(implicit context: Context)() {
const f: JSArray = NewJSArray();
assert(f.IsEmpty());
......@@ -756,6 +808,7 @@ namespace test {
c: int32;
}
@export
macro TestStructConstructor(implicit context: Context)() {
// Test default constructor
let a: TestOuter = TestOuter{a: 5, b: TestInner{x: 6, y: 7}, c: 8};
......@@ -799,6 +852,7 @@ namespace test {
h: int32;
}
@export
macro TestClassWithAllTypesLoadsAndStores(
t: TestClassWithAllTypes, r: RawPtr, v1: int8, v2: uint8, v3: int16,
v4: uint16) {
......@@ -836,6 +890,7 @@ namespace test {
return new InternalClass{a: x, b: x + 1};
}
@export
macro TestInternalClass(implicit context: Context)() {
const o = NewInternalClass(5);
o.Flip() otherwise unreachable;
......@@ -854,6 +909,7 @@ namespace test {
const b: int32;
}
@export
macro TestConstInStructs() {
const x = StructWithConst{a: Null, b: 1};
let y = StructWithConst{a: Null, b: 1};
......@@ -869,6 +925,7 @@ namespace test {
count: Smi;
}
@export
macro TestNewFixedArrayFromSpread(implicit context: Context)(): Object {
const i = TestIterator{count: 5};
return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i};
......@@ -888,6 +945,7 @@ namespace test {
* b = tmp;
}
@export
macro TestReferences() {
const array = new SmiPair{a: 7, b: 2};
const ref:&Smi = & array.a;
......
......@@ -50,6 +50,7 @@ def preprocess(input):
input = re.sub(r'(\n\s*\S[^\n]*\s)otherwise',
r'\1_OtheSaLi', input)
input = re.sub(r'@if\(', r'@iF(', input)
input = re.sub(r'@export', r'@eXpOrT', input)
# Special handing of '%' for intrinsics, turn the percent
# into a unicode character so that it gets treated as part of the
......@@ -85,6 +86,8 @@ def postprocess(output):
output = re.sub(r'_OtheSaLi',
r"otherwise", output)
output = re.sub(r'@iF\(', r'@if(', output)
output = re.sub(r'@eXpOrT',
r"@export", output)
while True:
old = output
......
......@@ -30,7 +30,7 @@ syn keyword torqueFunction macro builtin runtime intrinsic
syn keyword torqueKeyword cast convert from_constexpr min max unsafe_cast
syn keyword torqueLabel case
syn keyword torqueMatching try label catch
syn keyword torqueModifier extern javascript constexpr transitioning transient weak
syn keyword torqueModifier extern javascript constexpr transitioning transient weak export
syn match torqueNumber /\v<[0-9]+(\.[0-9]*)?>/
syn match torqueNumber /\v<0x[0-9a-fA-F]+>/
syn keyword torqueOperator operator
......
......@@ -103,7 +103,7 @@
},
{
"name": "keyword.other.torque",
"match": "\\b(constexpr|macro|builtin|runtime|intrinsic|javascript|implicit|deferred|label|labels|tail|let|generates|weak|extern|const|typeswitch|case|transient|transitioning|operator|namespace)\\b"
"match": "\\b(constexpr|macro|builtin|runtime|intrinsic|javascript|implicit|deferred|label|labels|tail|let|generates|weak|extern|const|typeswitch|case|transient|transitioning|operator|namespace|export)\\b"
},
{
"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