--- node/deps/v8/include/v8.h +++ node/deps/v8/include/v8.h @@ -9525,10 +9525,14 @@ */ static void SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags); + static void EnableCompilationForSourcelessUse(); + static void DisableCompilationForSourcelessUse(); + static void FixSourcelessScript(Isolate* v8_isolate, Local script); + /** Get the version string. */ static const char* GetVersion(); /** * Initializes V8. This function needs to be called before the first Isolate --- node/deps/v8/src/api/api.cc +++ node/deps/v8/src/api/api.cc @@ -927,10 +927,38 @@ void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags); } + +bool save_lazy; +bool save_predictable; + + +void V8::EnableCompilationForSourcelessUse() { + save_lazy = i::FLAG_lazy; + i::FLAG_lazy = false; + save_predictable = i::FLAG_predictable; + i::FLAG_predictable = true; +} + + +void V8::DisableCompilationForSourcelessUse() { + i::FLAG_lazy = save_lazy; + i::FLAG_predictable = save_predictable; +} + + +void V8::FixSourcelessScript(Isolate* v8_isolate, Local unbound_script) { + auto isolate = reinterpret_cast(v8_isolate); + auto function_info = + i::Handle::cast(Utils::OpenHandle(*unbound_script)); + i::Handle script(i::Script::cast(function_info->script()), isolate); + script->set_source(i::ReadOnlyRoots(isolate).undefined_value()); +} + + RegisteredExtension* RegisteredExtension::first_extension_ = nullptr; RegisteredExtension::RegisteredExtension(std::unique_ptr extension) : extension_(std::move(extension)) {} --- node/deps/v8/src/codegen/compiler.cc +++ node/deps/v8/src/codegen/compiler.cc @@ -2045,11 +2045,11 @@ // First check per-isolate compilation cache. maybe_result = compilation_cache->LookupScript( source, script_details.name_obj, script_details.line_offset, script_details.column_offset, origin_options, isolate->native_context(), language_mode); - if (!maybe_result.is_null()) { + if (!maybe_result.is_null() && source_length) { compile_timer.set_hit_isolate_cache(); } else if (can_consume_code_cache) { compile_timer.set_consuming_code_cache(); // Then check cached code provided by embedder. HistogramTimerScope timer(isolate->counters()->compile_deserialize()); --- node/deps/v8/src/objects/js-objects.cc +++ node/deps/v8/src/objects/js-objects.cc @@ -5524,10 +5524,13 @@ // Check if we should print {function} as a class. Handle maybe_class_positions = JSReceiver::GetDataProperty( function, isolate->factory()->class_positions_symbol()); if (maybe_class_positions->IsClassPositions()) { + if (String::cast(Script::cast(shared_info->script()).source()).IsUndefined(isolate)) { + return isolate->factory()->NewStringFromAsciiChecked("class {}"); + } ClassPositions class_positions = ClassPositions::cast(*maybe_class_positions); int start_position = class_positions.start(); int end_position = class_positions.end(); Handle script_source( --- node/deps/v8/src/objects/shared-function-info-inl.h +++ node/deps/v8/src/objects/shared-function-info-inl.h @@ -493,10 +493,18 @@ // check if it is old. Note, this is done this way since this function can be // called by the concurrent marker. Object data = function_data(); if (!data.IsBytecodeArray()) return false; + Object script_obj = script(); + if (!script_obj.IsUndefined()) { + Script script = Script::cast(script_obj); + if (script.source().IsUndefined()) { + return false; + } + } + if (mode == BytecodeFlushMode::kStressFlushBytecode) return true; BytecodeArray bytecode = BytecodeArray::cast(data); return bytecode.IsOld(); --- node/deps/v8/src/parsing/parsing.cc +++ node/deps/v8/src/parsing/parsing.cc @@ -42,6 +42,7 @@ Isolate* isolate, ReportErrorsAndStatisticsMode mode) { DCHECK(info->flags().is_toplevel()); DCHECK_NULL(info->literal()); + if (String::cast(script->source()).IsUndefined(isolate)) return false; VMState state(isolate); @@ -76,6 +77,7 @@ // Create a character stream for the parser. Handle