Skip to content

Commit ac7d7f3

Browse files
authored
v3: fix systemic parser/checker/transform/markused/gen issues; +75 passing tests (#27925)
1 parent 85859f0 commit ac7d7f3

39 files changed

Lines changed: 7618 additions & 704 deletions

vlib/builtin/closure/closure.c.v

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ type ClosureGetDataFn = fn () voidptr
1111

1212
type ClosureInitFn = fn ()
1313

14+
type ClosureDataDropFn = fn (voidptr)
15+
1416
struct ClosurePage {
1517
mut:
1618
next &ClosurePage = unsafe { nil }
@@ -21,6 +23,7 @@ struct ClosureLiveInfo {
2123
mut:
2224
ctx voidptr
2325
owns_data bool
26+
drop_data voidptr
2427
generation u64
2528
}
2629

@@ -354,11 +357,12 @@ fn closure_is_managed(exec_ptr voidptr) bool {
354357
return false
355358
}
356359

357-
fn closure_live_set(exec_ptr voidptr, data voidptr, owns_data bool) {
360+
fn closure_live_set(exec_ptr voidptr, data voidptr, owns_data bool, drop_data voidptr) {
358361
g_closure.next_generation++
359362
g_closure.live[exec_ptr] = ClosureLiveInfo{
360363
ctx: data
361364
owns_data: owns_data
365+
drop_data: drop_data
362366
generation: g_closure.next_generation
363367
}
364368
}
@@ -482,6 +486,14 @@ fn closure_release_no_lock(exec_ptr voidptr, generation u64) bool {
482486
data := closure_slot_data(exec_ptr)
483487
_ := closure_live_delete(exec_ptr)
484488
if info.owns_data && !isnil(data) {
489+
if !isnil(info.drop_data) {
490+
drop_fn := ClosureDataDropFn(info.drop_data)
491+
// A user-defined drop can allocate another closure. Run it outside the
492+
// runtime mutex after removing this slot from the live map.
493+
closure_mtx_unlock_platform()
494+
drop_fn(data)
495+
closure_mtx_lock_platform()
496+
}
485497
unsafe { free(data) }
486498
}
487499
unsafe {
@@ -796,6 +808,12 @@ fn closure_create(func voidptr, data voidptr) voidptr {
796808
// closure_create_with_data creates closure objects with explicit context ownership(INTERNAL COMPILER USE ONLY).
797809
@[direct_array_access]
798810
fn closure_create_with_data(func voidptr, data voidptr, owns_data bool) voidptr {
811+
return closure_create_with_data_and_drop(func, data, owns_data, unsafe { nil })
812+
}
813+
814+
// closure_create_with_data_and_drop creates an owned closure context with type-aware cleanup(INTERNAL COMPILER USE ONLY).
815+
@[direct_array_access]
816+
fn closure_create_with_data_and_drop(func voidptr, data voidptr, owns_data bool, drop_data voidptr) voidptr {
799817
closure_ensure_initialized()
800818
closure_mtx_lock_platform()
801819

@@ -837,7 +855,7 @@ fn closure_create_with_data(func voidptr, data voidptr, owns_data bool) voidptr
837855
p[1] = func // Target function to execute
838856
}
839857
}
840-
closure_live_set(curr_closure, data, owns_data)
858+
closure_live_set(curr_closure, data, owns_data, drop_data)
841859
closure_lifetime_track_no_lock(curr_closure)
842860
closure_mtx_unlock_platform()
843861

vlib/v3/eval/eval.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,9 @@ fn (mut e Eval) eval_expr(id flat.NodeId) !Value {
24822482
name: e.runtime_type_name(value)
24832483
}
24842484
}
2485+
.defer_result {
2486+
return error('`$res()` is not supported by the V3 eval backend')
2487+
}
24852488
.fn_literal {
24862489
return Value(e.eval_fn_literal(id, node)!)
24872490
}

vlib/v3/flat/flat.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ pub type NodeId = int
1010
pub type TextId = u32
1111

1212
pub const empty_node = NodeId(-1)
13+
pub const method_value_borrow_receiver_marker = '__v3_method_value_borrow_receiver'
14+
pub const method_value_clone_receiver_marker_prefix = '__v3_method_value_clone_receiver:'
1315

1416
const empty_node_value = Node{}
1517

@@ -102,6 +104,9 @@ pub enum NodeKind as u8 {
102104
// by parse_comptime_expr and fully expanded (into builder statements) by
103105
// parse_block_body at parse time, so it never reaches later phases.
104106
veb_template
107+
// A `$res()` / `$res(index)` expression. This must remain distinct from
108+
// `.ident` so user-spellable names cannot be reinterpreted as defer results.
109+
defer_result
105110
}
106111

107112
// Op lists op values used by flat.

0 commit comments

Comments
 (0)