medvednikov

/

vq Public
0 commits 21 issue 12 pull requests 0 contributors Discussions Projects CI

committed 56 years ago · View patch
3 files changed +132 -87
vlib/v3/gen/c/cleanc.v +19 -15

@@ -71,21 +71,22 @@ mut:

7171 // in_return is true only while generating a `return` statement's value, so a bare

7272 // generic literal (`return Box{...}`) may adopt `cur_fn_ret`'s concrete instance —

7373 // but a literal in a local decl / argument elsewhere in the body does not.

74- in_return bool

75- expected_expr_type types.Type = types.Type(types.void_)

76- expected_enum string

77- needed_optional_types map[string]string

78- emitted_optional_types map[string]bool

79- emitted_fns map[string]bool

80- array_method_cache map[string]string

81- param_types_cache map[string][]types.Type // (name|fallback) -> resolved param types

82- embedded_fields_by_type map[string][]types.StructField // type name -> its embedded fields (usually empty)

83- param_types_by_short map[string][]types.Type // method short-name suffix -> param types (fallback index)

84- spawn_wrapper_names map[string]string

85- spawn_wrapper_defs []string

86- callback_wrapper_names map[string]string

87- callback_wrapper_defs []string

88- parallel_used bool

74+ in_return bool

75+ expected_expr_type types.Type = types.Type(types.void_)

76+ expected_enum string

77+ needed_optional_types map[string]string

78+ emitted_optional_types map[string]bool

79+ emitted_fns map[string]bool

80+ array_method_cache map[string]string

81+ param_types_cache map[string][]types.Type // (name|fallback) -> resolved param types

82+ embedded_fields_by_type map[string][]types.StructField // type name -> its embedded fields (usually empty)

83+ param_types_by_short map[string][]types.Type // method short-name suffix -> param types (fallback index)

84+ generic_method_candidates map[string][]GenericMethodCandidate

85+ spawn_wrapper_names map[string]string

86+ spawn_wrapper_defs []string

87+ callback_wrapper_names map[string]string

88+ callback_wrapper_defs []string

89+ parallel_used bool

8990}

9091

