Version 3.11.0-45.0.dev Merge 5b1be80bf9c741f1ebb6843270d469052c1c623f into dev
diff --git a/DEPS b/DEPS index 73924eb..490d4f8 100644 --- a/DEPS +++ b/DEPS
@@ -75,7 +75,7 @@ "jsc_tag": "version:301576", # https://chrome-infra-packages.appspot.com/p/fuchsia/third_party/clang - "clang_version": "git_revision:9d7449a82b83ee589b8af8d6f86525727788b3b9", + "clang_version": "git_revision:8b93f27cf7e6e53636db870873b53269efa3cca4", # https://chrome-infra-packages.appspot.com/p/gn/gn "gn_version": "git_revision:07d3c6f4dc290fae5ca6152ebcb37d6815c411ab", @@ -147,10 +147,10 @@ "sync_http_rev": "6666fff944221891182e1f80bf56569338164d72", "tar_rev": "13479f7c2a18f499e840ad470cfcca8c579f6909", "test_rev": "8083c8f24ffbca58cc0385add03c296b70636e7a", - "tools_rev": "d0941a357a297610f012114d4da06fcccebe6c5c", + "tools_rev": "ce126700df1901b5782e38320b389a674912d0d0", "vector_math_rev": "a7b7e9ccb931348dbfa669e0f8fea1bf97705b16", "web_rev": "5a7d0be70a258252b95bac6b900f26d6dae4d433", - "webdev_rev": "82b385574a65e6025f970ce204365851dbbc1ac1", + "webdev_rev": "b9c39c00853dfad0e235bec3b265f86a0f4f328a", "webdriver_rev": "09104f459ed834d48b132f6b7734923b1fbcf2e9", "webkit_inspection_protocol_rev": "0f7685804d77ec02c6564d7ac1a6c8a2341c5bdf",
diff --git a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart index 0ce6417..a7b1149 100644 --- a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart +++ b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
@@ -476,6 +476,11 @@ } @override + bool? visitNullAwareElement(NullAwareElement node) { + return _nodeExits(node.value); + } + + @override bool visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this)!;
diff --git a/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart b/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart index ded19fd..f3257bd 100644 --- a/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart +++ b/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart
@@ -108,6 +108,10 @@ _assertFalse('[if (c) throw 42 else 0]'); } + test_nullAwareElement() async { + _assertFalse('[?0]'); + } + void _assertFalse(String expressionCode) { _assertHasReturn(expressionCode, false); }
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart index 7c467b3..a1c53b2 100644 --- a/pkg/dds/lib/src/dap/adapters/dart.dart +++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -63,10 +63,10 @@ const _noResult = null; /// Pattern for extracting useful error messages from an evaluation exception. -final _evalErrorMessagePattern = RegExp('Error: (.*)'); +final _evalErrorMessagePattern = RegExp('Error: (.+)'); /// Pattern for extracting useful error messages from an unhandled exception. -final _exceptionMessagePattern = RegExp('Unhandled exception:\n(.*)'); +final _exceptionMessagePattern = RegExp('Unhandled exception:\n(.+)'); /// Pattern for a trailing semicolon. final _trailingSemicolonPattern = RegExp(r';$'); @@ -1124,26 +1124,24 @@ result = await vmEvaluate(thread, library.id!, expression); } } catch (e) { - final rawMessage = '$e'; - - // Error messages can be quite verbose and don't fit well into a - // single-line watch window. For example: + // Expression compilation errors may result in exceptions here (failed + // RCP requests) rather than a returned vm.ErrorRef: // // evaluateInFrame: (113) Expression compilation error // org-dartlang-debug:synthetic_debug_expression:1:5: Error: A value of type 'String' can't be assigned to a variable of type 'num'. // 1 + "a" // ^ - // - // So in the case of a Watch context, try to extract the useful message. - if (args.context == 'watch') { - throw DebugAdapterException(extractEvaluationErrorMessage(rawMessage)); - } - - throw DebugAdapterException(rawMessage); + _throwEvalError(args, '$e'); } if (result is vm.ErrorRef) { - throw DebugAdapterException(result.message ?? '<error ref>'); + // Some kinds of errors will return ErrorRefs: + // + // Unhandled exception: + // NoSuchMethodError: Class 'DateTime' has no instance getter 'ye'. + // Receiver: Instance of 'DateTime' + // Tried calling: ye + _throwEvalError(args, result.message ?? '<error ref>'); } else if (result is vm.Sentinel) { throw DebugAdapterException(result.valueAsString ?? '<collected>'); } else if (result is vm.InstanceRef && thread != null) { @@ -1183,6 +1181,19 @@ } } + /// Throws a [DebugAdapterException] for an expression evaluation error. + /// + /// For some contexts, parts of the error message may be extracted resulting + /// in a shorter message (for example to provide less noise in a Watch + /// window). + Never _throwEvalError(EvaluateArguments args, String message) { + if (args.context == 'watch') { + message = extractEvaluationErrorMessage(message); + } + + throw DebugAdapterException(message); + } + /// Tries to extract the useful part from an evaluation exception message. /// /// If no message could be extracted, returns the whole original error.
diff --git a/pkg/dds/test/dap/integration/debug_eval_test.dart b/pkg/dds/test/dap/integration/debug_eval_test.dart index 4a050f8..5fd6726 100644 --- a/pkg/dds/test/dap/integration/debug_eval_test.dart +++ b/pkg/dds/test/dap/integration/debug_eval_test.dart
@@ -196,7 +196,8 @@ ); }); - test('returns short errors for evaluation in "watch" context', () async { + test('returns short errors for evaluation in "watch" context (rpc error)', + () async { final client = dap.client; final testFile = dap.createTestFile(simpleBreakpointProgram); final breakpointLine = lineWith(testFile, breakpointMarker); @@ -205,6 +206,8 @@ final topFrameId = await client.getTopFrameId(stop.threadId!); expectResponseError( client.evaluate( + // This expression fails with an RPC error (expression compilation) + // so will be handled as a failed request in the DAP handler. '1 + "a"', frameId: topFrameId, context: 'watch', @@ -216,6 +219,26 @@ ); }); + test('returns short errors for evaluation in "watch" context (ErrorRef)', + () async { + final client = dap.client; + final testFile = dap.createTestFile(simpleBreakpointProgram); + final breakpointLine = lineWith(testFile, breakpointMarker); + + final stop = await client.hitBreakpoint(testFile, breakpointLine); + final topFrameId = await client.getTopFrameId(stop.threadId!); + expectResponseError( + client.evaluate( + // This expression compiles but returns an ErrorRef which must be + // handled specifically in the DAP handler. + 'DateTime.now().ye', + frameId: topFrameId, + context: 'watch', + ), + equals("Class 'DateTime' has no instance getter 'ye'."), + ); + }); + test('returns truncated strings by default', () async { final client = dap.client; final testFile = dap.createTestFile(simpleBreakpointProgram);
diff --git a/runtime/tools/dartfuzz/flag_fuzzer.dart b/runtime/tools/dartfuzz/flag_fuzzer.dart index 4f028a4..0b638ad 100644 --- a/runtime/tools/dartfuzz/flag_fuzzer.dart +++ b/runtime/tools/dartfuzz/flag_fuzzer.dart
@@ -159,10 +159,14 @@ } } -test(List<String> Function(String) createDartCommand, int taskIndex) async { +test( + List<String> Function(String) createDartCommand, + int taskIndex, + String extension, +) async { taskStart(); - var dartCommand = createDartCommand("out/dartfuzz/$taskIndex.js"); + var dartCommand = createDartCommand("out/dartfuzz/$taskIndex.$extension"); var dartScript = dartCommand[0]; var dartArguments = dartCommand.getRange(1, dartCommand.length).toList(); @@ -177,7 +181,11 @@ dartScript, ...dartArguments, ], - ["diff", "out/dartfuzz/expected.js", "out/dartfuzz/$taskIndex.js"], + [ + "diff", + "out/dartfuzz/expected.$extension", + "out/dartfuzz/$taskIndex.$extension", + ], ]; } else { // AOT @@ -203,7 +211,11 @@ "out/dartfuzz/$taskIndex.elf", ...dartArguments, ], - ["diff", "out/dartfuzz/expected.js", "out/dartfuzz/$taskIndex.js"], + [ + "diff", + "out/dartfuzz/expected.$extension", + "out/dartfuzz/$taskIndex.$extension", + ], ]; } @@ -254,19 +266,26 @@ taskEnd(); } -shard(List<String> Function(String) createDartCommand, int shardIndex) async { +shard( + List<String> Function(String) createDartCommand, + int shardIndex, + String extension, +) async { while (!remainingTimeout.isNegative) { - await test(createDartCommand, shardIndex); + await test(createDartCommand, shardIndex, extension); } } -flagFuzz(List<String> Function(String) createDartCommand) async { +flagFuzz( + List<String> Function(String) createDartCommand, + String extension, +) async { stopwatch.start(); await Directory("out/dartfuzz").create(); var executable = "out/ReleaseX64/dart"; - var arguments = createDartCommand("out/dartfuzz/expected.js"); + var arguments = createDartCommand("out/dartfuzz/expected.$extension"); var processResult = await Process.run(executable, arguments); if (processResult.exitCode != 0) { print("=== FAILURE ==="); @@ -280,6 +299,6 @@ } for (var i = 0; i < Platform.numberOfProcessors; i++) { - shard(createDartCommand, i); + shard(createDartCommand, i, extension); } }
diff --git a/runtime/tools/dartfuzz/flag_fuzzer_dart2js.dart b/runtime/tools/dartfuzz/flag_fuzzer_dart2js.dart index 9a4b462..16cb486 100644 --- a/runtime/tools/dartfuzz/flag_fuzzer_dart2js.dart +++ b/runtime/tools/dartfuzz/flag_fuzzer_dart2js.dart
@@ -16,4 +16,5 @@ "--no-source-maps", // Otherwise output includes path "pkg/compiler/lib/src/util/memory_compiler.dart", ], + "js", );
diff --git a/runtime/tools/dartfuzz/flag_fuzzer_dart2wasm.dart b/runtime/tools/dartfuzz/flag_fuzzer_dart2wasm.dart index e088c6e..56a39c6 100644 --- a/runtime/tools/dartfuzz/flag_fuzzer_dart2wasm.dart +++ b/runtime/tools/dartfuzz/flag_fuzzer_dart2wasm.dart
@@ -15,4 +15,5 @@ "pkg/compiler/lib/src/util/memory_compiler.dart", output, ], + "wasm", );
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc index 84f9888..abd267a 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.cc +++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1929,11 +1929,54 @@ } void Assembler::PushRegisters(const RegisterSet& registers) { - UNIMPLEMENTED(); + const intptr_t xmm_regs_count = registers.FpuRegisterCount(); + if (xmm_regs_count > 0) { + subl(ESP, compiler::Immediate(xmm_regs_count * kFpuRegisterSize)); + // Store XMM registers with the lowest register number at the lowest + // address. + intptr_t offset = 0; + for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) { + XmmRegister xmm_reg = static_cast<XmmRegister>(i); + if (registers.ContainsFpuRegister(xmm_reg)) { + movups(Address(ESP, offset), xmm_reg); + offset += kFpuRegisterSize; + } + } + ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); + } + + // The order in which the registers are pushed must match the order + // in which the registers are encoded in the safe point's stack map. + for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) { + Register reg = static_cast<Register>(i); + if (registers.ContainsRegister(reg)) { + pushl(reg); + } + } } void Assembler::PopRegisters(const RegisterSet& registers) { - UNIMPLEMENTED(); + for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) { + Register reg = static_cast<Register>(i); + if (registers.ContainsRegister(reg)) { + popl(reg); + } + } + + const intptr_t xmm_regs_count = registers.FpuRegisterCount(); + if (xmm_regs_count > 0) { + // XMM registers have the lowest register number at the lowest address. + intptr_t offset = 0; + for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) { + XmmRegister xmm_reg = static_cast<XmmRegister>(i); + if (registers.ContainsFpuRegister(xmm_reg)) { + movups(xmm_reg, Address(ESP, offset)); + offset += kFpuRegisterSize; + } + } + ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); + addl(ESP, compiler::Immediate(offset)); + } } void Assembler::PushRegistersInOrder(std::initializer_list<Register> regs) { @@ -2610,9 +2653,8 @@ compiler::Immediate(0)); } -static constexpr intptr_t kNumberOfVolatileCpuRegisters = 3; -static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { - EAX, ECX, EDX}; +static const RegisterSet kRuntimeCallSavedRegisters(kDartVolatileCpuRegs, + kDartVolatileFpuRegs); void Assembler::CallRuntime(const RuntimeEntry& entry, intptr_t argument_count, @@ -2635,21 +2677,7 @@ __ EnterFrame(0); if (preserve_registers_) { - // Preserve volatile CPU registers. - for (intptr_t i = 0; i < kNumberOfVolatileCpuRegisters; i++) { - __ pushl(volatile_cpu_registers[i]); - } - - // Preserve all XMM registers. - __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); - // Store XMM registers with the lowest register number at the lowest - // address. - intptr_t offset = 0; - for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { - XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); - __ movups(Address(ESP, offset), xmm_reg); - offset += kFpuRegisterSize; - } + __ PushRegisters(kRuntimeCallSavedRegisters); } else { // These registers must always be preserved. COMPILE_ASSERT(IsCalleeSavedRegister(THR)); @@ -2674,25 +2702,9 @@ // ESP might have been modified to reserve space for arguments // and ensure proper alignment of the stack frame. // We need to restore it before restoring registers. - const intptr_t kPushedRegistersSize = - kNumberOfVolatileCpuRegisters * target::kWordSize + - kNumberOfXmmRegisters * kFpuRegisterSize; - __ leal(ESP, Address(EBP, -kPushedRegistersSize)); + __ leal(ESP, Address(EBP, -kRuntimeCallSavedRegisters.SpillSize())); - // Restore all XMM registers. - // XMM registers have the lowest register number at the lowest address. - intptr_t offset = 0; - for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { - XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); - __ movups(xmm_reg, Address(ESP, offset)); - offset += kFpuRegisterSize; - } - __ addl(ESP, Immediate(offset)); - - // Restore volatile CPU registers. - for (intptr_t i = kNumberOfVolatileCpuRegisters - 1; i >= 0; i--) { - __ popl(volatile_cpu_registers[i]); - } + __ PopRegisters(kRuntimeCallSavedRegisters); } __ leave();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc index 0e05e3c..41f1b78 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -699,56 +699,12 @@ locs->CheckWritableInputs(); ClobberDeadTempRegisters(locs); #endif - // TODO(vegorov): consider saving only caller save (volatile) registers. - const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount(); - if (xmm_regs_count > 0) { - __ subl(ESP, compiler::Immediate(xmm_regs_count * kFpuRegisterSize)); - // Store XMM registers with the lowest register number at the lowest - // address. - intptr_t offset = 0; - for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) { - XmmRegister xmm_reg = static_cast<XmmRegister>(i); - if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) { - __ movups(compiler::Address(ESP, offset), xmm_reg); - offset += kFpuRegisterSize; - } - } - ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); - } - - // The order in which the registers are pushed must match the order - // in which the registers are encoded in the safe point's stack map. - for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) { - Register reg = static_cast<Register>(i); - if (locs->live_registers()->ContainsRegister(reg)) { - __ pushl(reg); - } - } + __ PushRegisters(*locs->live_registers()); } void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) { - for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) { - Register reg = static_cast<Register>(i); - if (locs->live_registers()->ContainsRegister(reg)) { - __ popl(reg); - } - } - - const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount(); - if (xmm_regs_count > 0) { - // XMM registers have the lowest register number at the lowest address. - intptr_t offset = 0; - for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) { - XmmRegister xmm_reg = static_cast<XmmRegister>(i); - if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) { - __ movups(xmm_reg, compiler::Address(ESP, offset)); - offset += kFpuRegisterSize; - } - } - ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); - __ addl(ESP, compiler::Immediate(offset)); - } + __ PopRegisters(*locs->live_registers()); } #if defined(DEBUG)
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 909b6ff..78cda92 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc
@@ -1246,7 +1246,7 @@ ConstantInstr* GraphEntryInstr::constant_null() { ASSERT(initial_definitions()->length() > 0); for (intptr_t i = 0; i < initial_definitions()->length(); ++i) { - ConstantInstr* defn = (*initial_definitions())[i] -> AsConstant(); + ConstantInstr* defn = (*initial_definitions())[i]->AsConstant(); if (defn != nullptr && defn->value().IsNull()) return defn; } UNREACHABLE();
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc index 2001717..175c61e 100644 --- a/runtime/vm/compiler/backend/il_printer.cc +++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -1520,7 +1520,7 @@ for (intptr_t i = 0; i < phis()->length(); ++i) { if ((*phis())[i] == nullptr) continue; f->AddString("\n "); - (*phis())[i] -> PrintTo(f); + (*phis())[i]->PrintTo(f); } f->AddString("\n}"); }
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h index 6a5f993..c8c3172 100644 --- a/runtime/vm/constants_ia32.h +++ b/runtime/vm/constants_ia32.h
@@ -393,11 +393,12 @@ const RegList kAbiPreservedCpuRegs = (1 << EDI) | (1 << ESI) | (1 << EBX); +const RegList kAbiVolatileFpuRegs = kAllFpuRegistersList; + // Registers available to Dart that are not preserved by runtime calls. const RegList kDartVolatileCpuRegs = kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs; - -const RegList kAbiVolatileFpuRegs = kAllFpuRegistersList; +const RegList kDartVolatileFpuRegs = kAbiVolatileFpuRegs & ~(1 << FpuTMP); #undef R
diff --git a/runtime/vm/regexp/regexp_ast.cc b/runtime/vm/regexp/regexp_ast.cc index 884fed9..3bfd878 100644 --- a/runtime/vm/regexp/regexp_ast.cc +++ b/runtime/vm/regexp/regexp_ast.cc
@@ -145,7 +145,7 @@ OS::PrintErr("(|"); for (intptr_t i = 0; i < that->alternatives()->length(); i++) { OS::PrintErr(" "); - (*that->alternatives())[i] -> Accept(this, data); + (*that->alternatives())[i]->Accept(this, data); } OS::PrintErr(")"); return nullptr; @@ -155,7 +155,7 @@ OS::PrintErr("(:"); for (intptr_t i = 0; i < that->nodes()->length(); i++) { OS::PrintErr(" "); - (*that->nodes())[i] -> Accept(this, data); + (*that->nodes())[i]->Accept(this, data); } OS::PrintErr(")"); return nullptr;
diff --git a/tools/VERSION b/tools/VERSION index 56567be..c7e24e7 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 3 MINOR 11 PATCH 0 -PRERELEASE 44 +PRERELEASE 45 PRERELEASE_PATCH 0