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);
}
}
......
This diff is collapsed.
......@@ -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