Module: MilkTea::Types::Registry
- Defined in:
- lib/milk_tea/core/types/registry.rb
Class Method Summary collapse
- ._intern(key, &construct) ⇒ Object
- .dyn(interface_binding, type_arguments = []) ⇒ Object
- .function(name, params:, return_type:, receiver_type: nil, receiver_editable: false, variadic: false, external: false) ⇒ Object
- .generic_instance(name, arguments) ⇒ Object
- .lifetime_ref(name) ⇒ Object
- .nullable(base) ⇒ Object
- .param_signature(params) ⇒ Object
- .parameter(name, type, mutable: false, passing_mode: :plain, boundary_type: nil) ⇒ Object
- .primitive(name) ⇒ Object
- .proc(params:, return_type:) ⇒ Object
- .reset! ⇒ Object
- .simd(element_type, lane_count:) ⇒ Object
- .soa(element_type, count:) ⇒ Object
- .span(element_type) ⇒ Object
- .string_view ⇒ Object
- .task(result_type) ⇒ Object
- .tuple(element_types, field_names: nil) ⇒ Object
-
.type_signature(type) ⇒ Object
Name-sensitive signature for intern keys.
Class Method Details
._intern(key, &construct) ⇒ Object
13 14 15 16 17 |
# File 'lib/milk_tea/core/types/registry.rb', line 13 def self._intern(key, &construct) @mutex.synchronize do @pool[key] ||= construct.call end end |
.dyn(interface_binding, type_arguments = []) ⇒ Object
115 116 117 |
# File 'lib/milk_tea/core/types/registry.rb', line 115 def self.dyn(interface_binding, type_arguments = []) Dyn.new(interface_binding, type_arguments) end |
.function(name, params:, return_type:, receiver_type: nil, receiver_editable: false, variadic: false, external: false) ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/milk_tea/core/types/registry.rb', line 77 def self.function(name, params:, return_type:, receiver_type: nil, receiver_editable: false, variadic: false, external: false) params_frozen = params.freeze param_key = param_signature(params_frozen) _intern([:function, name, param_key, type_signature(return_type), type_signature(receiver_type), receiver_editable, variadic, external]) { Function.new(name, params: params_frozen, return_type: return_type, receiver_type: receiver_type, receiver_editable: receiver_editable, variadic: variadic, external: external) } end |
.generic_instance(name, arguments) ⇒ Object
27 28 29 30 |
# File 'lib/milk_tea/core/types/registry.rb', line 27 def self.generic_instance(name, arguments) args = arguments.freeze _intern([:generic, name, args.map { |a| type_signature(a) }.freeze]) { GenericInstance.new(name, args) } end |
.lifetime_ref(name) ⇒ Object
111 112 113 |
# File 'lib/milk_tea/core/types/registry.rb', line 111 def self.lifetime_ref(name) LifetimeRef.new(name) end |
.nullable(base) ⇒ Object
23 24 25 |
# File 'lib/milk_tea/core/types/registry.rb', line 23 def self.nullable(base) _intern([:nullable, type_signature(base)]) { Nullable.new(base) } end |
.param_signature(params) ⇒ Object
73 74 75 |
# File 'lib/milk_tea/core/types/registry.rb', line 73 def self.param_signature(params) params.map { |p| [p.name, type_signature(p.type), p.mutable, p.passing_mode, p.boundary_type] } end |
.parameter(name, type, mutable: false, passing_mode: :plain, boundary_type: nil) ⇒ Object
91 92 93 94 95 |
# File 'lib/milk_tea/core/types/registry.rb', line 91 def self.parameter(name, type, mutable: false, passing_mode: :plain, boundary_type: nil) _intern([:parameter, name, type, mutable, passing_mode, boundary_type]) { Parameter.new(name, type, mutable: mutable, passing_mode: passing_mode, boundary_type: boundary_type) } end |
.primitive(name) ⇒ Object
19 20 21 |
# File 'lib/milk_tea/core/types/registry.rb', line 19 def self.primitive(name) _intern([:primitive, name]) { Primitive.new(name) } end |
.proc(params:, return_type:) ⇒ Object
85 86 87 88 89 |
# File 'lib/milk_tea/core/types/registry.rb', line 85 def self.proc(params:, return_type:) params_frozen = params.freeze param_key = param_signature(params_frozen) _intern([:proc, param_key, type_signature(return_type)]) { Proc.new(params: params_frozen, return_type: return_type) } end |
.reset! ⇒ Object
9 10 11 |
# File 'lib/milk_tea/core/types/registry.rb', line 9 def self.reset! @mutex.synchronize { @pool.clear } end |
.simd(element_type, lane_count:) ⇒ Object
107 108 109 |
# File 'lib/milk_tea/core/types/registry.rb', line 107 def self.simd(element_type, lane_count:) _intern([:simd, type_signature(element_type), lane_count]) { Simd.new(element_type, lane_count: lane_count) } end |
.soa(element_type, count:) ⇒ Object
103 104 105 |
# File 'lib/milk_tea/core/types/registry.rb', line 103 def self.soa(element_type, count:) _intern([:soa, type_signature(element_type), count]) { SoA.new(element_type, count: count) } end |
.span(element_type) ⇒ Object
32 33 34 |
# File 'lib/milk_tea/core/types/registry.rb', line 32 def self.span(element_type) _intern([:span, type_signature(element_type)]) { Span.new(element_type) } end |
.string_view ⇒ Object
40 41 42 |
# File 'lib/milk_tea/core/types/registry.rb', line 40 def self.string_view _intern([:string_view]) { StringView.new } end |
.task(result_type) ⇒ Object
36 37 38 |
# File 'lib/milk_tea/core/types/registry.rb', line 36 def self.task(result_type) _intern([:task, type_signature(result_type)]) { Task.new(result_type) } end |
.tuple(element_types, field_names: nil) ⇒ Object
97 98 99 100 101 |
# File 'lib/milk_tea/core/types/registry.rb', line 97 def self.tuple(element_types, field_names: nil) et_frozen = element_types.freeze fn_frozen = field_names&.freeze _intern([:tuple, et_frozen.map { |t| type_signature(t) }.freeze, fn_frozen]) { Tuple.new(et_frozen, field_names: fn_frozen) } end |
.type_signature(type) ⇒ Object
Name-sensitive signature for intern keys. Parameter#eql? is name-insensitive (assignability must not depend on parameter names), so Function/Proc objects (and any wrapper containing them) that differ only in parameter names collide under Hash/==. Pool keys that embed such types raw therefore conflate fn(value: int) with fn(arg0: int) in a long-lived pool (the LSP never resets the registry between checks), leaking one program's parameter names into another's generated C. Embedding names here keeps distinct signatures distinct.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/milk_tea/core/types/registry.rb', line 52 def self.type_signature(type) case type when Function [:function, type.name, param_signature(type.params), type_signature(type.return_type), type_signature(type.receiver_type), type.receiver_editable, type.variadic, type.external] when Proc [:proc, param_signature(type.params), type_signature(type.return_type)] when Nullable [:nullable, type_signature(type.base)] when GenericInstance [:generic, type.name, type.arguments.map { |a| type_signature(a) }] when Tuple [:tuple, type.element_types.map { |t| type_signature(t) }, type.field_names] when Span [:span, type_signature(type.element_type)] when Task [:task, type_signature(type.result_type)] else type end end |