9192struct FixedArrayTypedefInfo {

@@ -166,6 +167,7 @@ pub fn FlatGen.new() FlatGen {

166167 param_types_cache: map[string][]types.Type{}

167168 embedded_fields_by_type: map[string][]types.StructField{}

168169 param_types_by_short: map[string][]types.Type{}

170+ generic_method_candidates: map[string][]GenericMethodCandidate{}

169171 spawn_wrapper_names: map[string]string{}

170172 spawn_wrapper_defs: []string{}

171173 callback_wrapper_names: map[string]string{}

@@ -260,6 +262,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin

260262 g.param_types_cache = map[string][]types.Type{}

261263 g.embedded_fields_by_type = map[string][]types.StructField{}

262264 g.param_types_by_short = map[string][]types.Type{}

265+ g.generic_method_candidates = map[string][]GenericMethodCandidate{}

263266 g.spawn_wrapper_names = map[string]string{}

264267 g.spawn_wrapper_defs = []string{}

265268 g.callback_wrapper_names = map[string]string{}

@@ -277,6 +280,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin

277280 g.preseed_struct_fn_ptr_types()

278281 g.preseed_global_fn_ptr_types()

279282 g.preseed_c_extern_fn_ptr_types()

283+ g.precompute_generic_method_candidate_index()

280284 // Decide fixed-array return wrappers before generating function bodies, so

281285 // signatures, returns and call sites all agree on the wrapped types.

282286 g.populate_fixed_array_ret_wrappers()

vlib/v3/gen/c/fn.v +56 -16

@@ -24,6 +24,12 @@ struct TopLevelStmt {

2424 module string

2525}

2626

27+struct GenericMethodCandidate {

28+ name string

29+ ret types.Type

30+ params []types.Type

31+}

32+

2733// gen_fns emits fns output for c.

2834fn (mut g FlatGen) gen_fns() {

2935 preferred_fns := g.preferred_c_backend_fn_nodes()

@@ -292,6 +298,45 @@ fn (g &FlatGen) emitted_fn_contains(name string) bool {

292298 return name.len > 0 && g.emitted_fns[name]

293299}

294300

301+fn generic_method_candidate_key(receiver string, method string) string {

302+ return '${receiver}\n${method}'

303+}

304+

305+fn (mut g FlatGen) precompute_generic_method_candidate_index() {

306+ g.generic_method_candidates = map[string][]GenericMethodCandidate{}

307+ for name, ret in g.tc.fn_ret_types {

308+ if !name.contains('[') || !name.contains('.') {

309+ continue

310+ }

311+ method := name.all_after_last('.')

312+ receiver := name.all_before_last('.')

313+ if method.len == 0 || !receiver.contains('[') {

314+ continue

315+ }

316+ base_receiver := receiver.all_before('[')

317+ if base_receiver.len == 0 {

318+ continue

319+ }

320+ candidate := GenericMethodCandidate{

321+ name: name

322+ ret: ret

323+ params: g.tc.fn_param_types[name] or { []types.Type{} }

324+ }

325+ g.add_generic_method_candidate(base_receiver, method, candidate)

326+ short_receiver := base_receiver.all_after_last('.')

327+ if short_receiver != base_receiver {

328+ g.add_generic_method_candidate(short_receiver, method, candidate)

329+ }

330+ }

331+}

332+

333+fn (mut g FlatGen) add_generic_method_candidate(receiver string, method string, candidate GenericMethodCandidate) {

334+ key := generic_method_candidate_key(receiver, method)

335+ mut candidates := g.generic_method_candidates[key] or { []GenericMethodCandidate{} }

336+ candidates << candidate

337+ g.generic_method_candidates[key] = candidates

338+}

339+

295340// qualified_fn_name supports qualified fn name handling for FlatGen.

296341fn (g &FlatGen) qualified_fn_name(name string) string {

297342 return qualified_fn_name_in_module(g.tc.cur_module, name)

@@ -545,26 +590,21 @@ fn (g &FlatGen) specialized_generic_method_name_for_call_with_arg_count(id flat.

545590 }

546591 }

547592 }

548- for allow_short_receiver in [false, true] {

549- for candidate, ret in g.tc.fn_ret_types {

550- if !candidate.contains('[') || candidate.all_after_last('.') != method {

593+ for lookup_receiver in [receiver, receiver.all_after_last('.')] {

594+ candidates := g.generic_method_candidates[generic_method_candidate_key(lookup_receiver,

595+ method)] or { continue }

596+ for candidate in candidates {

597+ if arg_count >= 0 && candidate.params.len != arg_count {

551598 continue

552599 }

553- candidate_receiver := candidate.all_before_last('.')

554- base_receiver := candidate_receiver.all_before('[')

555- receiver_matches := base_receiver == receiver || (allow_short_receiver

556- && base_receiver.all_after_last('.') == receiver.all_after_last('.'))

557- if !receiver_matches {

558- continue

559- }

560- params := g.tc.fn_param_types[candidate] or { []types.Type{} }

561- if arg_count >= 0 && params.len != arg_count {

562- continue

563- }

564- if g.type_names_match(call_ret, ret) || call_ret.name() == ret.name() {

565- return candidate

600+ if g.type_names_match(call_ret, candidate.ret)

601+ || call_ret.name() == candidate.ret.name() {

602+ return candidate.name

566603 }

567604 }

605+ if lookup_receiver == receiver.all_after_last('.') {

606+ break

607+ }

568608 }

569609 return none

570610}

vlib/v3/gen/c/fn_d_parallel.v +57 -56

@@ -362,62 +362,63 @@ fn (mut g FlatGen) fn_ptr_type_key(typ types.FnType) string {

362362// worker and, under -gc none, never freed.

363363fn (g &FlatGen) new_parallel_worker(worker_id int) &FlatGen {

364364 return &FlatGen{

365- sb: strings.new_builder(64_000)

366- a: unsafe { g.a }

367- used_fns: g.used_fns

368- used_fn_names: g.used_fn_names

369- test_files: g.test_files.clone()

370- str_lits: g.str_lits.clone()

371- str_lit_ids: g.str_lit_ids.clone()

372- global_types: g.global_types

373- enum_vals: g.enum_vals

374- interfaces: g.interfaces

375- const_vals: g.const_vals

376- const_modules: g.const_modules

377- const_init_order: g.const_init_order

378- global_modules: g.global_modules

379- global_inits: g.global_inits

380- global_init_order: g.global_init_order

381- iface_impls: g.iface_impls

382- iface_type_ids: g.iface_type_ids

383- module_init_fns: g.module_init_fns

384- module_init_fn_modules: g.module_init_fn_modules

385- module_imports: g.module_imports

386- libc_compat_fns: g.libc_compat_fns.clone()

387- tc: g.clone_parallel_type_checker()

388- has_builtins: g.has_builtins

389- tmp_count: (worker_id + 1) * 100_000

390- line_start: true

391- modules: g.modules

392- fn_ptr_types: g.fn_ptr_types.clone()

393- fixed_array_ret_wrappers: g.fixed_array_ret_wrappers

394- fn_decl_param_types: g.fn_decl_param_types

395- fn_decl_ret_types: g.fn_decl_ret_types

396- struct_decl_infos: g.struct_decl_infos

397- struct_decl_short_infos: g.struct_decl_short_infos

398- const_runtime_inits: g.const_runtime_inits.clone()

399- runtime_inits: g.runtime_inits.clone()

400- compiler_vroot: g.compiler_vroot

401- cur_param_names: g.cur_param_names.clone()

402- cur_param_type_values: g.cur_param_type_values.clone()

403- cur_param_types: g.cur_param_types.clone()

404- cur_mut_params: g.cur_mut_params.clone()

405- cur_fn_ret: g.cur_fn_ret

406- cur_fn_ret_is_optional: g.cur_fn_ret_is_optional

407- cur_fn_ret_base: g.cur_fn_ret_base

408- expected_expr_type: g.expected_expr_type

409- expected_enum: g.expected_enum

410- needed_optional_types: g.needed_optional_types.clone()

411- emitted_optional_types: g.emitted_optional_types.clone()

412- emitted_fns: g.emitted_fns.clone()

413- array_method_cache: g.array_method_cache.clone()

414- param_types_cache: g.param_types_cache.clone()

415- embedded_fields_by_type: g.embedded_fields_by_type

416- param_types_by_short: g.param_types_by_short

417- spawn_wrapper_names: g.spawn_wrapper_names.clone()

418- spawn_wrapper_defs: g.spawn_wrapper_defs.clone()

419- callback_wrapper_names: g.callback_wrapper_names.clone()

420- callback_wrapper_defs: g.callback_wrapper_defs.clone()

365+ sb: strings.new_builder(64_000)

366+ a: unsafe { g.a }

367+ used_fns: g.used_fns

368+ used_fn_names: g.used_fn_names

369+ test_files: g.test_files.clone()

370+ str_lits: g.str_lits.clone()

371+ str_lit_ids: g.str_lit_ids.clone()

372+ global_types: g.global_types

373+ enum_vals: g.enum_vals

374+ interfaces: g.interfaces

375+ const_vals: g.const_vals

376+ const_modules: g.const_modules

377+ const_init_order: g.const_init_order

378+ global_modules: g.global_modules

379+ global_inits: g.global_inits

380+ global_init_order: g.global_init_order

381+ iface_impls: g.iface_impls

382+ iface_type_ids: g.iface_type_ids

383+ module_init_fns: g.module_init_fns

384+ module_init_fn_modules: g.module_init_fn_modules

385+ module_imports: g.module_imports

386+ libc_compat_fns: g.libc_compat_fns.clone()

387+ tc: g.clone_parallel_type_checker()

388+ has_builtins: g.has_builtins

389+ tmp_count: (worker_id + 1) * 100_000

390+ line_start: true

391+ modules: g.modules

392+ fn_ptr_types: g.fn_ptr_types.clone()

393+ fixed_array_ret_wrappers: g.fixed_array_ret_wrappers

394+ fn_decl_param_types: g.fn_decl_param_types

395+ fn_decl_ret_types: g.fn_decl_ret_types

396+ struct_decl_infos: g.struct_decl_infos

397+ struct_decl_short_infos: g.struct_decl_short_infos

398+ const_runtime_inits: g.const_runtime_inits.clone()

399+ runtime_inits: g.runtime_inits.clone()

400+ compiler_vroot: g.compiler_vroot

401+ cur_param_names: g.cur_param_names.clone()

402+ cur_param_type_values: g.cur_param_type_values.clone()

403+ cur_param_types: g.cur_param_types.clone()

404+ cur_mut_params: g.cur_mut_params.clone()

405+ cur_fn_ret: g.cur_fn_ret

406+ cur_fn_ret_is_optional: g.cur_fn_ret_is_optional

407+ cur_fn_ret_base: g.cur_fn_ret_base

408+ expected_expr_type: g.expected_expr_type

409+ expected_enum: g.expected_enum

410+ needed_optional_types: g.needed_optional_types.clone()

411+ emitted_optional_types: g.emitted_optional_types.clone()

412+ emitted_fns: g.emitted_fns.clone()

413+ array_method_cache: g.array_method_cache.clone()

414+ param_types_cache: g.param_types_cache.clone()

415+ embedded_fields_by_type: g.embedded_fields_by_type

416+ param_types_by_short: g.param_types_by_short

417+ generic_method_candidates: g.generic_method_candidates

418+ spawn_wrapper_names: g.spawn_wrapper_names.clone()

419+ spawn_wrapper_defs: g.spawn_wrapper_defs.clone()

420+ callback_wrapper_names: g.callback_wrapper_names.clone()

421+ callback_wrapper_defs: g.callback_wrapper_defs.clone()

421422 }

422423}