Skip to content

Commit 1ab3f01

Browse files
authored
Merge branch 'main' into fix/122344-debugger-pause
2 parents 28edd58 + 1a9df91 commit 1ab3f01

File tree

185 files changed

+2201
-988
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

185 files changed

+2201
-988
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
excludeAgent: coding-agent
3+
---
4+
5+
# Code Review Instructions for dotnet/runtime
6+
7+
These instructions guide code reviews for the dotnet/runtime repository. A compiler runs on every PR (as do a wealth of static analyzers for C# changes), so focus on higher-level concerns that require expert judgment rather than stylistic or syntactic issues.
8+
9+
## Review Priorities
10+
11+
### 1. Security
12+
13+
**Critical Security Concerns:**
14+
- **Input Validation & Sanitization**: Ensure all external inputs (user data, file I/O, network data) are properly validated and sanitized before use
15+
- **Injection Vulnerabilities**: Check for potential SQL injection, command injection, path traversal, or code injection risks
16+
- **Cryptographic Operations**: Verify proper use of cryptographic APIs, secure random number generation, and correct handling of keys/certificates
17+
- **Buffer Overflows**: In native code, check for proper bounds checking and safe memory operations
18+
- **Authentication & Authorization**: Ensure proper access control checks are in place and cannot be bypassed
19+
- **Information Disclosure**: Watch for accidental logging or exposure of sensitive data (credentials, keys, PII)
20+
- **Denial of Service**: Check for potential infinite loops, resource exhaustion, or algorithmic complexity attacks
21+
- **Deserialization**: Ensure safe deserialization practices, especially with untrusted data
22+
- **Race Conditions**: Identify potential TOCTOU (time-of-check-time-of-use) vulnerabilities in security-sensitive operations
23+
24+
### 2. Performance
25+
26+
**Performance Considerations:**
27+
- **Algorithmic Complexity**: Identify inefficient algorithms (O(n²) where O(n) is possible, unnecessary allocations)
28+
- **Memory Allocations**: Watch for excessive allocations in hot paths, consider stack allocation (stackalloc) or object pooling where appropriate
29+
- **Boxing**: Identify unnecessary boxing of value types
30+
- **String Operations**: Check for string concatenation in loops (use StringBuilder), excessive string allocations
31+
- **LINQ Performance**: Evaluate LINQ usage in performance-critical paths; consider more direct alternatives
32+
- **Async/Await Overhead**: Ensure async/await is used appropriately (not for trivial synchronous operations)
33+
- **Collection Choices**: Verify appropriate collection types for access patterns (List vs. HashSet vs. Dictionary)
34+
- **Lazy Initialization**: Check for opportunities to defer expensive operations
35+
- **Caching**: Identify repeated expensive computations that could be cached
36+
- **Span<T> and Memory<T>**: Encourage use of modern memory-efficient types for buffer manipulation
37+
- **Native Interop**: Ensure P/Invoke calls are efficient and properly marshaled
38+
39+
### 3. Backwards Compatibility
40+
41+
**Compatibility Requirements:**
42+
- **Public API Changes**: Any change to public APIs requires careful scrutiny
43+
- Breaking changes are generally not acceptable
44+
- New optional parameters, overloads, and interface implementations need careful consideration
45+
- Verify that API additions follow existing patterns and naming conventions
46+
- **Serialization Compatibility**: Ensure changes don't break serialization/deserialization of persisted data
47+
- **Configuration Changes**: Changes to configuration format or behavior must maintain backwards compatibility
48+
- **Binary Compatibility**: IL-level changes must preserve binary compatibility for existing assemblies
49+
- **Behavioral Changes**: Even non-breaking API changes can break consumers if behavior changes unexpectedly
50+
- Document behavioral changes clearly
51+
- Consider feature flags or opt-in mechanisms for significant behavior changes
52+
- **Obsolete APIs**: Check that proper obsolescence process is followed (attributes, documentation, migration path)
53+
54+
### 4. Cross-Component Interactions
55+
56+
**Integration Points:**
57+
- **Runtime/Library Boundaries**: Changes affecting CoreCLR, Mono, or NativeAOT must work across all runtimes
58+
- **Platform Differences**: Ensure changes work correctly across Windows, Linux, macOS, and other supported platforms
59+
- **Architecture Considerations**: Verify behavior is correct on x86, x64, ARM32, and ARM64
60+
- **Dependencies**: Changes to core libraries may impact higher-level libraries; consider cascading effects
61+
- **Threading Models**: Ensure thread-safety is maintained and synchronization primitives are used correctly
62+
- **Lifecycle Management**: Verify proper initialization, disposal patterns, and cleanup across component boundaries
63+
- **Shared State**: Carefully review any shared mutable state for thread-safety and consistency
64+
- **Error Handling**: Ensure exceptions and error codes are properly propagated across component boundaries
65+
66+
### 5. Correctness and Edge Cases
67+
68+
**Code Correctness:**
69+
- **Null Handling**: While the compiler enforces nullable reference types, verify runtime null checks are appropriate
70+
- **Boundary Conditions**: Test for off-by-one errors, empty collections, null inputs, maximum values
71+
- **Error Paths**: Ensure error handling is correct and complete; resources are properly cleaned up
72+
- **Concurrency**: Identify race conditions, deadlocks, or improper synchronization
73+
- **Exception Safety**: Verify operations maintain invariants even when exceptions occur
74+
- **Resource Management**: Ensure IDisposable is implemented correctly and resources are not leaked
75+
- **Numeric Overflow**: Check for potential integer overflow/underflow in calculations
76+
- **Culture/Locale Issues**: Verify culture-invariant operations where appropriate, proper localization otherwise
77+
- **Time Handling**: Check for timezone, daylight saving, and leap second handling issues
78+
79+
### 6. Design and Architecture
80+
81+
**Design Quality:**
82+
- **API Design**: Ensure new APIs are intuitive, follow framework design guidelines, and are hard to misuse
83+
- **Abstraction Level**: Verify abstractions are at the appropriate level and don't leak implementation details
84+
- **Separation of Concerns**: Check that responsibilities are properly separated
85+
- **Extensibility**: Consider whether the design allows for future extension without breaking changes
86+
- **SOLID Principles**: Evaluate adherence to single responsibility, open/closed, and other design principles
87+
- **Code Duplication**: Identify opportunities to reduce duplication while maintaining clarity
88+
- **Testability**: Ensure the code is designed to be testable (proper dependency injection, separation of concerns)
89+
90+
### 7. Testing
91+
92+
**Test Quality:**
93+
- **Coverage**: Ensure new functionality has appropriate test coverage
94+
- **Test Scenarios**: Verify tests cover happy paths, error paths, and edge cases
95+
- **Test Reliability**: Watch for flaky tests (timing dependencies, environmental assumptions)
96+
- **Test Performance**: Ensure tests run efficiently and don't unnecessarily slow down CI
97+
- **Platform-Specific Tests**: Verify platform-specific tests are properly conditioned
98+
- **Regression Tests**: Check that bugs being fixed have corresponding regression tests
99+
100+
### 8. Documentation and Code Clarity
101+
102+
**Documentation:**
103+
- **XML Documentation**: New public APIs must have clear XML documentation explaining purpose, parameters, return values, and exceptions. Do not comment on existing APIs that lack documentation.
104+
- **Complex Logic**: Comments should explain the "why" behind non-obvious decisions, not restate what the code does
105+
- **TODOs and FIXMEs**: Ensure they are tracked with issues and are appropriate for the change
106+
- **Breaking Changes**: Must be clearly documented with migration guidance
107+
108+
## What NOT to Focus On
109+
110+
The following are handled by automated tooling and don't need review comments:
111+
112+
- Code formatting and style (handled by `.editorconfig` and analyzers)
113+
- Naming convention violations (handled by analyzers)
114+
- Missing using directives (handled by compiler)
115+
- Most syntax errors (handled by compiler)
116+
- Simple code style preferences without technical merit
117+
118+
## Review Approach
119+
120+
1. **Understand the Context**: Read the PR description and linked issues to understand the goal. Consider as much relevant code from the containing project as possible. For public APIs, review any code in the repo that consumes the method.
121+
2. **Assess the Scope**: Verify the change is focused and not mixing unrelated concerns
122+
3. **Evaluate Risk**: Consider the risk level based on what components are affected and how widely used they are
123+
4. **Think Like an Attacker**: For security-sensitive code, consider how it might be exploited
124+
5. **Think Like a Consumer**: Consider how the API will be used and potentially misused
125+
6. **Consider Maintenance**: Think about long-term maintenance burden and technical debt
126+
127+
## Severity Guidelines
128+
129+
- **Critical**: Security vulnerabilities, data corruption, crashes, breaking changes
130+
- **High**: Performance regressions, resource leaks, incorrect behavior in common scenarios
131+
- **Medium**: Edge case bugs, suboptimal design, missing documentation
132+
- **Low**: Code clarity issues, minor inefficiencies, nice-to-have improvements

.github/copilot-instructions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
excludeAgent: code-review-agent
3+
---
4+
15
**Any code you commit SHOULD compile, and new and existing tests related to the change SHOULD pass.**
26

37
You MUST make your best effort to ensure your changes satisfy those criteria before committing. If for any reason you were unable to build or test the changes, you MUST report that. You MUST NOT claim success unless all builds and tests pass as described above.

Directory.Build.props

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@
3636
- src/mono/msbuild/common/MonoAOTCompiler.props
3737
- src/tasks/AppleAppBuilder/Xcode.cs
3838
- src/tasks/MobileBuildTasks/Apple/AppleProject.cs
39+
- src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets
3940
- https://github.com/dotnet/sdk repo > src/Installer/redist-installer/targets/GeneratePKG.targets
4041
-->
4142
<AndroidApiLevelMin>21</AndroidApiLevelMin>
42-
<iOSVersionMin>12.2</iOSVersionMin>
43-
<tvOSVersionMin>12.2</tvOSVersionMin>
43+
<iOSVersionMin>13.0</iOSVersionMin>
44+
<tvOSVersionMin>13.0</tvOSVersionMin>
4445
<macOSVersionMin>12.0</macOSVersionMin>
45-
<MacCatalystVersionMin>15.0</MacCatalystVersionMin>
46+
<MacCatalystVersionMin>15.2</MacCatalystVersionMin>
4647
</PropertyGroup>
4748

4849
<PropertyGroup>

docs/workflow/ci/triaging-failures.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,6 @@ set RunningIlasmRoundTrip=1
6060
```
6161
triggers an ildasm/ilasm round-trip test (that is, the test assembly is disassembled, then re-assembled, then run).
6262

63-
And,
64-
```
65-
set DoLink=1
66-
```
67-
triggers ILLink testing.
68-
6963
## Product and test assets
7064

7165
To reproduce and/or debug a test failure, you'll need the product and test assets. You can either build these using the normal build processes,

eng/build.ps1

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,16 @@ if ($vs) {
181181
$configToOpen = $runtimeConfiguration
182182
}
183183

184-
# Auto-generated solution file that still uses the sln format
185-
if ($vs -ieq "coreclr.sln" -or $vs -ieq "coreclr") {
186-
# If someone passes in coreclr.sln or just coreclr (case-insensitive),
187-
# launch the generated CMake solution.
188-
$vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "artifacts\obj\coreclr" | Join-Path -ChildPath "windows.$archToOpen.$((Get-Culture).TextInfo.ToTitleCase($configToOpen))" | Join-Path -ChildPath "ide" | Join-Path -ChildPath "CoreCLR.sln"
184+
# Auto-generated solution file that uses the sln or slnx format
185+
if ($vs -match "^coreclr(\.slnx|\.sln)?$") {
186+
# If someone passes in coreclr.sln or coreclr.slnx or just coreclr (case-insensitive),
187+
# launch the generated CMake solution with the right extension, defaulting to slnx.
188+
$ext = [System.IO.Path]::GetExtension($vs)
189+
if ([string]::IsNullOrEmpty($ext)) {
190+
$ext = ".slnx"
191+
}
192+
193+
$vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "artifacts\obj\coreclr" | Join-Path -ChildPath "windows.$archToOpen.$((Get-Culture).TextInfo.ToTitleCase($configToOpen))" | Join-Path -ChildPath "ide" | Join-Path -ChildPath "CoreCLR$ext"
189194
if (-Not (Test-Path $vs)) {
190195
Invoke-Expression "& `"$repoRoot/eng/common/msbuild.ps1`" $repoRoot/src/coreclr/runtime.proj /clp:nosummary /restore /p:Ninja=false /p:Configuration=$configToOpen /p:TargetArchitecture=$archToOpen /p:ConfigureOnly=true /p:ClrFullNativeBuild=true"
191196
if ($lastExitCode -ne 0) {
@@ -197,9 +202,14 @@ if ($vs) {
197202
}
198203
}
199204
}
200-
# Auto-generated solution file that still uses the sln format
201-
elseif ($vs -ieq "corehost.sln" -or $vs -ieq "corehost") {
202-
$vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "artifacts\obj\" | Join-Path -ChildPath "win-$archToOpen.$((Get-Culture).TextInfo.ToTitleCase($configToOpen))" | Join-Path -ChildPath "corehost" | Join-Path -ChildPath "ide" | Join-Path -ChildPath "corehost.sln"
205+
# Auto-generated solution file that uses the sln or slnx format
206+
elseif ($vs -match "^corehost(\.slnx|\.sln)?$") {
207+
$ext = [System.IO.Path]::GetExtension($vs)
208+
if ([string]::IsNullOrEmpty($ext)) {
209+
$ext = ".slnx"
210+
}
211+
212+
$vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "artifacts\obj\" | Join-Path -ChildPath "win-$archToOpen.$((Get-Culture).TextInfo.ToTitleCase($configToOpen))" | Join-Path -ChildPath "corehost" | Join-Path -ChildPath "ide" | Join-Path -ChildPath "corehost$ext"
203213
if (-Not (Test-Path $vs)) {
204214
Invoke-Expression "& `"$repoRoot/eng/common/msbuild.ps1`" $repoRoot/src/native/corehost/corehost.proj /clp:nosummary /restore /p:Ninja=false /p:Configuration=$configToOpen /p:TargetArchitecture=$archToOpen /p:ConfigureOnly=true"
205215
if ($lastExitCode -ne 0) {

eng/docker/libraries-sdk.windows.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ USER ContainerAdministrator
1414
# remove the existing ASP.NET SDK, we want to keep only the latest one we download later
1515
RUN Remove-Item -Force -Recurse 'C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/*'
1616

17-
RUN Invoke-WebRequest -Uri https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1 -OutFile .\dotnet-install.ps1
17+
RUN Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1 -OutFile .\dotnet-install.ps1
1818
RUN & .\dotnet-install.ps1 -Channel $env:_DOTNET_INSTALL_CHANNEL -Quality daily -InstallDir 'C:/Program Files/dotnet'
1919

2020
USER ContainerUser

eng/native/build-commons.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ build_native()
9393

9494
# set default macCatalyst deployment target
9595
# keep in sync with SetOSTargetMinVersions in the root Directory.Build.props
96-
cmakeArgs="-DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_OSX_SYSROOT=macosx -DCMAKE_SYSTEM_VARIANT=maccatalyst -DCMAKE_OSX_DEPLOYMENT_TARGET=15.0 $cmakeArgs"
96+
cmakeArgs="-DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_OSX_SYSROOT=macosx -DCMAKE_SYSTEM_VARIANT=maccatalyst -DCMAKE_OSX_DEPLOYMENT_TARGET=15.2 $cmakeArgs"
9797
fi
9898

9999
if [[ "$targetOS" == android || "$targetOS" == linux-bionic ]]; then
@@ -127,7 +127,7 @@ build_native()
127127

128128
# set default iOS simulator deployment target
129129
# keep in sync with SetOSTargetMinVersions in the root Directory.Build.props
130-
cmakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $cmakeArgs"
130+
cmakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs"
131131
if [[ "$__TargetArch" == x64 ]]; then
132132
cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs"
133133
elif [[ "$__TargetArch" == arm64 ]]; then
@@ -141,7 +141,7 @@ build_native()
141141

142142
# set default iOS device deployment target
143143
# keep in sync with SetOSTargetMinVersions in the root Directory.Build.props
144-
cmakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $cmakeArgs"
144+
cmakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs"
145145
if [[ "$__TargetArch" == arm64 ]]; then
146146
cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs"
147147
else
@@ -153,7 +153,7 @@ build_native()
153153

154154
# set default tvOS simulator deployment target
155155
# keep in sync with SetOSTargetMinVersions in the root Directory.Build.props
156-
cmakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $cmakeArgs"
156+
cmakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs"
157157
if [[ "$__TargetArch" == x64 ]]; then
158158
cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs"
159159
elif [[ "$__TargetArch" == arm64 ]]; then
@@ -167,7 +167,7 @@ build_native()
167167

168168
# set default tvOS device deployment target
169169
# keep in sync with SetOSTargetMinVersions in the root Directory.Build.props
170-
cmakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $cmakeArgs"
170+
cmakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs"
171171
if [[ "$__TargetArch" == arm64 ]]; then
172172
cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs"
173173
else

eng/native/configurecompiler.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,10 +705,10 @@ if (CLR_CMAKE_HOST_UNIX OR CLR_CMAKE_HOST_WASI)
705705
endif()
706706
add_link_options(${DISABLE_OVERRIDING_MIN_VERSION_ERROR})
707707
if(CLR_CMAKE_HOST_ARCH_ARM64)
708-
set(CLR_CMAKE_MACCATALYST_COMPILER_TARGET "arm64-apple-ios15.0-macabi")
708+
set(CLR_CMAKE_MACCATALYST_COMPILER_TARGET "arm64-apple-ios15.2-macabi")
709709
add_link_options(-target ${CLR_CMAKE_MACCATALYST_COMPILER_TARGET})
710710
elseif(CLR_CMAKE_HOST_ARCH_AMD64)
711-
set(CLR_CMAKE_MACCATALYST_COMPILER_TARGET "x86_64-apple-ios15.0-macabi")
711+
set(CLR_CMAKE_MACCATALYST_COMPILER_TARGET "x86_64-apple-ios15.2-macabi")
712712
add_link_options(-target ${CLR_CMAKE_MACCATALYST_COMPILER_TARGET})
713713
else()
714714
clr_unknown_arch()

eng/pipelines/coreclr/templates/helix-queues-setup.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
helixQueues:
3434

3535
# iOS Simulator/Mac Catalyst arm64
36-
- ${{ if in(parameters.platform, 'maccatalyst_arm64', 'iossimulator_arm64') }}:
36+
- ${{ if in(parameters.platform, 'iossimulator_arm64', 'tvossimulator_arm64', 'maccatalyst_arm64') }}:
3737
- OSX.15.Arm64.Open
3838

3939
# iOS/tvOS Simulator x64 & MacCatalyst x64

eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
2424
isiOSLikeOnlyBuild: ${{ parameters.isiOSLikeOnlyBuild }}
2525
platforms:
26-
# - ios_arm64 TODO: Enable when Helix queue is available https://github.com/dotnet/dnceng/issues/6440
26+
# - ios_arm64 TODO: Enable when Helix queue upgrade is finished https://github.com/dotnet/runtime/issues/122452
2727
- tvos_arm64
2828
variables:
2929
# map dependencies variables to local variables
@@ -64,7 +64,7 @@ jobs:
6464
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
6565
isiOSLikeOnlyBuild: ${{ parameters.isiOSLikeOnlyBuild }}
6666
platforms:
67-
#- ios_arm64 TODO: Enable when Helix queue is available https://github.com/dotnet/dnceng/issues/6440
67+
# - ios_arm64 TODO: Enable when Helix queue upgrade is finished https://github.com/dotnet/runtime/issues/122452
6868
- tvos_arm64
6969
variables:
7070
- ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
@@ -109,7 +109,7 @@ jobs:
109109
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
110110
isiOSLikeOnlyBuild: ${{ parameters.isiOSLikeOnlyBuild }}
111111
platforms:
112-
- ios_arm64
112+
# - ios_arm64 TODO: Enable when Helix queue upgrade is finished https://github.com/dotnet/runtime/issues/122452
113113
- tvos_arm64
114114
variables:
115115
# map dependencies variables to local variables

0 commit comments

Comments
 (0)