diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 11acfcee40c..0f8baa91e6a 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -1049,6 +1049,7 @@ type ILReaderContext = userStringsStreamPhysicalLoc: int32; stringsStreamPhysicalLoc: int32; blobsStreamPhysicalLoc: int32; + blobsStreamSize: int32; readUserStringHeap: (int32 -> string); memoizeString: string -> string; readStringHeap: (int32 -> string); @@ -1534,9 +1535,13 @@ let readStringHeapUncached ctxtH idx = let readStringHeap ctxt idx = ctxt.readStringHeap idx let readStringHeapOption ctxt idx = if idx = 0 then None else Some (readStringHeap ctxt idx) +let emptyByteArray: byte[] = [||] let readBlobHeapUncached ctxtH idx = let ctxt = getHole ctxtH - seekReadBlob ctxt.is (ctxt.blobsStreamPhysicalLoc + idx) + // valid index lies in range [1..streamSize) + // NOTE: idx cannot be 0 - Blob\String heap has first empty element that is one byte 0 + if idx <= 0 || idx >= ctxt.blobsStreamSize then emptyByteArray + else seekReadBlob ctxt.is (ctxt.blobsStreamPhysicalLoc + idx) let readBlobHeap ctxt idx = ctxt.readBlobHeap idx let readBlobHeapOption ctxt idx = if idx = 0 then None else Some (readBlobHeap ctxt idx) @@ -3973,6 +3978,7 @@ let rec genOpenBinaryReader infile is opts = userStringsStreamPhysicalLoc = userStringsStreamPhysicalLoc; stringsStreamPhysicalLoc = stringsStreamPhysicalLoc; blobsStreamPhysicalLoc = blobsStreamPhysicalLoc; + blobsStreamSize = blobsStreamSize; memoizeString = Tables.memoize id; readUserStringHeap = cacheUserStringHeap (readUserStringHeapUncached ctxtH); readStringHeap = cacheStringHeap (readStringHeapUncached ctxtH); diff --git a/tests/fsharp/core/ilread/Library.dll b/tests/fsharp/core/ilread/Library.dll new file mode 100644 index 00000000000..7e724a12b20 Binary files /dev/null and b/tests/fsharp/core/ilread/Library.dll differ diff --git a/tests/fsharp/core/ilread/build.bat b/tests/fsharp/core/ilread/build.bat new file mode 100644 index 00000000000..8ee2cf351c6 --- /dev/null +++ b/tests/fsharp/core/ilread/build.bat @@ -0,0 +1,35 @@ +@if "%_echo%"=="" echo off + +setlocal +REM Configure the sample, i.e. where to find the F# compiler and C# compiler. +if EXIST build.ok DEL /f /q build.ok + +call %~d0%~p0..\..\..\config.bat +@if ERRORLEVEL 1 goto Error + +if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" ( + REM Skipping test for FSI.EXE + goto Skip +) + +"%FSC%" %fsc_flags% /r:Library.dll /out:test.exe test.fs +@if ERRORLEVEL 1 goto Error + +"%PEVERIFY%" test.exe +@if ERRORLEVEL 1 goto Error + +:Ok +echo Built fsharp %~f0 ok. +echo. > build.ok +endlocal +exit /b 0 + +:Skip +echo Skipped %~f0 +endlocal +exit /b 0 + + +:Error +endlocal +exit /b %ERRORLEVEL% diff --git a/tests/fsharp/core/ilread/run.bat b/tests/fsharp/core/ilread/run.bat new file mode 100644 index 00000000000..2cbceb83a46 --- /dev/null +++ b/tests/fsharp/core/ilread/run.bat @@ -0,0 +1,22 @@ +@if "%_echo%"=="" echo off + +setlocal +dir build.ok > NUL ) || ( + @echo 'build.ok' not found. + goto :ERROR +) + +call %~d0%~p0..\..\..\config.bat + +%CLIX% .\test.exe +if ERRORLEVEL 1 goto Error + +:Ok +echo Ran fsharp %~f0 ok. +endlocal +exit /b 0 + +:Error +endlocal +exit /b %ERRORLEVEL% + diff --git a/tests/fsharp/core/ilread/test.fs b/tests/fsharp/core/ilread/test.fs new file mode 100644 index 00000000000..160a97cb9e1 --- /dev/null +++ b/tests/fsharp/core/ilread/test.fs @@ -0,0 +1,8 @@ +open Library + +[] +let main _ = + let cls = Class1() + let len = cls.GetLength("123") + printfn "%O" len + if len = 3 then 0 else 1 \ No newline at end of file diff --git a/tests/test.lst b/tests/test.lst index 4489bbcb7f8..74ceee14e44 100644 --- a/tests/test.lst +++ b/tests/test.lst @@ -35,6 +35,7 @@ Core03 fsharp\core\innerpoly Core03,Smoke fsharp\core\int32 Core03 fsharp\core\internalsvisible Core03 fsharp\core\interop +Core03 fsharp\core\ilread Core03 fsharp\core\lazy Core03 fsharp\core\letrec Core03,Smoke fsharp\core\libtest