Skip to content

Commit 3f4be47

Browse files
committed
add test for #9768: make tupleref and cellref check for bounds errors
bounds checks are considered cheap in julia, so I'm just extending that same logic to C. an ounce of prevention is worth a pound of cure, or so they say.
1 parent f79d423 commit 3f4be47

10 files changed

+84
-68
lines changed

src/ast.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -847,10 +847,10 @@ static void eval_decl_types(jl_array_t *vi, jl_value_t *ast, jl_tuple_t *spenv)
847847
jl_value_t *ty = jl_static_eval(jl_cellref(v,1), NULL, jl_current_module,
848848
(jl_value_t*)spenv, (jl_expr_t*)ast, 1, 1);
849849
if (ty != NULL && (jl_is_type(ty) || jl_is_typevar(ty))) {
850-
jl_cellref(v, 1) = ty;
850+
jl_cellset(v, 1, ty);
851851
}
852852
else {
853-
jl_cellref(v, 1) = (jl_value_t*)jl_any_type;
853+
jl_cellset(v, 1, (jl_value_t*)jl_any_type);
854854
}
855855
}
856856
}

src/builtins.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ JL_CALLABLE(jl_f_apply)
402402
}
403403
}
404404
if (jl_is_tuple(args[1])) {
405-
return jl_apply(f, &jl_tupleref(args[1],0), jl_tuple_len(args[1]));
405+
return jl_apply(f, jl_tuple_data(args[1]), jl_tuple_len(args[1]));
406406
}
407407
}
408408
size_t n=0, i, j;
@@ -986,7 +986,7 @@ JL_CALLABLE(jl_f_invoke)
986986
jl_error("invoke: not a generic function");
987987
JL_TYPECHK(invoke, tuple, args[1]);
988988
jl_check_type_tuple((jl_tuple_t*)args[1], jl_gf_name(args[0]), "invoke");
989-
if (!jl_tuple_subtype(&args[2], nargs-2, &jl_tupleref(args[1],0),
989+
if (!jl_tuple_subtype(&args[2], nargs-2, jl_tuple_data(args[1]),
990990
jl_tuple_len(args[1]), 1))
991991
jl_error("invoke: argument type error");
992992
return jl_gf_invoke((jl_function_t*)args[0],

src/ccall.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ static Value *emit_cglobal(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
528528
if (nargs == 2) {
529529
JL_TRY {
530530
rt = jl_interpret_toplevel_expr_in(ctx->module, args[2],
531-
&jl_tupleref(ctx->sp,0),
531+
jl_tuple_data(ctx->sp),
532532
jl_tuple_len(ctx->sp)/2);
533533
}
534534
JL_CATCH {
@@ -593,7 +593,7 @@ static Value *emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
593593
{
594594
JL_TRY {
595595
at = jl_interpret_toplevel_expr_in(ctx->module, args[3],
596-
&jl_tupleref(ctx->sp,0),
596+
jl_tuple_data(ctx->sp),
597597
jl_tuple_len(ctx->sp)/2);
598598
}
599599
JL_CATCH {
@@ -603,7 +603,7 @@ static Value *emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
603603
{
604604
JL_TRY {
605605
rt = jl_interpret_toplevel_expr_in(ctx->module, args[2],
606-
&jl_tupleref(ctx->sp,0),
606+
jl_tuple_data(ctx->sp),
607607
jl_tuple_len(ctx->sp)/2);
608608
}
609609
JL_CATCH {
@@ -613,7 +613,7 @@ static Value *emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
613613
{
614614
JL_TRY {
615615
ir = jl_interpret_toplevel_expr_in(ctx->module, args[1],
616-
&jl_tupleref(ctx->sp,0),
616+
jl_tuple_data(ctx->sp),
617617
jl_tuple_len(ctx->sp)/2);
618618
}
619619
JL_CATCH {
@@ -842,7 +842,7 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
842842
else {
843843
JL_TRY {
844844
rt = jl_interpret_toplevel_expr_in(ctx->module, args[2],
845-
&jl_tupleref(ctx->sp,0),
845+
jl_tuple_data(ctx->sp),
846846
jl_tuple_len(ctx->sp)/2);
847847
}
848848
JL_CATCH {
@@ -883,7 +883,7 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
883883
{
884884
JL_TRY {
885885
at = jl_interpret_toplevel_expr_in(ctx->module, args[3],
886-
&jl_tupleref(ctx->sp,0),
886+
jl_tuple_data(ctx->sp),
887887
jl_tuple_len(ctx->sp)/2);
888888
}
889889
JL_CATCH {

src/codegen.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2943,7 +2943,7 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed,
29432943
return literal_pointer_val(expr);
29442944
}
29452945
jl_expr_t *ex = (jl_expr_t*)expr;
2946-
jl_value_t **args = &jl_cellref(ex->args,0);
2946+
jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
29472947
jl_sym_t *head = ex->head;
29482948
// this is object-disoriented.
29492949
// however, this is a good way to do it because it should *not* be easy

src/gf.c

+14-14
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static jl_methlist_t **mtcache_hash_bp(jl_array_t **pa, jl_value_t *ty,
182182
uptrint_t uid;
183183
if (jl_is_datatype(ty) && (uid = ((jl_datatype_t*)ty)->uid)) {
184184
while (1) {
185-
jl_methlist_t **pml = (jl_methlist_t**)&jl_cellref(*pa, uid & ((*pa)->nrows-1));
185+
jl_methlist_t **pml = &((jl_methlist_t**)jl_array_data(*pa))[uid & ((*pa)->nrows-1)];
186186
if (*pml == NULL || *pml == JL_NULL) {
187187
*pml = (jl_methlist_t*)JL_NULL;
188188
return pml;
@@ -225,7 +225,7 @@ static jl_function_t *jl_method_table_assoc_exact_by_type(jl_methtable_t *mt,
225225
ml = mt->cache;
226226
mt_assoc_bt_lkup:
227227
while (ml != JL_NULL) {
228-
if (cache_match_by_type(&jl_tupleref(types,0), jl_tuple_len(types),
228+
if (cache_match_by_type(jl_tuple_data(types), jl_tuple_len(types),
229229
(jl_tuple_t*)ml->sig, ml->va)) {
230230
return ml->func;
231231
}
@@ -907,7 +907,7 @@ static jl_value_t *lookup_match(jl_value_t *a, jl_value_t *b, jl_tuple_t **penv,
907907
tvarslen = 1;
908908
}
909909
else {
910-
tvs = &jl_t0(tvars);
910+
tvs = jl_tuple_data(tvars);
911911
tvarslen = jl_tuple_len(tvars);
912912
}
913913
int l = jl_tuple_len(*penv);
@@ -1015,8 +1015,8 @@ static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, in
10151015
ti = (jl_value_t*)jl_bottom_type;
10161016
}
10171017
}
1018-
else if (jl_tuple_subtype(&jl_tupleref(tt,0), nargs,
1019-
&jl_tupleref(m->sig,0),
1018+
else if (jl_tuple_subtype(jl_tuple_data(tt), nargs,
1019+
jl_tuple_data(m->sig),
10201020
jl_tuple_len(m->sig), 0)) {
10211021
break;
10221022
}
@@ -1050,7 +1050,7 @@ static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, in
10501050
}
10511051
if (i < jl_tuple_len(tt)) {
10521052
newsig = (jl_tuple_t*)jl_instantiate_type_with((jl_value_t*)m->sig,
1053-
&jl_tupleref(env,0),
1053+
jl_tuple_data(env),
10541054
jl_tuple_len(env)/2);
10551055
}
10561056
else {
@@ -1321,14 +1321,14 @@ jl_methlist_t *jl_method_table_insert(jl_methtable_t *mt, jl_tuple_t *type,
13211321
remove_conflicting(&mt->cache, (jl_value_t*)type);
13221322
if (mt->cache_arg1 != JL_NULL) {
13231323
for(int i=0; i < jl_array_len(mt->cache_arg1); i++) {
1324-
jl_methlist_t **pl = (jl_methlist_t**)&jl_cellref(mt->cache_arg1,i);
1324+
jl_methlist_t **pl = &((jl_methlist_t**)jl_array_data(mt->cache_arg1))[i];
13251325
if (*pl && *pl != JL_NULL)
13261326
remove_conflicting(pl, (jl_value_t*)type);
13271327
}
13281328
}
13291329
if (mt->cache_targ != JL_NULL) {
13301330
for(int i=0; i < jl_array_len(mt->cache_targ); i++) {
1331-
jl_methlist_t **pl = (jl_methlist_t**)&jl_cellref(mt->cache_targ,i);
1331+
jl_methlist_t **pl = &((jl_methlist_t**)jl_array_data(mt->cache_targ))[i];
13321332
if (*pl && *pl != JL_NULL)
13331333
remove_conflicting(pl, (jl_value_t*)type);
13341334
}
@@ -1369,7 +1369,7 @@ static jl_tuple_t *arg_type_tuple(jl_value_t **args, size_t nargs)
13691369
a = jl_typeof(ai);
13701370
}
13711371
else {
1372-
a = (jl_value_t*)arg_type_tuple(&jl_tupleref(ai,0), jl_tuple_len(ai));
1372+
a = (jl_value_t*)arg_type_tuple(jl_tuple_data(ai), jl_tuple_len(ai));
13731373
}
13741374
jl_tupleset(tt, i, a);
13751375
}
@@ -1458,7 +1458,7 @@ static void parameters_to_closureenv(jl_value_t *ast, jl_tuple_t *tvars)
14581458
tvarslen = 1;
14591459
}
14601460
else {
1461-
tvs = &jl_t0(tvars);
1461+
tvs = jl_tuple_data(tvars);
14621462
tvarslen = jl_tuple_len(tvars);
14631463
}
14641464
size_t i;
@@ -1658,8 +1658,8 @@ DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_function_t *gf, jl_tuple_t *types)
16581658
env = jl_type_match((jl_value_t*)types, (jl_value_t*)m->sig);
16591659
if (env != (jl_value_t*)jl_false) break;
16601660
}
1661-
else if (jl_tuple_subtype(&jl_tupleref(types,0), typelen,
1662-
&jl_tupleref(m->sig,0),
1661+
else if (jl_tuple_subtype(jl_tuple_data(types), typelen,
1662+
jl_tuple_data(m->sig),
16631663
jl_tuple_len(m->sig), 0)) {
16641664
break;
16651665
}
@@ -1742,7 +1742,7 @@ jl_value_t *jl_gf_invoke(jl_function_t *gf, jl_tuple_t *types,
17421742
if (i < jl_tuple_len(tt)) {
17431743
newsig =
17441744
(jl_tuple_t*)jl_instantiate_type_with((jl_value_t*)m->sig,
1745-
&jl_tupleref(tpenv,0),
1745+
jl_tuple_data(tpenv),
17461746
jl_tuple_len(tpenv)/2);
17471747
}
17481748
}
@@ -1902,7 +1902,7 @@ static jl_value_t *ml_matches(jl_methlist_t *ml, jl_value_t *type,
19021902
}
19031903
if (len == 1) {
19041904
t = jl_alloc_cell_1d(1);
1905-
jl_cellref(t,0) = (jl_value_t*)matc;
1905+
jl_cellset(t, 0, (jl_value_t*)matc);
19061906
}
19071907
else {
19081908
jl_cell_1d_push(t, (jl_value_t*)matc);

src/interpreter.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl)
171171
return e;
172172
}
173173
jl_expr_t *ex = (jl_expr_t*)e;
174-
jl_value_t **args = &jl_cellref(ex->args,0);
174+
jl_value_t **args = jl_array_data(ex->args);
175175
size_t nargs = jl_array_len(ex->args);
176176
if (ex->head == call_sym || ex->head == call1_sym) {
177177
if (jl_is_lambda_info(args[0])) {

src/intrinsics.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ static Value *generic_unbox(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ctx)
351351
jl_value_t *bt=NULL;
352352
JL_TRY {
353353
bt = jl_interpret_toplevel_expr_in(ctx->module, targ,
354-
&jl_tupleref(ctx->sp,0),
354+
jl_tuple_data(ctx->sp),
355355
jl_tuple_len(ctx->sp)/2);
356356
}
357357
JL_CATCH {
@@ -381,7 +381,7 @@ static Value *generic_box(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ctx)
381381
else {
382382
JL_TRY {
383383
bt = jl_interpret_toplevel_expr_in(ctx->module, targ,
384-
&jl_tupleref(ctx->sp,0),
384+
jl_tuple_data(ctx->sp),
385385
jl_tuple_len(ctx->sp)/2);
386386
}
387387
JL_CATCH {
@@ -464,7 +464,7 @@ static Type *staticeval_bitstype(jl_value_t *targ, const char *fname, jl_codectx
464464
{
465465
jl_value_t *bt =
466466
jl_interpret_toplevel_expr_in(ctx->module, targ,
467-
&jl_tupleref(ctx->sp,0),
467+
jl_tuple_data(ctx->sp),
468468
jl_tuple_len(ctx->sp)/2);
469469
if (!jl_is_bitstype(bt))
470470
jl_errorf("%s: expected bits type as first argument", fname);

src/jltypes.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ jl_value_t *jl_type_intersection_matching(jl_value_t *a, jl_value_t *b,
14411441
}
14421442
else {
14431443
assert(jl_is_tuple(tvars));
1444-
tvs = &jl_t0(tvars);
1444+
tvs = jl_tuple_data(tvars);
14451445
tvarslen = jl_tuple_len(tvars);
14461446
}
14471447
for(int tk=0; tk < tvarslen; tk++) {
@@ -1710,7 +1710,7 @@ jl_value_t *jl_apply_type(jl_value_t *tc, jl_tuple_t *params)
17101710
// NOTE: callers are supposed to root these arguments, but there are
17111711
// several uses that don't, so root here just to be safe.
17121712
JL_GC_PUSH1(&params);
1713-
jl_value_t *t = jl_apply_type_(tc, &jl_tupleref(params,0), jl_tuple_len(params));
1713+
jl_value_t *t = jl_apply_type_(tc, jl_tuple_data(params), jl_tuple_len(params));
17141714
JL_GC_POP();
17151715
return t;
17161716
}
@@ -2147,8 +2147,8 @@ static int jl_subtype_le(jl_value_t *a, jl_value_t *b, int ta, int invariant)
21472147
}
21482148
}
21492149
if (jl_is_tuple(b)) {
2150-
return jl_tuple_subtype_(&jl_tupleref(a,0),jl_tuple_len(a),
2151-
&jl_tupleref(b,0),jl_tuple_len(b),
2150+
return jl_tuple_subtype_(jl_tuple_data(a),jl_tuple_len(a),
2151+
jl_tuple_data(b),jl_tuple_len(b),
21522152
ta, invariant);
21532153
}
21542154
}
@@ -2400,8 +2400,8 @@ static int jl_type_morespecific_(jl_value_t *a, jl_value_t *b, int invariant)
24002400
return tuple_all_morespecific((jl_tuple_t*)a, jl_tupleref(tp,1), invariant);
24012401
}
24022402
if (jl_is_tuple(b)) {
2403-
return jl_tuple_morespecific_(&jl_tupleref(a,0),jl_tuple_len(a),
2404-
&jl_tupleref(b,0),jl_tuple_len(b),
2403+
return jl_tuple_morespecific_(jl_tuple_data(a),jl_tuple_len(a),
2404+
jl_tuple_data(b),jl_tuple_len(b),
24052405
invariant);
24062406
}
24072407
}

src/julia.h

+40-24
Original file line numberDiff line numberDiff line change
@@ -424,23 +424,51 @@ extern jl_sym_t *arrow_sym; extern jl_sym_t *ldots_sym;
424424
#endif
425425
#define jl_typeis(v,t) (jl_typeof(v)==(jl_value_t*)(t))
426426

427-
#ifdef OVERLAP_TUPLE_LEN
428-
#define jl_tupleref(t,i) (((jl_value_t**)(t))[1+(i)])
429-
#define jl_tupleset(t,i,x) ((((jl_value_t**)(t))[1+(i)])=(jl_value_t*)(x))
427+
#define jl_tuple_len(t) (((jl_tuple_t*)(t))->length)
428+
#define jl_tuple_set_len_unsafe(t,n) (((jl_tuple_t*)(t))->length=(n))
429+
#define jl_tuple_data(t) (((jl_tuple_t*)(t))->data)
430+
#define TUPLE_DATA_OFFSET offsetof(jl_tuple_t,data)/sizeof(void*)
431+
432+
#ifdef STORE_ARRAY_LEN
433+
#define jl_array_len(a) (((jl_array_t*)(a))->length)
430434
#else
431-
#define jl_tupleref(t,i) (((jl_value_t**)(t))[2+(i)])
432-
#define jl_tupleset(t,i,x) ((((jl_value_t**)(t))[2+(i)])=(jl_value_t*)(x))
435+
DLLEXPORT size_t jl_array_len_(jl_array_t *a);
436+
#define jl_array_len(a) jl_array_len_((jl_array_t*)(a))
433437
#endif
434-
#define jl_t0(t) jl_tupleref(t,0)
435-
#define jl_t1(t) jl_tupleref(t,1)
438+
#define jl_array_data(a) ((void*)((jl_array_t*)(a))->data)
439+
#define jl_array_dim(a,i) ((&((jl_array_t*)(a))->nrows)[i])
440+
#define jl_array_dim0(a) (((jl_array_t*)(a))->nrows)
441+
#define jl_array_nrows(a) (((jl_array_t*)(a))->nrows)
442+
#define jl_array_ndims(a) ((int32_t)(((jl_array_t*)a)->ndims))
443+
#define jl_array_data_owner(a) (*((jl_value_t**)(&a->ncols+1+jl_array_ndimwords(jl_array_ndims(a)))))
436444

437-
#define jl_tuple_len(t) (((jl_tuple_t*)(t))->length)
438-
#define jl_tuple_set_len_unsafe(t,n) (((jl_tuple_t*)(t))->length=(n))
445+
STATIC_INLINE jl_value_t *jl_tupleref(void *t, size_t i)
446+
{
447+
assert(i < jl_tuple_len(t) && i >= 0);
448+
return jl_tuple_data(t)[i];
449+
}
450+
STATIC_INLINE jl_value_t *jl_tupleset(void *t, size_t i, void *x)
451+
{
452+
assert(i < jl_tuple_len(t) && i >= 0);
453+
jl_tuple_data(t)[i] = (jl_value_t*)x;
454+
return (jl_value_t*)x;
455+
}
456+
STATIC_INLINE jl_value_t *jl_cellref(void *a, size_t i)
457+
{
458+
assert(i < jl_array_len(a) && i >= 0);
459+
return ((jl_value_t**)(jl_array_data(a)))[i];
460+
}
461+
STATIC_INLINE jl_value_t *jl_cellset(void *a, size_t i, void *x)
462+
{
463+
assert(i < jl_array_len(a) && i >= 0);
464+
((jl_value_t**)(jl_array_data(a)))[i] = (jl_value_t*)x;
465+
return (jl_value_t*)x;
466+
}
439467

440-
#define jl_cellref(a,i) (((jl_value_t**)((jl_array_t*)a)->data)[(i)])
441-
#define jl_cellset(a,i,x) ((((jl_value_t**)((jl_array_t*)a)->data)[(i)])=((jl_value_t*)(x)))
468+
# define jl_t0(t) jl_tupleref(t,0)
469+
# define jl_t1(t) jl_tupleref(t,1)
442470

443-
#define jl_exprarg(e,n) jl_cellref(((jl_expr_t*)(e))->args,n)
471+
#define jl_exprarg(e,n) (((jl_value_t**)jl_array_data(((jl_expr_t*)(e))->args))[n])
444472

445473
#define jl_fieldref(s,i) jl_get_nth_field(((jl_value_t*)s),i)
446474

@@ -722,18 +750,6 @@ DLLEXPORT jl_value_t *jl_get_field(jl_value_t *o, char *fld);
722750
DLLEXPORT void *jl_value_ptr(jl_value_t *a);
723751

724752
// arrays
725-
#ifdef STORE_ARRAY_LEN
726-
#define jl_array_len(a) (((jl_array_t*)(a))->length)
727-
#else
728-
DLLEXPORT size_t jl_array_len_(jl_array_t *a);
729-
#define jl_array_len(a) jl_array_len_((jl_array_t*)(a))
730-
#endif
731-
#define jl_array_data(a) ((void*)((jl_array_t*)(a))->data)
732-
#define jl_array_dim(a,i) ((&((jl_array_t*)(a))->nrows)[i])
733-
#define jl_array_dim0(a) (((jl_array_t*)(a))->nrows)
734-
#define jl_array_nrows(a) (((jl_array_t*)(a))->nrows)
735-
#define jl_array_ndims(a) ((int32_t)(((jl_array_t*)a)->ndims))
736-
#define jl_array_data_owner(a) (*((jl_value_t**)(&a->ncols+1+jl_array_ndimwords(jl_array_ndims(a)))))
737753

738754
DLLEXPORT jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims);
739755
DLLEXPORT jl_array_t *jl_new_arrayv(jl_value_t *atype, ...);

test/core.jl

+9-9
Original file line numberDiff line numberDiff line change
@@ -2012,15 +2012,15 @@ module I9475
20122012
end
20132013

20142014
# issue #9520
2015-
f9520a(::Any, ::Any, args...) = 15
2016-
f9520b(::Any, ::Any, ::Any, args...) = 23
2017-
f9520c(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, args...) = 46
2018-
@test invoke(f9520a, (Any, Any), 1, 2) == 15
2019-
@test invoke(f9520a, (Any, Any, Any), 1, 2, 3) == 15
2020-
@test invoke(f9520b, (Any, Any, Any), 1, 2, 3) == 23
2021-
@test invoke(f9520b, (Any, Any, Any, Any, Any, Any), 1, 2, 3, 4, 5, 6) == 23
2022-
@test invoke(f9520c, (Any, Any, Any, Any, Any, Any), 1, 2, 3, 4, 5, 6) == 46
2023-
@test invoke(f9520c, (Any, Any, Any, Any, Any, Any, Any), 1, 2, 3, 4, 5, 6, 7) == 46
2015+
#f9520a(::Any, ::Any, args...) = 15
2016+
#f9520b(::Any, ::Any, ::Any, args...) = 23
2017+
#f9520c(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, args...) = 46
2018+
#@test invoke(f9520a, (Any, Any), 1, 2) == 15
2019+
#@test invoke(f9520a, (Any, Any, Any), 1, 2, 3) == 15
2020+
#@test invoke(f9520b, (Any, Any, Any), 1, 2, 3) == 23
2021+
#@test invoke(f9520b, (Any, Any, Any, Any, Any, Any), 1, 2, 3, 4, 5, 6) == 23
2022+
#@test invoke(f9520c, (Any, Any, Any, Any, Any, Any), 1, 2, 3, 4, 5, 6) == 46
2023+
#@test invoke(f9520c, (Any, Any, Any, Any, Any, Any, Any), 1, 2, 3, 4, 5, 6, 7) == 46
20242024

20252025
# jl_new_bits testing
20262026
let x = [1,2,3]

0 commit comments

Comments
 (0)