Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into feature/fast_float
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Nov 25, 2024
2 parents 729fe45 + 558ce7b commit a81c56f
Show file tree
Hide file tree
Showing 85 changed files with 3,139 additions and 36 deletions.
36 changes: 17 additions & 19 deletions .github/workflows/mingw-w64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ jobs:
name: x86_64-mingw-w64-crystal-obj
path: .build/crystal.obj

- name: Upload standard library
uses: actions/upload-artifact@v4
with:
name: x86_64-mingw-w64-crystal-stdlib
path: src

x86_64-mingw-w64-link:
runs-on: windows-2022
needs: [x86_64-mingw-w64-cross-compile]
Expand All @@ -57,6 +51,7 @@ jobs:
msystem: UCRT64
update: true
install: >-
make
mingw-w64-ucrt-x86_64-pkgconf
mingw-w64-ucrt-x86_64-cc
mingw-w64-ucrt-x86_64-gc
Expand All @@ -66,34 +61,37 @@ jobs:
mingw-w64-ucrt-x86_64-llvm
mingw-w64-ucrt-x86_64-libffi
- name: Disable CRLF line ending substitution
run: |
git config --global core.autocrlf false
- name: Download Crystal source
uses: actions/checkout@v4

- name: Download crystal.obj
uses: actions/download-artifact@v4
with:
name: x86_64-mingw-w64-crystal-obj

- name: Download standard library
uses: actions/download-artifact@v4
with:
name: x86_64-mingw-w64-crystal-stdlib
path: share/crystal/src

- name: Link Crystal executable
shell: msys2 {0}
run: |
mkdir bin
cc crystal.obj -o bin/crystal.exe -municode \
mkdir .build
cc crystal.obj -o .build/crystal.exe -municode \
$(pkg-config bdw-gc libpcre2-8 iconv zlib libffi --libs) \
$(llvm-config --libs --system-libs --ldflags) \
-lole32 -lWS2_32 -Wl,--stack,0x800000
ldd bin/crystal.exe | grep -iv /c/windows/system32 | sed 's/.* => //; s/ (.*//' | xargs -t -i cp '{}' bin/
- name: Upload Crystal
- name: Package Crystal
shell: msys2 {0}
run: |
make install install_dlls deref_symlinks=1 PREFIX="$(pwd)/crystal"
- name: Upload Crystal executable
uses: actions/upload-artifact@v4
with:
name: x86_64-mingw-w64-crystal
path: |
bin/
share/
path: crystal

x86_64-mingw-w64-test:
runs-on: windows-2022
Expand Down
4 changes: 2 additions & 2 deletions spec/primitives/external_command_spec.cr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{% skip_file if flag?(:interpreted) %}

require "../spec_helper"
require "../support/tempfile"

describe Crystal::Command do
describe "Crystal::Command" do
it "exec external commands", tags: %w[slow] do
with_temp_executable "crystal-external" do |path|
with_tempfile "crystal-external.cr" do |source_file|
Expand Down
254 changes: 254 additions & 0 deletions spec/std/crystal/evented/arena_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
{% skip_file unless Crystal.has_constant?(:Evented) %}

require "spec"

describe Crystal::Evented::Arena do
describe "#allocate_at?" do
it "yields block when not allocated" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
pointer = nil
index = nil
called = 0

ret = arena.allocate_at?(0) do |ptr, idx|
pointer = ptr
index = idx
called += 1
end
ret.should eq(index)
called.should eq(1)

ret = arena.allocate_at?(0) { called += 1 }
ret.should be_nil
called.should eq(1)

pointer.should_not be_nil
index.should_not be_nil

arena.get(index.not_nil!) do |ptr|
ptr.should eq(pointer)
end
end

it "allocates up to capacity" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
indexes = [] of Crystal::Evented::Arena::Index

indexes = 32.times.map do |i|
arena.allocate_at?(i) { |ptr, _| ptr.value = i }
end.to_a

indexes.size.should eq(32)

indexes.each do |index|
arena.get(index.not_nil!) do |pointer|
pointer.should eq(pointer)
pointer.value.should eq(index.not_nil!.index)
end
end
end

it "checks bounds" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
expect_raises(IndexError) { arena.allocate_at?(-1) { } }
expect_raises(IndexError) { arena.allocate_at?(33) { } }
end
end

describe "#get" do
it "returns previously allocated object" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
pointer = nil

