Skip to content

Commit

Permalink
Merge branch 'master' into feat/enumerable-to_a-block
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota authored Dec 22, 2023
2 parents a3d3632 + 3ecdf16 commit 75cf47c
Show file tree
Hide file tree
Showing 103 changed files with 14,596 additions and 369 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/llvm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
llvm_ubuntu_version: "18.04"
- llvm_version: "16.0.3"
llvm_ubuntu_version: "22.04"
- llvm_version: "17.0.2"
- llvm_version: "17.0.6"
llvm_ubuntu_version: "22.04"
name: "LLVM ${{ matrix.llvm_version }}"
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wasm32.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
rm wasm32-wasi-libs.tar.gz
- name: Build spec/wasm32_std_spec.cr
run: bin/crystal build spec/wasm32_std_spec.cr -o wasm32_std_spec.wasm --target wasm32-wasi -Duse_pcre -Dwithout_openssl
run: bin/crystal build spec/wasm32_std_spec.cr -o wasm32_std_spec.wasm --target wasm32-wasi -Dwithout_iconv -Dwithout_openssl
env:
CRYSTAL_LIBRARY_PATH: ${{ github.workspace }}/wasm32-wasi-libs

Expand Down
40 changes: 33 additions & 7 deletions .github/workflows/win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,21 +164,21 @@ jobs:
if: steps.cache-openssl-dlls.outputs.cache-hit != 'true'
run: .\etc\win-ci\build-openssl.ps1 -BuildTree deps\openssl -Version 3.1.0 -Dynamic

x86_64-windows-llvm:
x86_64-windows-llvm-libs:
runs-on: windows-2022
steps:
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1

- name: Cache LLVM
id: cache-llvm
id: cache-llvm-libs
uses: actions/cache@v3
with:
path: llvm
key: llvm-libs-${{ env.CI_LLVM_VERSION }}-msvc

- name: Download LLVM
if: steps.cache-llvm.outputs.cache-hit != 'true'
if: steps.cache-llvm-libs.outputs.cache-hit != 'true'
run: |
iwr https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ env.CI_LLVM_VERSION }}/llvm-${{ env.CI_LLVM_VERSION }}.src.tar.xz -OutFile llvm.tar.xz
(Get-FileHash -Algorithm SHA256 .\llvm.tar.xz).hash -eq "D820E63BC3A6F4F833EC69A1EF49A2E81992E90BC23989F98946914B061AB6C7"
Expand All @@ -187,7 +187,7 @@ jobs:
mv llvm-* llvm-src
- name: Download LLVM's CMake files
if: steps.cache-llvm.outputs.cache-hit != 'true'
if: steps.cache-llvm-libs.outputs.cache-hit != 'true'
run: |
iwr https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ env.CI_LLVM_VERSION }}/cmake-${{ env.CI_LLVM_VERSION }}.src.tar.xz -OutFile cmake.tar.xz
(Get-FileHash -Algorithm SHA256 .\cmake.tar.xz).hash -eq "B6D83C91F12757030D8361DEDC5DD84357B3EDB8DA406B5D0850DF8B6F7798B1"
Expand All @@ -196,16 +196,42 @@ jobs:
mv cmake-* cmake
- name: Build LLVM
if: steps.cache-llvm.outputs.cache-hit != 'true'
if: steps.cache-llvm-libs.outputs.cache-hit != 'true'
run: |
mkdir llvm-build
cd llvm-build
cmake ..\llvm-src -Thost=x64 -DLLVM_TARGETS_TO_BUILD="X86;AArch64" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DBUILD_SHARED_LIBS=OFF -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF
cmake --build . --config Release
cmake "-DCMAKE_INSTALL_PREFIX=$(pwd)\..\llvm" -P cmake_install.cmake
x86_64-windows-llvm-dlls:
runs-on: windows-2022
steps:
- name: Disable CRLF line ending substitution
run: |
git config --global core.autocrlf false
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1

- name: Download Crystal source
uses: actions/checkout@v4

- name: Cache LLVM
id: cache-llvm-dlls
uses: actions/cache@v3
with:
path: |
libs/llvm_VERSION
libs/llvm-dynamic.lib
dlls/LLVM-C.dll
key: llvm-dlls-${{ env.CI_LLVM_VERSION }}-${{ hashFiles('etc/win-ci/build-llvm.ps1') }}-msvc
- name: Build LLVM
if: steps.cache-llvm-dlls.outputs.cache-hit != 'true'
run: .\etc\win-ci\build-llvm.ps1 -BuildTree deps\llvm -Version ${{ env.CI_LLVM_VERSION }} -TargetsToBuild X86,AArch64 -Dynamic

