[parser] Remove AST/Parser support for JS Runtime calls

JS runtime calls are a vestige of the days when V8 had part
of its runtime implemented in JavaScript. This cleanup CL
removes parser/AST support JS runtime calls and removes the
special-casing for those slots in native contexts.

There are still two uses of CallJSRuntime in the interpreter, but
they hardcode their context indices. This CL updates the unittests
to hardcode the same indices for printing bytecode expectations.

Change-Id: I05756bf6575bcb93b0e9a89407a7239fb0f5b30d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5590413
Commit-Queue: Adam Klein <adamk@chromium.org>
Auto-Submit: Adam Klein <adamk@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94384}
This commit is contained in:
Adam Klein authored and V8 LUCI CQ committed 2024-06-11 18:05:36 +00:00
1 parent c1067a57c9
commit 03dbdef1b3
9 files changed
+32 -141

No files matched your search

-25
View File
@@ -38,22 +38,6 @@ namespace internal {
#ifdef DEBUG
static const char* NameForNativeContextIntrinsicIndex(uint32_t idx) {
switch (idx) {
#define NATIVE_CONTEXT_FIELDS_IDX(NAME, Type, name) \
case Context::NAME: \
return #name;
NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELDS_IDX)
#undef NATIVE_CONTEXT_FIELDS_IDX
default:
break;
}
return "UnknownIntrinsicIndex";
}
void AstNode::Print(Isolate* isolate) {
AstPrinter::PrintOut(isolate, this);
}
@@ -1132,14 +1116,5 @@ Literal* AstNodeFactory::NewNumberLiteral(double number, int pos) {
return zone_->New<Literal>(number, pos);
}
const char* CallRuntime::debug_name() {
#ifdef DEBUG
return is_jsruntime() ? NameForNativeContextIntrinsicIndex(context_index_)
: function_->name;
#else
return is_jsruntime() ? "(context function)" : function_->name;
#endif // DEBUG
}
} // namespace internal
} // namespace v8
+6 -29
View File
@@ -1823,24 +1823,12 @@ class SuperCallForwardArgs final : public Expression {
};
// The CallRuntime class does not represent any official JavaScript
// language construct. Instead it is used to call a C or JS function
// with a set of arguments. This is used from the builtins that are
// implemented in JavaScript.
// language construct. Instead it is used to call a runtime function
// with a set of arguments.
class CallRuntime final : public Expression {
public:
const ZonePtrList<Expression>* arguments() const { return &arguments_; }
bool is_jsruntime() const { return function_ == nullptr; }
int context_index() const {
DCHECK(is_jsruntime());
return context_index_;
}
const Runtime::Function* function() const {
DCHECK(!is_jsruntime());
return function_;
}
const char* debug_name();
const Runtime::Function* function() const { return function_; }
private:
friend class AstNodeFactory;
@@ -1850,15 +1838,10 @@ class CallRuntime final : public Expression {
const ScopedPtrList<Expression>& arguments, int pos)
: Expression(pos, kCallRuntime),
function_(function),
arguments_(arguments.ToConstVector(), zone) {}
CallRuntime(Zone* zone, int context_index,
const ScopedPtrList<Expression>& arguments, int pos)
: Expression(pos, kCallRuntime),
context_index_(context_index),
function_(nullptr),
arguments_(arguments.ToConstVector(), zone) {}
arguments_(arguments.ToConstVector(), zone) {
DCHECK_NOT_NULL(function_);
}
int context_index_;
const Runtime::Function* function_;
ZonePtrList<Expression> arguments_;
};
@@ -3239,12 +3222,6 @@ class AstNodeFactory final {
return zone_->New<CallRuntime>(zone_, function, arguments, pos);
}
CallRuntime* NewCallRuntime(int context_index,
const ScopedPtrList<Expression>& arguments,
int pos) {
return zone_->New<CallRuntime>(zone_, context_index, arguments, pos);
}
UnaryOperation* NewUnaryOperation(Token::Value op,
Expression* expression,
int pos) {
+1 -2
View File
@@ -1417,8 +1417,7 @@ void AstPrinter::VisitCallNew(CallNew* node) {
void AstPrinter::VisitCallRuntime(CallRuntime* node) {
base::EmbeddedVector<char, 128> buf;
SNPrintF(buf, "CALL RUNTIME %s%s", node->debug_name(),
node->is_jsruntime() ? " (JS function)" : "");
SNPrintF(buf, "CALL RUNTIME %s", node->function()->name);
IndentedScope indent(this, buf.begin(), node->position());
PrintArguments(node->arguments());
}
+5 -11
View File
@@ -6557,17 +6557,11 @@ void BytecodeGenerator::VisitSuperCallForwardArgs(SuperCallForwardArgs* expr) {
}
void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) {
RegisterList args = register_allocator()->NewGrowableRegisterList();
VisitArguments(expr->arguments(), &args);
builder()->CallJSRuntime(expr->context_index(), args);
} else {
// Evaluate all arguments to the runtime call.
RegisterList args = register_allocator()->NewGrowableRegisterList();
VisitArguments(expr->arguments(), &args);
Runtime::FunctionId function_id = expr->function()->function_id;
builder()->CallRuntime(function_id, args);
}
// Evaluate all arguments to the runtime call.
RegisterList args = register_allocator()->NewGrowableRegisterList();
VisitArguments(expr->arguments(), &args);
Runtime::FunctionId function_id = expr->function()->function_id;
builder()->CallRuntime(function_id, args);
}
void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
-26
View File
@@ -561,32 +561,6 @@ Handle<Object> Context::ErrorMessageForWasmCodeGeneration() {
"Wasm code generation disallowed by embedder");
}
#define COMPARE_NAME(index, type, name) \
if (string->IsOneByteEqualTo(base::StaticCharVector(#name))) return index;
int Context::IntrinsicIndexForName(DirectHandle<String> string) {
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(COMPARE_NAME);
return kNotFound;
}
#undef COMPARE_NAME
#define COMPARE_NAME(index, type, name) \
{ \
const int name_length = static_cast<int>(arraysize(#name)) - 1; \
if ((length == name_length) && strncmp(string, #name, name_length) == 0) \
return index; \
}
int Context::IntrinsicIndexForName(const unsigned char* unsigned_string,
int length) {
const char* string = reinterpret_cast<const char*>(unsigned_string);
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(COMPARE_NAME);
return kNotFound;
}
#undef COMPARE_NAME
#ifdef VERIFY_HEAP
namespace {
// TODO(v8:12298): Fix js-context-specialization cctests to set up full
+7 -13
View File
@@ -41,15 +41,6 @@ enum ContextLookupFlags {
// must always be allocated via Heap::AllocateContext() or
// Factory::NewContext.
#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \
V(ASYNC_MODULE_EVALUATE_INTERNAL, JSFunction, \
async_module_evaluate_internal) \
V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
V(FUNCTION_PROTOTYPE_APPLY_INDEX, JSFunction, function_prototype_apply)
#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSGlobalProxy, global_proxy_object) \
/* TODO(ishell): Actually we store exactly EmbedderDataArray here but */ \
@@ -58,7 +49,13 @@ enum ContextLookupFlags {
V(EMBEDDER_DATA_INDEX, HeapObject, embedder_data) \
V(CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX, HeapObject, \
continuation_preserved_embedder_data) \
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \
V(ASYNC_MODULE_EVALUATE_INTERNAL, JSFunction, \
async_module_evaluate_internal) \
V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
V(FUNCTION_PROTOTYPE_APPLY_INDEX, JSFunction, function_prototype_apply) \
/* TypedArray constructors - these must stay in order! */ \
V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \
V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \
@@ -623,9 +620,6 @@ class Context : public TorqueGeneratedContext<Context, HeapObject> {
Handle<Object> ErrorMessageForCodeGenerationFromStrings();
Handle<Object> ErrorMessageForWasmCodeGeneration();
static int IntrinsicIndexForName(DirectHandle<String> name);
static int IntrinsicIndexForName(const unsigned char* name, int length);
#define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
inline void set_##name(Tagged<UNPAREN(type)> value); \
inline bool is_##name(Tagged<UNPAREN(type)> value) const; \
+8 -20
View File
@@ -409,30 +409,18 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
return NewV8RuntimeFunctionForFuzzing(function, args, pos);
}
if (function != nullptr) {
// Check for possible name clash.
DCHECK_EQ(Context::kNotFound,
Context::IntrinsicIndexForName(name->raw_data(), name->length()));
// Check that the expected number of arguments are being passed.
if (function->nargs != -1 && function->nargs != args.length()) {
ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
return FailureExpression();
}
return factory()->NewCallRuntime(function, args, pos);
}
int context_index =
Context::IntrinsicIndexForName(name->raw_data(), name->length());
// Check that the function is defined.
if (context_index == Context::kNotFound) {
if (function == nullptr) {
ReportMessage(MessageTemplate::kNotDefined, name);
return FailureExpression();
}
return factory()->NewCallRuntime(context_index, args, pos);
// Check that the expected number of arguments are being passed.
if (function->nargs != -1 && function->nargs != args.length()) {
ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
return FailureExpression();
}
return factory()->NewCallRuntime(function, args, pos);
}
// More permissive runtime-function creation on fuzzers.
-6
View File
@@ -713,12 +713,6 @@ class PreParserFactory {
return PreParserStatement::Iteration();
}
PreParserExpression NewCallRuntime(
Runtime::FunctionId id, ZoneChunkList<PreParserExpression>* arguments,
int pos) {
return PreParserExpression::Default();
}
PreParserExpression NewImportCallExpression(const PreParserExpression& args,
int pos) {
return PreParserExpression::Default();
@@ -30,17 +30,13 @@ namespace interpreter {
static const char* NameForNativeContextIntrinsicIndex(uint32_t idx) {
switch (idx) {
#define COMPARE_NATIVE_CONTEXT_INTRINSIC_IDX(NAME, Type, name) \
case Context::NAME: \
return #name;
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(COMPARE_NATIVE_CONTEXT_INTRINSIC_IDX)
case Context::REFLECT_APPLY_INDEX:
return "reflect_apply";
case Context::REFLECT_CONSTRUCT_INDEX:
return "reflect_construct";
default:
break;
return "UnknownIntrinsicIndex";
}
return "UnknownIntrinsicIndex";
}
// static