Skip to content

Commit a773c8b

Browse files
authored
release-1.9: Backports for 1.9.3 (#50507)
Backported PRs: - [x] #47782 <!-- Generalize Bool parse method to AbstractString --> - [x] #48634 <!-- Remove unused "deps" mechanism in internal sorting keywords [NFC] --> - [x] #49931 <!-- Lock finalizers' lists at exit --> - [x] #50064 <!-- Fix numbered prompt with input only with comment --> - [x] #50474 <!-- docs: Fix a `!!! note` which was miscapitalized --> - [x] #50516 <!-- Fix visibility of assert on GCC12/13 --> - [x] #50635 <!-- `versioninfo()`: include build info and unofficial warning --> - [x] #49915 <!-- Revert "Remove number / vector (#44358)" --> - [x] #50781 <!-- fix `bit_map!` with aliasing --> - [x] #50845 <!-- fix #50438, use default pool for at-threads --> - [x] #49031 <!-- Update inference.md --> - [x] #50289 <!-- Initialize prev_nold and nold in gc_reset_page --> - [x] #50559 <!-- Expand kwcall lowering positional default check to vararg --> - [x] #49582 <!-- Update HISTORY.md for `DelimitedFiles` --> - [x] #50341 <!-- invokelatest docs should say not exported before 1.9 --> - [x] #50525 <!-- only check that values are finite in `generic_lufact` when `check=true` --> - [x] #50444 <!-- Optimize getfield lowering to avoid boxing in some cases --> - [x] #50523 <!-- Avoid generic call in most cases for getproperty --> - [x] #50860 <!-- Add `Base.get_extension` to docs/API --> - [x] #50164 <!-- codegen: handle dead code with unsafe_store of FCA pointers --> - [x] #50568 <!-- `Array(::AbstractRange)` should return an `Array` --> - [x] #50871 <!-- macOS: Don't inspect dead threadtls during exception handling. --> Need manual backport: - [ ] #48542 <!-- Add docs on task-specific buffering using multithreading --> - [ ] #50591 <!-- build: fix various makefile bugs --> Non-merged PRs with backport label: - [ ] #50842 <!-- Avoid race conditions with recursive rm --> - [ ] #50823 <!-- Make ranges more robust with unsigned indexes. --> - [ ] #50663 <!-- Fix Expr(:loopinfo) codegen --> - [ ] #49716 <!-- Update varinfo() docstring signature --> - [ ] #49713 <!-- prevent REPL from erroring in numbered mode in some situations --> - [ ] #49573 <!-- Implement jl_cpu_pause on PPC64 --> - [ ] #48726 <!-- fix macro expansion of property destructuring --> - [ ] #48642 <!-- Use gc alloc instead of alloc typed in lowering --> - [ ] #48183 <!-- Don't use pkgimage for package if any includes fall in tracked path for coverage or alloc tracking --> - [ ] #48050 <!-- improve `--heap-size-hint` arg handling --> - [ ] #47615 <!-- Allow threadsafe access to buffer of type inference profiling trees -->
2 parents 6fc1be0 + c25c2bc commit a773c8b

33 files changed

+243
-33
lines changed

NEWS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Standard library changes
181181

182182
#### DelimitedFiles
183183

184-
* DelimitedFiles has been moved out as a separate package. It now has to be explicitly installed to be used.
184+
* DelimitedFiles has been moved out as a separate package.
185185

186186
Deprecated or removed
187187
---------------------

base/abstractarray.jl

+2
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,8 @@ false
766766
checkindex(::Type{Bool}, inds::AbstractUnitRange, i) =
767767
throw(ArgumentError("unable to check bounds for indices of type $(typeof(i))"))
768768
checkindex(::Type{Bool}, inds::AbstractUnitRange, i::Real) = (first(inds) <= i) & (i <= last(inds))
769+
checkindex(::Type{Bool}, inds::IdentityUnitRange, i::Real) = checkindex(Bool, inds.indices, i)
770+
checkindex(::Type{Bool}, inds::OneTo{T}, i::T) where {T<:BitInteger} = unsigned(i - one(i)) < unsigned(last(inds))
769771
checkindex(::Type{Bool}, inds::AbstractUnitRange, ::Colon) = true
770772
checkindex(::Type{Bool}, inds::AbstractUnitRange, ::Slice) = true
771773
function checkindex(::Type{Bool}, inds::AbstractUnitRange, r::AbstractRange)

base/bitarray.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -1791,9 +1791,10 @@ function bit_map!(f::F, dest::BitArray, A::BitArray) where F
17911791
dest_last = destc[len_Ac]
17921792
_msk = _msk_end(A)
17931793
# first zero out the bits mask is going to change
1794-
destc[len_Ac] = (dest_last & (~_msk))
17951794
# then update bits by `or`ing with a masked RHS
1796-
destc[len_Ac] |= f(Ac[len_Ac]) & _msk
1795+
# DO NOT SEPARATE ONTO TO LINES.
1796+
# Otherwise there will be bugs when Ac aliases destc
1797+
destc[len_Ac] = (dest_last & (~_msk)) | f(Ac[len_Ac]) & _msk
17971798
dest
17981799
end
17991800
function bit_map!(f::F, dest::BitArray, A::BitArray, B::BitArray) where F
@@ -1812,9 +1813,10 @@ function bit_map!(f::F, dest::BitArray, A::BitArray, B::BitArray) where F
18121813
dest_last = destc[len_Ac]
18131814
_msk = _msk_end(min_bitlen)
18141815
# first zero out the bits mask is going to change
1815-
destc[len_Ac] = (dest_last & ~(_msk))
18161816
# then update bits by `or`ing with a masked RHS
1817-
destc[len_Ac] |= f(Ac[end], Bc[end]) & _msk
1817+
# DO NOT SEPARATE ONTO TO LINES.
1818+
# Otherwise there will be bugs when Ac or Bc aliases destc
1819+
destc[len_Ac] = (dest_last & ~(_msk)) | f(Ac[end], Bc[end]) & _msk
18181820
dest
18191821
end
18201822

base/essentials.jl

+3
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,9 @@ e.g. long-running event loops or callback functions that may
809809
call obsolete versions of a function `f`.
810810
(The drawback is that `invokelatest` is somewhat slower than calling
811811
`f` directly, and the type of the result cannot be inferred by the compiler.)
812+
813+
!!! compat "Julia 1.9"
814+
Prior to Julia 1.9, this function was not exported, and was called as `Base.invokelatest`.
812815
"""
813816
function invokelatest(@nospecialize(f), @nospecialize args...; kwargs...)
814817
kwargs = merge(NamedTuple(), kwargs)

base/parse.jl

+10-5
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::
176176
return n
177177
end
178178

179-
function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}},
179+
function tryparse_internal(::Type{Bool}, sbuff::AbstractString,
180180
startpos::Int, endpos::Int, base::Integer, raise::Bool)
181181
if isempty(sbuff)
182182
raise && throw(ArgumentError("input string is empty"))
@@ -202,10 +202,15 @@ function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}},
202202
end
203203

204204
len = endpos - startpos + 1
205-
p = pointer(sbuff) + startpos - 1
206-
GC.@preserve sbuff begin
207-
(len == 4) && (0 == _memcmp(p, "true", 4)) && (return true)
208-
(len == 5) && (0 == _memcmp(p, "false", 5)) && (return false)
205+
if sbuff isa Union{String, SubString{String}}
206+
p = pointer(sbuff) + startpos - 1
207+
GC.@preserve sbuff begin
208+
(len == 4) && (0 == _memcmp(p, "true", 4)) && (return true)
209+
(len == 5) && (0 == _memcmp(p, "false", 5)) && (return false)
210+
end
211+
else
212+
(len == 4) && (SubString(sbuff, startpos:startpos+3) == "true") && (return true)
213+
(len == 5) && (SubString(sbuff, startpos:startpos+4) == "false") && (return false)
209214
end
210215

211216
if raise

base/range.jl

+15-2
Original file line numberDiff line numberDiff line change
@@ -1363,8 +1363,21 @@ function vcat(rs::AbstractRange{T}...) where T
13631363
return a
13641364
end
13651365

1366-
Array{T,1}(r::AbstractRange{T}) where {T} = vcat(r)
1367-
collect(r::AbstractRange) = vcat(r)
1366+
# This method differs from that for AbstractArrays as it
1367+
# use iteration instead of indexing. This works even if certain
1368+
# non-standard ranges don't support indexing.
1369+
# See https://github.com/JuliaLang/julia/pull/27302
1370+
# Similarly, collect(r::AbstractRange) uses iteration
1371+
function Array{T,1}(r::AbstractRange{T}) where {T}
1372+
a = Vector{T}(undef, length(r))
1373+
i = 1
1374+
for x in r
1375+
@inbounds a[i] = x
1376+
i += 1
1377+
end
1378+
return a
1379+
end
1380+
collect(r::AbstractRange) = Array(r)
13681381

13691382
_reverse(r::OrdinalRange, ::Colon) = (:)(last(r), negate(step(r)), first(r))
13701383
function _reverse(r::StepRangeLen, ::Colon)

base/reflection.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -1913,12 +1913,15 @@ end
19131913
"""
19141914
@invokelatest f(args...; kwargs...)
19151915
1916-
Provides a convenient way to call [`Base.invokelatest`](@ref).
1916+
Provides a convenient way to call [`invokelatest`](@ref).
19171917
`@invokelatest f(args...; kwargs...)` will simply be expanded into
19181918
`Base.invokelatest(f, args...; kwargs...)`.
19191919
19201920
!!! compat "Julia 1.7"
19211921
This macro requires Julia 1.7 or later.
1922+
1923+
!!! compat "Julia 1.9"
1924+
Prior to Julia 1.9, this macro was not exported, and was called as `Base.@invokelatest`.
19221925
"""
19231926
macro invokelatest(ex)
19241927
f, args, kwargs = destructure_callex(ex)

base/threadingconstructs.jl

+7-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,13 @@ function threading_run(fun, static)
138138
for i = 1:n
139139
t = Task(() -> fun(i)) # pass in tid
140140
t.sticky = static
141-
static && ccall(:jl_set_task_tid, Cint, (Any, Cint), t, tid_offset + i-1)
141+
if static
142+
ccall(:jl_set_task_tid, Cint, (Any, Cint), t, tid_offset + i-1)
143+
else
144+
# TODO: this should be the current pool (except interactive) if there
145+
# are ever more than two pools.
146+
ccall(:jl_set_task_threadpoolid, Cint, (Any, Int8), t, _sym_to_tpid(:default))
147+
end
142148
tasks[i] = t
143149
schedule(t)
144150
end

doc/src/base/base.md

+1
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ Base.identify_package
449449
Base.locate_package
450450
Base.require
451451
Base.compilecache
452+
Base.get_extension
452453
```
453454

454455
## Internals

doc/src/devdocs/inference.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
to the process of deducing the types of later values from the types of
77
input values. Julia's approach to inference has been described in blog
88
posts
9-
([1](https://juliacomputing.com/blog/2016/04/inference-convergence/),
10-
[2](https://juliacomputing.com/blog/2017/05/inference-converage2/)).
9+
([1](https://info.juliahub.com/inference-convergence-algorithm-in-julia/),
10+
[2](https://info.juliahub.com/inference-convergence-algorithm-in-julia-revisited/)).
1111

1212
## Debugging compiler.jl
1313

doc/src/manual/multi-threading.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ sum_multi_good (generic function with 1 method)
276276
julia> sum_multi_good(1:1_000_000)
277277
500000500000
278278
```
279-
!!! Note
279+
!!! note
280280
Buffers should not be managed based on `threadid()` i.e. `buffers = zeros(Threads.nthreads())` because concurrent tasks
281281
can yield, meaning multiple concurrent tasks may use the same buffer on a given thread, introducing risk of data races.
282282
Further, when more than one thread is available tasks may change thread at yield points, which is known as

src/codegen.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,13 @@ static const auto jlundefvarerror_func = new JuliaFunction{
693693
{PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
694694
get_attrs_noreturn,
695695
};
696+
static const auto jlhasnofield_func = new JuliaFunction{
697+
XSTR(jl_has_no_field_error),
698+
[](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
699+
{PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted),
700+
PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
701+
get_attrs_noreturn,
702+
};
696703
static const auto jlboundserrorv_func = new JuliaFunction{
697704
XSTR(jl_bounds_error_ints),
698705
[](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
@@ -1048,6 +1055,18 @@ static const auto jlgetnthfieldchecked_func = new JuliaFunction{
10481055
Attributes(C, {Attribute::NonNull}),
10491056
None); },
10501057
};
1058+
static const auto jlfieldindex_func = new JuliaFunction{
1059+
XSTR(jl_field_index),
1060+
[](LLVMContext &C) {
1061+
auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
1062+
return FunctionType::get(getInt32Ty(C),
1063+
{T_prjlvalue, T_prjlvalue, getInt32Ty(C)}, false);
1064+
},
1065+
[](LLVMContext &C) { return AttributeList::get(C,
1066+
Attributes(C, {Attribute::NoUnwind, Attribute::ReadOnly, Attribute::WillReturn}),
1067+
AttributeSet(),
1068+
None); }, // This function can error if the third argument is 1 so don't do that.
1069+
};
10511070
static const auto jlfieldisdefinedchecked_func = new JuliaFunction{
10521071
XSTR(jl_field_isdefined_checked),
10531072
[](LLVMContext &C) {
@@ -3236,6 +3255,8 @@ static jl_llvm_functions_t
32363255
jl_value_t *jlrettype,
32373256
jl_codegen_params_t &params);
32383257

3258+
static void emit_hasnofield_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_sym_t *type, jl_cgval_t name);
3259+
32393260
static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
32403261
const jl_cgval_t *argv, size_t nargs, jl_value_t *rt,
32413262
jl_expr_t *ex, bool is_promotable)
@@ -3706,6 +3727,27 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
37063727
*ret = mark_julia_type(ctx, fld_val, true, jl_any_type);
37073728
return true;
37083729
}
3730+
} else if (fld.typ == (jl_value_t*)jl_symbol_type) { // Known type but unknown symbol
3731+
if (jl_is_datatype(utt) && (utt != jl_module_type) && jl_struct_try_layout(utt)) {
3732+
if ((jl_datatype_nfields(utt) == 1 && !jl_is_namedtuple_type(utt))) {
3733+
jl_svec_t *fn = jl_field_names(utt);
3734+
assert(jl_svec_len(fn) == 1);
3735+
Value *typ_sym = literal_pointer_val(ctx, jl_svecref(fn, 0));
3736+
Value *cond = ctx.builder.CreateICmpEQ(mark_callee_rooted(ctx, typ_sym), mark_callee_rooted(ctx, boxed(ctx, fld)));
3737+
emit_hasnofield_error_ifnot(ctx, cond, utt->name->name, fld);
3738+
*ret = emit_getfield_knownidx(ctx, obj, 0, utt, order);
3739+
return true;
3740+
}
3741+
else {
3742+
Value *index = ctx.builder.CreateCall(prepare_call(jlfieldindex_func),
3743+
{emit_typeof_boxed(ctx, obj, false), boxed(ctx, fld), ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)});
3744+
Value *cond = ctx.builder.CreateICmpNE(index, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), -1));
3745+
emit_hasnofield_error_ifnot(ctx, cond, utt->name->name, fld);
3746+
Value *idx2 = ctx.builder.CreateAdd(ctx.builder.CreateIntCast(index, getSizeTy(ctx.builder.getContext()), false), ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1)); // getfield_unknown is 1 based
3747+
if (emit_getfield_unknownidx(ctx, ret, obj, idx2, utt, jl_false, order))
3748+
return true;
3749+
}
3750+
}
37093751
}
37103752
// TODO: generic getfield func with more efficient calling convention
37113753
return false;
@@ -4426,6 +4468,22 @@ static void undef_var_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_sym_t *name)
44264468
ctx.builder.SetInsertPoint(ifok);
44274469
}
44284470

4471+
static void emit_hasnofield_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_sym_t *type, jl_cgval_t name)
4472+
{
4473+
++EmittedUndefVarErrors;
4474+
assert(name.typ == (jl_value_t*)jl_symbol_type);
4475+
BasicBlock *err = BasicBlock::Create(ctx.builder.getContext(), "err", ctx.f);
4476+
BasicBlock *ifok = BasicBlock::Create(ctx.builder.getContext(), "ok");
4477+
ctx.builder.CreateCondBr(ok, ifok, err);
4478+
ctx.builder.SetInsertPoint(err);
4479+
ctx.builder.CreateCall(prepare_call(jlhasnofield_func),
4480+
{mark_callee_rooted(ctx, literal_pointer_val(ctx, (jl_value_t*)type)),
4481+
mark_callee_rooted(ctx, boxed(ctx, name))});
4482+
ctx.builder.CreateUnreachable();
4483+
ctx.f->getBasicBlockList().push_back(ifok);
4484+
ctx.builder.SetInsertPoint(ifok);
4485+
}
4486+
44294487
// returns a jl_ppvalue_t location for the global variable m.s
44304488
// if the reference currently bound or assign == true,
44314489
// pbnd will also be assigned with the binding address
@@ -8692,6 +8750,7 @@ static void init_jit_functions(void)
86928750
add_named_global(jlatomicerror_func, &jl_atomic_error);
86938751
add_named_global(jlthrow_func, &jl_throw);
86948752
add_named_global(jlundefvarerror_func, &jl_undefined_var_error);
8753+
add_named_global(jlhasnofield_func, &jl_has_no_field_error);
86958754
add_named_global(jlboundserrorv_func, &jl_bounds_error_ints);
86968755
add_named_global(jlboundserror_func, &jl_bounds_error_int);
86978756
add_named_global(jlvboundserror_func, &jl_bounds_error_tuple_int);
@@ -8736,6 +8795,7 @@ static void init_jit_functions(void)
87368795
add_named_global("jl_adopt_thread", &jl_adopt_thread);
87378796
add_named_global(jlgetcfunctiontrampoline_func, &jl_get_cfunction_trampoline);
87388797
add_named_global(jlgetnthfieldchecked_func, &jl_get_nth_field_checked);
8798+
add_named_global(jlfieldindex_func, &jl_field_index);
87398799
add_named_global(diff_gc_total_bytes_func, &jl_gc_diff_total_bytes);
87408800
add_named_global(sync_gc_total_bytes_func, &jl_gc_sync_total_bytes);
87418801
add_named_global(jlarray_data_owner_func, &jl_array_data_owner);

src/datatype.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1511,8 +1511,7 @@ JL_DLLEXPORT int jl_field_index(jl_datatype_t *t, jl_sym_t *fld, int err)
15111511
}
15121512
}
15131513
if (err)
1514-
jl_errorf("type %s has no field %s", jl_symbol_name(t->name->name),
1515-
jl_symbol_name(fld));
1514+
jl_has_no_field_error(t->name->name, fld);
15161515
return -1;
15171516
}
15181517

src/gc.c

+7
Original file line numberDiff line numberDiff line change
@@ -638,12 +638,17 @@ void jl_gc_run_all_finalizers(jl_task_t *ct)
638638
jl_ptls_t* gc_all_tls_states;
639639
gc_n_threads = jl_atomic_load_acquire(&jl_n_threads);
640640
gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states);
641+
// this is called from `jl_atexit_hook`; threads could still be running
642+
// so we have to guard the finalizers' lists
643+
JL_LOCK_NOGC(&finalizers_lock);
641644
schedule_all_finalizers(&finalizer_list_marked);
642645
for (int i = 0; i < gc_n_threads; i++) {
643646
jl_ptls_t ptls2 = gc_all_tls_states[i];
644647
if (ptls2)
645648
schedule_all_finalizers(&ptls2->finalizers);
646649
}
650+
// unlock here because `run_finalizers` locks this
651+
JL_UNLOCK_NOGC(&finalizers_lock);
647652
gc_n_threads = 0;
648653
gc_all_tls_states = NULL;
649654
run_finalizers(ct);
@@ -1410,6 +1415,8 @@ static inline jl_taggedvalue_t *reset_page(jl_ptls_t ptls2, const jl_gc_pool_t *
14101415
pg->has_marked = 0;
14111416
pg->fl_begin_offset = -1;
14121417
pg->fl_end_offset = -1;
1418+
pg->prev_nold = 0;
1419+
pg->nold = 0;
14131420
return beg;
14141421
}
14151422

src/intrinsics.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
678678
ai.decorateInst(load);
679679
return mark_julia_type(ctx, load, true, ety);
680680
}
681-
else if (!jl_isbits(ety)) {
681+
else if (!deserves_stack(ety)) {
682682
assert(jl_is_datatype(ety));
683683
uint64_t size = jl_datatype_size(ety);
684684
Value *strct = emit_allocobj(ctx, size,
@@ -697,7 +697,7 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
697697
assert(!isboxed);
698698
if (!type_is_ghost(ptrty)) {
699699
Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
700-
return typed_load(ctx, thePtr, im1, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, AtomicOrdering::NotAtomic, true, align_nb);
700+
return typed_load(ctx, thePtr, im1, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, AtomicOrdering::NotAtomic, false, align_nb);
701701
}
702702
else {
703703
return ghostValue(ctx, ety);
@@ -751,7 +751,7 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
751751
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_data);
752752
ai.decorateInst(store);
753753
}
754-
else if (!jl_isbits(ety)) {
754+
else if (x.ispointer()) {
755755
thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
756756
uint64_t size = jl_datatype_size(ety);
757757
im1 = ctx.builder.CreateMul(im1, ConstantInt::get(getSizeTy(ctx.builder.getContext()),
@@ -824,7 +824,7 @@ static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
824824
return jl_cgval_t();
825825
}
826826

827-
if (!jl_isbits(ety)) {
827+
if (!deserves_stack(ety)) {
828828
assert(jl_is_datatype(ety));
829829
uint64_t size = jl_datatype_size(ety);
830830
Value *strct = emit_allocobj(ctx, size,
@@ -848,7 +848,7 @@ static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
848848
assert(!isboxed);
849849
if (!type_is_ghost(ptrty)) {
850850
Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
851-
return typed_load(ctx, thePtr, nullptr, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, llvm_order, true, nb);
851+
return typed_load(ctx, thePtr, nullptr, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, llvm_order, false, nb);
852852
}
853853
else {
854854
if (order > jl_memory_order_monotonic)
@@ -924,6 +924,7 @@ static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, const jl
924924
}
925925

926926
if (!jl_isbits(ety)) {
927+
//if (!deserves_stack(ety))
927928
//Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
928929
//uint64_t size = jl_datatype_size(ety);
929930
return emit_runtime_call(ctx, f, argv, nargs); // TODO: optimizations

src/jl_exported_funcs.inc

+1
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@
513513
XX(jl_uncompress_argname_n) \
514514
XX(jl_uncompress_ir) \
515515
XX(jl_undefined_var_error) \
516+
XX(jl_has_no_field_error) \
516517
XX(jl_value_ptr) \
517518
XX(jl_ver_is_release) \
518519
XX(jl_ver_major) \

src/julia-syntax.scm

+1-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@
559559
name positional-sparams
560560
`((|::|
561561
;; if there are optional positional args, we need to be able to reference the function name
562-
,(if (any kwarg? pargl) (gensy) UNUSED)
562+
,(if (any kwarg? `(,@pargl ,@vararg)) (gensy) UNUSED)
563563
(call (core kwftype) ,ftype)) ,kw ,@pargl ,@vararg)
564564
`(block
565565
;; propagate method metadata to keyword sorter

src/julia.h

+1
Original file line numberDiff line numberDiff line change
@@ -1706,6 +1706,7 @@ JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname,
17061706
jl_value_t *ty JL_MAYBE_UNROOTED,
17071707
jl_value_t *got JL_MAYBE_UNROOTED);
17081708
JL_DLLEXPORT void JL_NORETURN jl_undefined_var_error(jl_sym_t *var);
1709+
JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_sym_t *type_name, jl_sym_t *var);
17091710
JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str);
17101711
JL_DLLEXPORT void JL_NORETURN jl_bounds_error(jl_value_t *v JL_MAYBE_UNROOTED,
17111712
jl_value_t *t JL_MAYBE_UNROOTED);

0 commit comments

Comments
 (0)