x86_64-windows:
needs: [x86_64-windows-libs, x86_64-windows-dlls, x86_64-windows-llvm]
needs: [x86_64-windows-libs, x86_64-windows-dlls, x86_64-windows-llvm-libs, x86_64-windows-llvm-dlls]
uses: ./.github/workflows/win_build_portable.yml
with:
release: false
Expand Down Expand Up @@ -258,7 +284,7 @@ jobs:

x86_64-windows-release:
if: github.repository_owner == 'crystal-lang' && (startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/ci/'))
needs: [x86_64-windows-libs, x86_64-windows-dlls, x86_64-windows-llvm]
needs: [x86_64-windows-libs, x86_64-windows-dlls, x86_64-windows-llvm-libs, x86_64-windows-llvm-dlls]
uses: ./.github/workflows/win_build_portable.yml
with:
release: true
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/win_build_portable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ jobs:
path: llvm
key: llvm-libs-${{ inputs.llvm_version }}-msvc
fail-on-cache-miss: true
- name: Restore LLVM DLLs
uses: actions/cache/restore@v3
with:
path: |
libs/llvm_VERSION
libs/llvm-dynamic.lib
dlls/LLVM-C.dll
key: llvm-dlls-${{ inputs.llvm_version }}-${{ hashFiles('etc/win-ci/build-llvm.ps1') }}-msvc
fail-on-cache-miss: true

- name: Set up environment
run: |
Expand Down
42 changes: 42 additions & 0 deletions etc/win-ci/build-llvm.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
param(
[Parameter(Mandatory)] [string] $BuildTree,
[Parameter(Mandatory)] [string] $Version,
[Parameter(Mandatory)] [string[]] $TargetsToBuild,
[switch] $Dynamic
)

if (-not $Dynamic) {
Write-Host "Error: Building LLVM as a static library is not supported yet" -ForegroundColor Red
Exit 1
}

. "$(Split-Path -Parent $MyInvocation.MyCommand.Path)\setup.ps1"

[void](New-Item -Name (Split-Path -Parent $BuildTree) -ItemType Directory -Force)
Setup-Git -Path $BuildTree -Url https://github.com/llvm/llvm-project.git -Ref llvmorg-$Version

Run-InDirectory $BuildTree\build {
$args = "-Thost=x64 -DLLVM_TARGETS_TO_BUILD=""$($TargetsToBuild -join ';')"" -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF"
if ($Dynamic) {
$args = "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL $args"
} else {
$args = "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DLLVM_BUILD_LLVM_C_DYLIB=OFF $args"
}
& $cmake ..\llvm $args.split(' ')
& $cmake --build . --config Release --target llvm-config --target LLVM-C
if (-not $?) {
Write-Host "Error: Failed to build LLVM" -ForegroundColor Red
Exit 1
}
}

if ($Dynamic) {
mv -Force $BuildTree\build\Release\lib\LLVM-C.lib libs\llvm-dynamic.lib
mv -Force $BuildTree\build\Release\bin\LLVM-C.dll dlls\
} else {
# TODO (probably never)
}

Add-Content libs\llvm_VERSION $(& "$BuildTree\build\Release\bin\llvm-config.exe" --version)
Add-Content libs\llvm_VERSION $(& "$BuildTree\build\Release\bin\llvm-config.exe" --targets-built)
Add-Content libs\llvm_VERSION $(& "$BuildTree\build\Release\bin\llvm-config.exe" --system-libs)
82 changes: 82 additions & 0 deletions scripts/generate_llvm_version_info.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#! /usr/bin/env crystal
#
# This script generates the `lib/llvm_VERSION` file from LLVM-C.dll, needed for
# dynamically linking against LLVM on Windows. This is only needed when using an
# LLVM installation different from the one bundled with Crystal.

require "c/libloaderapi"

# The list of supported targets are hardcoded in:
# https://github.com/llvm/llvm-project/blob/main/llvm/CMakeLists.txt
LLVM_ALL_TARGETS = %w(
AArch64
AMDGPU
ARM
AVR
BPF
Hexagon
Lanai
LoongArch
Mips
MSP430
NVPTX
PowerPC
RISCV
Sparc
SystemZ
VE
WebAssembly
X86
XCore
ARC
CSKY
DirectX
M68k
SPIRV
Xtensa
)

def find_dll_in_env_path
ENV["PATH"]?.try &.split(Process::PATH_DELIMITER, remove_empty: true) do |path|
dll_path = File.join(path, "LLVM-C.dll")
return dll_path if File.exists?(File.join(path, "LLVM-C.dll"))
end
end

unless dll_fname = ARGV.shift? || find_dll_in_env_path
abort "Error: Cannot locate LLVM-C.dll, pass its absolute path as a command-line argument or ensure it is available in the PATH environment variable"
end

unless dll = LibC.LoadLibraryExW(dll_fname.check_no_null_byte.to_utf16, nil, 0)
abort "Error: Failed to load DLL at #{dll_fname}"
end

begin
unless llvm_get_version = LibC.GetProcAddress(dll, "LLVMGetVersion")
abort "Error: Failed to resolve LLVMGetVersion"
end

llvm_get_version = Proc(LibC::UInt*, LibC::UInt*, LibC::UInt*, Nil).new(llvm_get_version, Pointer(Void).null)
major = uninitialized LibC::UInt
minor = uninitialized LibC::UInt
patch = uninitialized LibC::UInt
llvm_get_version.call(pointerof(major), pointerof(minor), pointerof(patch))

targets_built = LLVM_ALL_TARGETS.select do |target|
LibC.GetProcAddress(dll, "LLVMInitialize#{target}Target") && LibC.GetProcAddress(dll, "LLVMInitialize#{target}TargetInfo")
end

# The list of required system libraries are hardcoded in:
# https://github.com/llvm/llvm-project/blob/main/llvm/lib/Support/CMakeLists.txt
# There is no way to infer them from `dumpbin /dependents` alone, because that
# command lists DLLs only, whereas some of these libraries are purely static.
system_libs = %w(psapi shell32 ole32 uuid advapi32)
# https://github.com/llvm/llvm-project/commit/a5ffabce98a4b2e9d69009fa3e60f2b154100860
system_libs << "ws2_32" if {major, minor, patch} >= {18, 0, 0}

puts "#{major}.#{minor}.#{patch}"
puts targets_built.join(' ')
puts system_libs.join(' ', &.+ ".lib")
ensure
LibC.FreeLibrary(dll)
end
101 changes: 101 additions & 0 deletions spec/compiler/codegen/sizeof_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,105 @@ describe "Code gen: sizeof" do
z)).to_i.should eq(16)
end