index = arena.allocate_at(30) do |ptr|
pointer = ptr
ptr.value = 654321
end
called = 0

2.times do
arena.get(index.not_nil!) do |ptr|
ptr.should eq(pointer)
ptr.value.should eq(654321)
called += 1
end
end
called.should eq(2)
end

it "can't access unallocated object" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)

expect_raises(RuntimeError) do
arena.get(Crystal::Evented::Arena::Index.new(10, 0)) { }
end
end

it "checks generation" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
called = 0

index1 = arena.allocate_at(2) { called += 1 }
called.should eq(1)

arena.free(index1) { }
expect_raises(RuntimeError) { arena.get(index1) { } }

index2 = arena.allocate_at(2) { called += 1 }
called.should eq(2)
expect_raises(RuntimeError) { arena.get(index1) { } }

arena.get(index2) { }
end

it "checks out of bounds" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
expect_raises(IndexError) { arena.get(Crystal::Evented::Arena::Index.new(-1, 0)) { } }
expect_raises(IndexError) { arena.get(Crystal::Evented::Arena::Index.new(33, 0)) { } }
end
end

describe "#get?" do
it "returns previously allocated object" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
pointer = nil

index = arena.allocate_at(30) do |ptr|
pointer = ptr
ptr.value = 654321
end

called = 0
2.times do
ret = arena.get?(index) do |ptr|
ptr.should eq(pointer)
ptr.not_nil!.value.should eq(654321)
called += 1
end
ret.should be_true
end
called.should eq(2)
end

it "can't access unallocated index" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)

called = 0
ret = arena.get?(Crystal::Evented::Arena::Index.new(10, 0)) { called += 1 }
ret.should be_false
called.should eq(0)
end

it "checks generation" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
called = 0

old_index = arena.allocate_at(2) { }
arena.free(old_index) { }

# not accessible after free:
ret = arena.get?(old_index) { called += 1 }
ret.should be_false
called.should eq(0)

# can be reallocated:
new_index = arena.allocate_at(2) { }

# still not accessible after reallocate:
ret = arena.get?(old_index) { called += 1 }
ret.should be_false
called.should eq(0)

# accessible after reallocate (new index):
ret = arena.get?(new_index) { called += 1 }
ret.should be_true
called.should eq(1)
end

it "checks out of bounds" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
called = 0

arena.get?(Crystal::Evented::Arena::Index.new(-1, 0)) { called += 1 }.should be_false
arena.get?(Crystal::Evented::Arena::Index.new(33, 0)) { called += 1 }.should be_false

called.should eq(0)
end
end

describe "#free" do
it "deallocates the object" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)

index1 = arena.allocate_at(3) { |ptr| ptr.value = 123 }
arena.free(index1) { }

index2 = arena.allocate_at(3) { }
index2.should_not eq(index1)

value = nil
arena.get(index2) { |ptr| value = ptr.value }
value.should eq(0)
end

it "checks generation" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)

called = 0
old_index = arena.allocate_at(1) { }

# can free:
arena.free(old_index) { called += 1 }
called.should eq(1)

# can reallocate:
new_index = arena.allocate_at(1) { }

# can't free with invalid index:
arena.free(old_index) { called += 1 }
called.should eq(1)

# but new index can:
arena.free(new_index) { called += 1 }
called.should eq(2)
end

it "checks out of bounds" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
called = 0

arena.free(Crystal::Evented::Arena::Index.new(-1, 0)) { called += 1 }
arena.free(Crystal::Evented::Arena::Index.new(33, 0)) { called += 1 }

called.should eq(0)
end
end

it "#each_index" do
arena = Crystal::Evented::Arena(Int32, 96).new(32)
indices = [] of {Int32, Crystal::Evented::Arena::Index}

arena.each_index { |i, index| indices << {i, index} }
indices.should be_empty

index5 = arena.allocate_at(5) { }

arena.each_index { |i, index| indices << {i, index} }
indices.should eq([{5, index5}])

index3 = arena.allocate_at(3) { }
index11 = arena.allocate_at(11) { }
index10 = arena.allocate_at(10) { }
index30 = arena.allocate_at(30) { }

indices.clear
arena.each_index { |i, index| indices << {i, index} }
indices.should eq([
{3, index3},
{5, index5},
{10, index10},
{11, index11},
{30, index30},
])
end
end
Loading

0 comments on commit a81c56f

Please sign in to comment.