describe "alignof" do
it "gets alignof primitive types" do
run("alignof(Int32)").to_i.should eq(4)
run("alignof(Void)").to_i.should eq(1)
run("alignof(NoReturn)").to_i.should eq(1)
run("alignof(Nil)").to_i.should eq(1)
run("alignof(Bool)").to_i.should eq(1)
end

it "gets alignof struct" do
run(<<-CRYSTAL).to_i.should eq(4)
struct Foo
def initialize(@x : Int8, @y : Int32, @z : Int16)
end
end
Foo.new(1, 2, 3)
alignof(Foo)
CRYSTAL
end

it "gets alignof class" do
# pointer size and alignment should be identical
run(<<-CRYSTAL).to_i.should eq(sizeof(Void*))
class Foo
def initialize(@x : Int8, @y : Int32, @z : Int16)
end
end
Foo.new(1, 2, 3)
alignof(Foo)
CRYSTAL
end
end

describe "instance_alignof" do
it "gets instance_alignof class" do
run(<<-CRYSTAL).to_i.should eq(4)
class Foo
def initialize(@x : Int8, @y : Int32, @z : Int16)
end
end
Foo.new(1, 2, 3)
instance_alignof(Foo)
CRYSTAL

run(<<-CRYSTAL).to_i.should eq(8)
class Foo
def initialize(@x : Int8, @y : Int64, @z : Int16)
end
end
Foo.new(1, 2, 3)
instance_alignof(Foo)
CRYSTAL

run(<<-CRYSTAL).to_i.should eq(4)
class Foo
end
Foo.new
instance_alignof(Foo)
CRYSTAL
end

it "gets instance_alignof a generic type with type vars" do
run(<<-CRYSTAL).to_i.should eq(4)
class Foo(T)
def initialize(@x : T)
end
end
instance_alignof(Foo(Int32))
CRYSTAL

run(<<-CRYSTAL).to_i.should eq(8)
class Foo(T)
def initialize(@x : T)
end
end
instance_alignof(Foo(Int64))
CRYSTAL

run(<<-CRYSTAL).to_i.should eq(4)
class Foo(T)
def initialize(@x : T)
end
end
instance_alignof(Foo(Int8))
CRYSTAL
end
end
end
Loading

0 comments on commit 75cf47c

Please sign in to comment.