mirror of
https://github.com/vlang/v.git
synced 2025-09-12 00:46:55 -04:00
v: optimize the compiler performance (#22709)
This commit is contained in:
parent
2ad5d0cd15
commit
ee4f29fd87
@ -746,12 +746,6 @@ fn (s string) == (a string) bool {
|
|||||||
if s.len != a.len {
|
if s.len != a.len {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if s.len > 0 {
|
|
||||||
last_idx := s.len - 1
|
|
||||||
if s[last_idx] != a[last_idx] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe {
|
unsafe {
|
||||||
return vmemcmp(s.str, a.str, a.len) == 0
|
return vmemcmp(s.str, a.str, a.len) == 0
|
||||||
}
|
}
|
||||||
|
@ -360,6 +360,7 @@ pub:
|
|||||||
is_global bool
|
is_global bool
|
||||||
is_volatile bool
|
is_volatile bool
|
||||||
is_deprecated bool
|
is_deprecated bool
|
||||||
|
is_embed bool
|
||||||
pub mut:
|
pub mut:
|
||||||
is_recursive bool
|
is_recursive bool
|
||||||
is_part_of_union bool
|
is_part_of_union bool
|
||||||
@ -485,6 +486,7 @@ pub:
|
|||||||
next_comments []Comment
|
next_comments []Comment
|
||||||
has_prev_newline bool
|
has_prev_newline bool
|
||||||
has_break_line bool
|
has_break_line bool
|
||||||
|
is_embed bool
|
||||||
pub mut:
|
pub mut:
|
||||||
expr Expr // `val1`
|
expr Expr // `val1`
|
||||||
name string // 'field1'
|
name string // 'field1'
|
||||||
|
@ -40,6 +40,7 @@ pub fn new_scope(parent &Scope, start_pos int) &Scope {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@[inline]
|
||||||
fn (s &Scope) dont_lookup_parent() bool {
|
fn (s &Scope) dont_lookup_parent() bool {
|
||||||
return s.parent == unsafe { nil } || s.detached_from_parent
|
return s.parent == unsafe { nil } || s.detached_from_parent
|
||||||
}
|
}
|
||||||
|
@ -2000,7 +2000,7 @@ pub fn (mut t Table) unwrap_generic_type_ex(typ Type, generic_names []string, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update type in `info.embeds`, if it's embed
|
// Update type in `info.embeds`, if it's embed
|
||||||
if fields[i].name.len > 1 && fields[i].name[0].is_capital() {
|
if fields[i].is_embed {
|
||||||
mut parent_sym := t.sym(typ)
|
mut parent_sym := t.sym(typ)
|
||||||
mut parent_info := parent_sym.info
|
mut parent_info := parent_sym.info
|
||||||
if mut parent_info is Struct {
|
if mut parent_info is Struct {
|
||||||
@ -2186,7 +2186,7 @@ pub fn (mut t Table) generic_insts_to_concrete() {
|
|||||||
fields[i].typ = t_typ
|
fields[i].typ = t_typ
|
||||||
}
|
}
|
||||||
// Update type in `info.embeds`, if it's embed
|
// Update type in `info.embeds`, if it's embed
|
||||||
if fields[i].name.len > 1 && fields[i].name[0].is_capital() {
|
if fields[i].is_embed {
|
||||||
for mut embed in parent_info.embeds {
|
for mut embed in parent_info.embeds {
|
||||||
if embed == orig_type {
|
if embed == orig_type {
|
||||||
embed = fields[i].typ
|
embed = fields[i].typ
|
||||||
|
@ -1701,7 +1701,7 @@ pub fn (t &TypeSymbol) embed_name() string {
|
|||||||
|
|
||||||
pub fn (t &TypeSymbol) has_method(name string) bool {
|
pub fn (t &TypeSymbol) has_method(name string) bool {
|
||||||
for mut method in unsafe { t.methods } {
|
for mut method in unsafe { t.methods } {
|
||||||
if method.name == name {
|
if method.name.len == name.len && method.name == name {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1715,7 +1715,7 @@ pub fn (t &TypeSymbol) has_method_with_generic_parent(name string) bool {
|
|||||||
|
|
||||||
pub fn (t &TypeSymbol) find_method(name string) ?Fn {
|
pub fn (t &TypeSymbol) find_method(name string) ?Fn {
|
||||||
for mut method in unsafe { t.methods } {
|
for mut method in unsafe { t.methods } {
|
||||||
if method.name == name {
|
if method.name.len == name.len && method.name == name {
|
||||||
return method
|
return method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1830,7 +1830,7 @@ pub fn (t &TypeSymbol) has_field(name string) bool {
|
|||||||
|
|
||||||
fn (a &Aggregate) find_field(name string) ?StructField {
|
fn (a &Aggregate) find_field(name string) ?StructField {
|
||||||
for mut field in unsafe { a.fields } {
|
for mut field in unsafe { a.fields } {
|
||||||
if field.name == name {
|
if field.name.len == name.len && field.name == name {
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1839,7 +1839,7 @@ fn (a &Aggregate) find_field(name string) ?StructField {
|
|||||||
|
|
||||||
pub fn (i &Interface) find_field(name string) ?StructField {
|
pub fn (i &Interface) find_field(name string) ?StructField {
|
||||||
for mut field in unsafe { i.fields } {
|
for mut field in unsafe { i.fields } {
|
||||||
if field.name == name {
|
if field.name.len == name.len && field.name == name {
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1848,7 +1848,7 @@ pub fn (i &Interface) find_field(name string) ?StructField {
|
|||||||
|
|
||||||
pub fn (i &Interface) find_method(name string) ?Fn {
|
pub fn (i &Interface) find_method(name string) ?Fn {
|
||||||
for mut method in unsafe { i.methods } {
|
for mut method in unsafe { i.methods } {
|
||||||
if method.name == name {
|
if method.name.len == name.len && method.name == name {
|
||||||
return method
|
return method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1857,7 +1857,7 @@ pub fn (i &Interface) find_method(name string) ?Fn {
|
|||||||
|
|
||||||
pub fn (i &Interface) has_method(name string) bool {
|
pub fn (i &Interface) has_method(name string) bool {
|
||||||
for mut method in unsafe { i.methods } {
|
for mut method in unsafe { i.methods } {
|
||||||
if method.name == name {
|
if method.name.len == name.len && method.name == name {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1866,7 +1866,7 @@ pub fn (i &Interface) has_method(name string) bool {
|
|||||||
|
|
||||||
pub fn (s Struct) find_field(name string) ?StructField {
|
pub fn (s Struct) find_field(name string) ?StructField {
|
||||||
for mut field in unsafe { s.fields } {
|
for mut field in unsafe { s.fields } {
|
||||||
if field.name == name {
|
if name.len == field.name.len && field.name == name {
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5360,10 +5360,10 @@ fn (c &Checker) check_import_sym_conflict(ident string) bool {
|
|||||||
for import_sym in c.file.imports {
|
for import_sym in c.file.imports {
|
||||||
// Check if alias exists or not
|
// Check if alias exists or not
|
||||||
if !import_sym.alias.is_blank() {
|
if !import_sym.alias.is_blank() {
|
||||||
if import_sym.alias == ident {
|
if import_sym.alias.len == ident.len && import_sym.alias == ident {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else if import_sym.mod == ident {
|
} else if import_sym.mod.len == ident.len && import_sym.mod == ident {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,8 +806,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
|
|||||||
|
|
||||||
// all the fields of initialized embedded struct are ignored, they are considered initialized
|
// all the fields of initialized embedded struct are ignored, they are considered initialized
|
||||||
sym := c.table.sym(init_field.typ)
|
sym := c.table.sym(init_field.typ)
|
||||||
if init_field.name != '' && init_field.name[0].is_capital() && sym.kind == .struct
|
if init_field.is_embed && sym.kind == .struct && sym.language == .v {
|
||||||
&& sym.language == .v {
|
|
||||||
struct_fields := c.table.struct_fields(sym)
|
struct_fields := c.table.struct_fields(sym)
|
||||||
for struct_field in struct_fields {
|
for struct_field in struct_fields {
|
||||||
inited_fields << struct_field.name
|
inited_fields << struct_field.name
|
||||||
@ -928,7 +927,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sym := c.table.sym(field.typ)
|
sym := c.table.sym(field.typ)
|
||||||
if field.name != '' && field.name[0].is_capital() && sym.info is ast.Struct {
|
if field.is_embed && sym.info is ast.Struct {
|
||||||
// struct embeds
|
// struct embeds
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -957,13 +956,14 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field.typ.is_ptr() && !field.typ.has_flag(.shared_f) && !field.typ.has_flag(.option)
|
field_is_option := field.typ.has_flag(.option)
|
||||||
|
if field.typ.is_ptr() && !field.typ.has_flag(.shared_f) && !field_is_option
|
||||||
&& !node.has_update_expr && !c.pref.translated && !c.file.is_translated {
|
&& !node.has_update_expr && !c.pref.translated && !c.file.is_translated {
|
||||||
c.error('reference field `${type_sym.name}.${field.name}` must be initialized',
|
c.error('reference field `${type_sym.name}.${field.name}` must be initialized',
|
||||||
node.pos)
|
node.pos)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !field.typ.has_flag(.option) {
|
if !field_is_option {
|
||||||
if sym.kind == .struct {
|
if sym.kind == .struct {
|
||||||
c.check_ref_fields_initialized(sym, mut checked_types, '${type_sym.name}.${field.name}',
|
c.check_ref_fields_initialized(sym, mut checked_types, '${type_sym.name}.${field.name}',
|
||||||
node.pos)
|
node.pos)
|
||||||
@ -976,7 +976,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Do not allow empty uninitialized interfaces
|
// Do not allow empty uninitialized interfaces
|
||||||
if sym.kind == .interface && !node.has_update_expr && !field.typ.has_flag(.option)
|
if sym.kind == .interface && !node.has_update_expr && !field_is_option
|
||||||
&& sym.language != .js && !field.attrs.contains('noinit') {
|
&& sym.language != .js && !field.attrs.contains('noinit') {
|
||||||
// TODO: should be an error instead, but first `ui` needs updating.
|
// TODO: should be an error instead, but first `ui` needs updating.
|
||||||
c.note('interface field `${type_sym.name}.${field.name}` must be initialized',
|
c.note('interface field `${type_sym.name}.${field.name}` must be initialized',
|
||||||
@ -996,7 +996,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
|||||||
c.error('field `${type_sym.name}.${field.name}` must be initialized', node.pos)
|
c.error('field `${type_sym.name}.${field.name}` must be initialized', node.pos)
|
||||||
}
|
}
|
||||||
if !node.has_update_expr && !field.has_default_expr && !field.typ.is_ptr()
|
if !node.has_update_expr && !field.has_default_expr && !field.typ.is_ptr()
|
||||||
&& !field.typ.has_flag(.option) {
|
&& !field_is_option {
|
||||||
field_final_sym := c.table.final_sym(field.typ)
|
field_final_sym := c.table.final_sym(field.typ)
|
||||||
if field_final_sym.kind == .struct {
|
if field_final_sym.kind == .struct {
|
||||||
mut zero_struct_init := ast.StructInit{
|
mut zero_struct_init := ast.StructInit{
|
||||||
@ -1063,7 +1063,7 @@ fn (mut c Checker) check_ref_fields_initialized(struct_sym &ast.TypeSymbol, mut
|
|||||||
if sym.language == .c {
|
if sym.language == .c {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field.name != '' && field.name[0].is_capital() && sym.language == .v {
|
if field.is_embed && sym.language == .v {
|
||||||
// an embedded struct field
|
// an embedded struct field
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1106,7 +1106,7 @@ fn (mut c Checker) check_ref_fields_initialized_note(struct_sym &ast.TypeSymbol,
|
|||||||
if sym.language == .c {
|
if sym.language == .c {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field.name != '' && field.name[0].is_capital() && sym.language == .v {
|
if field.is_embed && sym.language == .v {
|
||||||
// an embedded struct field
|
// an embedded struct field
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,14 @@ pub fn (o &OrderedDepMap) get(name string) []string {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@[direct_array_access]
|
||||||
pub fn (mut o OrderedDepMap) delete(name string) {
|
pub fn (mut o OrderedDepMap) delete(name string) {
|
||||||
if name !in o.data {
|
if name !in o.data {
|
||||||
panic('delete: no such key: ${name}')
|
panic('delete: no such key: ${name}')
|
||||||
}
|
}
|
||||||
for i, _ in o.keys {
|
for i, _ in o.keys {
|
||||||
if o.keys[i] == name {
|
item := o.keys[i]
|
||||||
|
if item.len == name.len && item == name {
|
||||||
o.keys.delete(i)
|
o.keys.delete(i)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1086,8 +1086,12 @@ fn (mut g Gen) gen_array_contains_methods() {
|
|||||||
ptr_typ := g.equality_fn(elem_type)
|
ptr_typ := g.equality_fn(elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
||||||
} else if elem_kind == .alias && elem_is_not_ptr {
|
} else if elem_kind == .alias && elem_is_not_ptr {
|
||||||
|
if g.no_eq_method_types[elem_type] {
|
||||||
|
fn_builder.writeln('\t\tif (((${elem_type_str}*)a.data)[i] == v) {')
|
||||||
|
} else {
|
||||||
ptr_typ := g.equality_fn(elem_type)
|
ptr_typ := g.equality_fn(elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fn_builder.writeln('\t\tif (((${elem_type_str}*)a.data)[i] == v) {')
|
fn_builder.writeln('\t\tif (((${elem_type_str}*)a.data)[i] == v) {')
|
||||||
}
|
}
|
||||||
@ -1124,8 +1128,12 @@ fn (mut g Gen) gen_array_contains_methods() {
|
|||||||
ptr_typ := g.equality_fn(elem_type)
|
ptr_typ := g.equality_fn(elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(a[i], v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(a[i], v)) {')
|
||||||
} else if elem_kind == .alias && elem_is_not_ptr {
|
} else if elem_kind == .alias && elem_is_not_ptr {
|
||||||
|
if g.no_eq_method_types[elem_type] {
|
||||||
|
fn_builder.writeln('\t\tif (a[i] == v) {')
|
||||||
|
} else {
|
||||||
ptr_typ := g.equality_fn(elem_type)
|
ptr_typ := g.equality_fn(elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(a[i], v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(a[i], v)) {')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fn_builder.writeln('\t\tif (a[i] == v) {')
|
fn_builder.writeln('\t\tif (a[i] == v) {')
|
||||||
}
|
}
|
||||||
|
@ -97,8 +97,12 @@ fn (mut g Gen) gen_sumtype_equality_fn(left_type ast.Type) string {
|
|||||||
eq_fn := g.gen_map_equality_fn(typ)
|
eq_fn := g.gen_map_equality_fn(typ)
|
||||||
fn_builder.writeln('\t\treturn ${eq_fn}_map_eq(*${left_arg}, *${right_arg});')
|
fn_builder.writeln('\t\treturn ${eq_fn}_map_eq(*${left_arg}, *${right_arg});')
|
||||||
} else if variant.sym.kind == .alias && !typ.is_ptr() {
|
} else if variant.sym.kind == .alias && !typ.is_ptr() {
|
||||||
|
if g.no_eq_method_types[typ] {
|
||||||
|
fn_builder.writeln('\t\treturn *${left_arg} == *${right_arg};')
|
||||||
|
} else {
|
||||||
eq_fn := g.gen_alias_equality_fn(typ)
|
eq_fn := g.gen_alias_equality_fn(typ)
|
||||||
fn_builder.writeln('\t\treturn ${eq_fn}_alias_eq(*${left_arg}, *${right_arg});')
|
fn_builder.writeln('\t\treturn ${eq_fn}_alias_eq(*${left_arg}, *${right_arg});')
|
||||||
|
}
|
||||||
} else if variant.sym.kind == .function {
|
} else if variant.sym.kind == .function {
|
||||||
fn_builder.writeln('\t\treturn *((voidptr*)(*${left_arg})) == *((voidptr*)(*${right_arg}));')
|
fn_builder.writeln('\t\treturn *((voidptr*)(*${left_arg})) == *((voidptr*)(*${right_arg}));')
|
||||||
} else {
|
} else {
|
||||||
@ -242,8 +246,12 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
|
|||||||
eq_fn := g.gen_map_equality_fn(field.typ)
|
eq_fn := g.gen_map_equality_fn(field.typ)
|
||||||
fn_builder.write_string('${eq_fn}_map_eq(${left_arg}, ${right_arg})')
|
fn_builder.write_string('${eq_fn}_map_eq(${left_arg}, ${right_arg})')
|
||||||
} else if field_type.sym.kind == .alias && !field.typ.is_ptr() {
|
} else if field_type.sym.kind == .alias && !field.typ.is_ptr() {
|
||||||
|
if g.no_eq_method_types[field.typ] {
|
||||||
|
fn_builder.write_string('${left_arg} == ${right_arg}')
|
||||||
|
} else {
|
||||||
eq_fn := g.gen_alias_equality_fn(field.typ)
|
eq_fn := g.gen_alias_equality_fn(field.typ)
|
||||||
fn_builder.write_string('${eq_fn}_alias_eq(${left_arg}, ${right_arg})')
|
fn_builder.write_string('${eq_fn}_alias_eq(${left_arg}, ${right_arg})')
|
||||||
|
}
|
||||||
} else if field_type.sym.kind == .function && !field.typ.has_flag(.option) {
|
} else if field_type.sym.kind == .function && !field.typ.has_flag(.option) {
|
||||||
fn_builder.write_string('*((voidptr*)(${left_arg})) == *((voidptr*)(${right_arg}))')
|
fn_builder.write_string('*((voidptr*)(${left_arg})) == *((voidptr*)(${right_arg}))')
|
||||||
} else if field_type.sym.kind == .interface
|
} else if field_type.sym.kind == .interface
|
||||||
@ -385,8 +393,12 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string {
|
|||||||
eq_fn := g.gen_map_equality_fn(elem.typ)
|
eq_fn := g.gen_map_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
||||||
} else if elem.sym.kind == .alias && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .alias && !elem.typ.is_ptr() {
|
||||||
|
if g.no_eq_method_types[elem.typ] {
|
||||||
|
fn_builder.writeln('\t\tif (((${ptr_elem_styp}*)${left_data})[i] != ((${ptr_elem_styp}*)${right_data})[i]) {')
|
||||||
|
} else {
|
||||||
eq_fn := g.gen_alias_equality_fn(elem.typ)
|
eq_fn := g.gen_alias_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
||||||
|
}
|
||||||
} else if elem.sym.kind == .function {
|
} else if elem.sym.kind == .function {
|
||||||
fn_builder.writeln('\t\tif (*((voidptr*)((byte*)${left_data}+(i*${left_elem}))) != *((voidptr*)((byte*)${right_data}+(i*${right_elem})))) {')
|
fn_builder.writeln('\t\tif (*((voidptr*)((byte*)${left_data}+(i*${left_elem}))) != *((voidptr*)((byte*)${right_data}+(i*${right_elem})))) {')
|
||||||
} else {
|
} else {
|
||||||
|
@ -87,6 +87,7 @@ mut:
|
|||||||
file &ast.File = unsafe { nil }
|
file &ast.File = unsafe { nil }
|
||||||
table &ast.Table = unsafe { nil }
|
table &ast.Table = unsafe { nil }
|
||||||
styp_cache map[ast.Type]string
|
styp_cache map[ast.Type]string
|
||||||
|
no_eq_method_types map[ast.Type]bool // types that does not need to call its auto eq methods for optimization
|
||||||
unique_file_path_hash u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`)
|
unique_file_path_hash u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`)
|
||||||
fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0
|
fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0
|
||||||
last_fn_c_name string
|
last_fn_c_name string
|
||||||
@ -466,6 +467,9 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
|
|||||||
for k, v in g.autofree_methods {
|
for k, v in g.autofree_methods {
|
||||||
global_g.autofree_methods[k] = v
|
global_g.autofree_methods[k] = v
|
||||||
}
|
}
|
||||||
|
for k, v in g.no_eq_method_types {
|
||||||
|
global_g.no_eq_method_types[k] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
util.timing_start('cgen serial processing')
|
util.timing_start('cgen serial processing')
|
||||||
@ -1062,13 +1066,13 @@ pub fn (mut g Gen) write_typeof_functions() {
|
|||||||
// V type to C typecc
|
// V type to C typecc
|
||||||
@[inline]
|
@[inline]
|
||||||
fn (mut g Gen) styp(t ast.Type) string {
|
fn (mut g Gen) styp(t ast.Type) string {
|
||||||
if t.has_flag(.option) {
|
if !t.has_option_or_result() {
|
||||||
|
return g.base_type(t)
|
||||||
|
} else if t.has_flag(.option) {
|
||||||
// Register an optional if it's not registered yet
|
// Register an optional if it's not registered yet
|
||||||
return g.register_option(t)
|
return g.register_option(t)
|
||||||
} else if t.has_flag(.result) {
|
|
||||||
return g.register_result(t)
|
|
||||||
} else {
|
} else {
|
||||||
return g.base_type(t)
|
return g.register_result(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,7 +1102,7 @@ fn (mut g Gen) base_type(_t ast.Type) string {
|
|||||||
if t.has_flag(.shared_f) {
|
if t.has_flag(.shared_f) {
|
||||||
styp = g.find_or_register_shared(t, styp)
|
styp = g.find_or_register_shared(t, styp)
|
||||||
}
|
}
|
||||||
nr_muls := g.unwrap_generic(t).nr_muls()
|
nr_muls := t.nr_muls()
|
||||||
if nr_muls > 0 {
|
if nr_muls > 0 {
|
||||||
styp += strings.repeat(`*`, nr_muls)
|
styp += strings.repeat(`*`, nr_muls)
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,19 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
|||||||
}
|
}
|
||||||
match kind {
|
match kind {
|
||||||
.alias {
|
.alias {
|
||||||
|
// optimize simple eq/ne operation on numbers
|
||||||
|
if left.unaliased_sym.is_int() {
|
||||||
|
if left.typ.is_ptr() {
|
||||||
|
g.write('*'.repeat(left.typ.nr_muls()))
|
||||||
|
}
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(' ${node.op} ')
|
||||||
|
if right.typ.is_ptr() {
|
||||||
|
g.write('*'.repeat(right.typ.nr_muls()))
|
||||||
|
}
|
||||||
|
g.expr(node.right)
|
||||||
|
g.no_eq_method_types[left.typ] = true
|
||||||
|
} else {
|
||||||
ptr_typ := g.equality_fn(left.typ)
|
ptr_typ := g.equality_fn(left.typ)
|
||||||
if node.op == .ne {
|
if node.op == .ne {
|
||||||
g.write('!')
|
g.write('!')
|
||||||
@ -209,6 +222,7 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
|||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.array {
|
.array {
|
||||||
ptr_typ := g.equality_fn(left.unaliased.clear_flag(.shared_f))
|
ptr_typ := g.equality_fn(left.unaliased.clear_flag(.shared_f))
|
||||||
if node.op == .ne {
|
if node.op == .ne {
|
||||||
@ -515,10 +529,10 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
|||||||
expr: node.left
|
expr: node.left
|
||||||
expr_type: node.left_type
|
expr_type: node.left_type
|
||||||
}
|
}
|
||||||
g.infix_expr_in_optimization(new_node_left, node.right)
|
g.infix_expr_in_optimization(new_node_left, node.left_type, node.right)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.infix_expr_in_optimization(node.left, node.right)
|
g.infix_expr_in_optimization(node.left, node.left_type, node.right)
|
||||||
}
|
}
|
||||||
g.write(')')
|
g.write(')')
|
||||||
return
|
return
|
||||||
@ -604,7 +618,7 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
|||||||
// `a in [1,2,3]!` optimization => `a == 1 || a == 2 || a == 3`
|
// `a in [1,2,3]!` optimization => `a == 1 || a == 2 || a == 3`
|
||||||
// avoids an allocation
|
// avoids an allocation
|
||||||
g.write('(')
|
g.write('(')
|
||||||
g.infix_expr_in_optimization(node.left, node.right)
|
g.infix_expr_in_optimization(node.left, node.left_type, node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -642,8 +656,9 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
|||||||
// infix_expr_in_optimization optimizes `<var> in <array>` expressions,
|
// infix_expr_in_optimization optimizes `<var> in <array>` expressions,
|
||||||
// and transform them in a series of equality comparison
|
// and transform them in a series of equality comparison
|
||||||
// i.e. `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
|
// i.e. `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
|
||||||
fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, left_type ast.Type, right ast.ArrayInit) {
|
||||||
mut elem_sym := g.table.sym(right.elem_type)
|
mut elem_sym := g.table.sym(right.elem_type)
|
||||||
|
left_parent_idx := g.table.sym(left_type).parent_idx
|
||||||
for i, array_expr in right.exprs {
|
for i, array_expr in right.exprs {
|
||||||
match elem_sym.kind {
|
match elem_sym.kind {
|
||||||
.string, .alias, .sum_type, .map, .interface, .array, .struct {
|
.string, .alias, .sum_type, .map, .interface, .array, .struct {
|
||||||
@ -659,9 +674,10 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
|||||||
} else {
|
} else {
|
||||||
g.write('_SLIT_EQ(${var}.str, ${var}.len, "${slit}")')
|
g.write('_SLIT_EQ(${var}.str, ${var}.len, "${slit}")')
|
||||||
}
|
}
|
||||||
unsafe {
|
if i < right.exprs.len - 1 {
|
||||||
goto end
|
g.write(' || ')
|
||||||
}
|
}
|
||||||
|
continue
|
||||||
} else if array_expr is ast.StringLiteral {
|
} else if array_expr is ast.StringLiteral {
|
||||||
g.write('fast_string_eq(')
|
g.write('fast_string_eq(')
|
||||||
} else {
|
} else {
|
||||||
@ -674,7 +690,23 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
|||||||
} else {
|
} else {
|
||||||
ptr_typ := g.equality_fn(right.elem_type)
|
ptr_typ := g.equality_fn(right.elem_type)
|
||||||
if elem_sym.kind == .alias {
|
if elem_sym.kind == .alias {
|
||||||
|
// optimization for alias to number
|
||||||
|
if elem_sym.is_int() {
|
||||||
|
g.expr(left)
|
||||||
|
g.write(' == ')
|
||||||
|
if left_parent_idx != 0 && !((array_expr is ast.SelectorExpr
|
||||||
|
&& array_expr.typ == left_type)
|
||||||
|
|| (array_expr is ast.Ident && array_expr.obj.typ == left_type)) {
|
||||||
|
g.write('(${g.styp(left_parent_idx)})')
|
||||||
|
}
|
||||||
|
g.expr(array_expr)
|
||||||
|
if i < right.exprs.len - 1 {
|
||||||
|
g.write(' || ')
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
g.write('${ptr_typ}_alias_eq(')
|
g.write('${ptr_typ}_alias_eq(')
|
||||||
|
}
|
||||||
} else if elem_sym.kind == .sum_type {
|
} else if elem_sym.kind == .sum_type {
|
||||||
g.write('${ptr_typ}_sumtype_eq(')
|
g.write('${ptr_typ}_sumtype_eq(')
|
||||||
} else if elem_sym.kind == .map {
|
} else if elem_sym.kind == .map {
|
||||||
@ -698,7 +730,6 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
|||||||
g.expr(array_expr)
|
g.expr(array_expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
|
||||||
if i < right.exprs.len - 1 {
|
if i < right.exprs.len - 1 {
|
||||||
g.write(' || ')
|
g.write(' || ')
|
||||||
}
|
}
|
||||||
|
@ -782,7 +782,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// embeded
|
// embeded
|
||||||
if name.len > 0 && name[0].is_capital() && field_sym.info is ast.Struct {
|
if field.is_embed && field_sym.info is ast.Struct {
|
||||||
for embed in info.embeds {
|
for embed in info.embeds {
|
||||||
if embed == int(field.typ) {
|
if embed == int(field.typ) {
|
||||||
prefix_embed := if embed_prefix != '' {
|
prefix_embed := if embed_prefix != '' {
|
||||||
|
@ -31,7 +31,7 @@ fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if typ.has_flag(.generic) && g.table.sym(typ).kind == .struct {
|
} else if g.table.sym(typ).kind == .struct {
|
||||||
// resolve selector `a.foo` where `a` is struct[T] on non generic function
|
// resolve selector `a.foo` where `a` is struct[T] on non generic function
|
||||||
sym := g.table.sym(typ)
|
sym := g.table.sym(typ)
|
||||||
if sym.info is ast.Struct {
|
if sym.info is ast.Struct {
|
||||||
|
@ -2214,6 +2214,7 @@ fn (mut p Parser) note_with_pos(s string, pos token.Pos) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@[direct_array_access]
|
||||||
fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
||||||
// in here might be 1) multi-expr 2) multi-assign
|
// in here might be 1) multi-expr 2) multi-assign
|
||||||
// 1, a, c ... } // multi-expression
|
// 1, a, c ... } // multi-expression
|
||||||
|
@ -340,6 +340,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
|||||||
attrs: p.attrs
|
attrs: p.attrs
|
||||||
is_pub: is_embed || is_field_pub
|
is_pub: is_embed || is_field_pub
|
||||||
is_mut: is_embed || is_field_mut
|
is_mut: is_embed || is_field_mut
|
||||||
|
is_embed: is_embed
|
||||||
is_global: is_field_global
|
is_global: is_field_global
|
||||||
is_volatile: is_field_volatile
|
is_volatile: is_field_volatile
|
||||||
is_deprecated: is_field_deprecated
|
is_deprecated: is_field_deprecated
|
||||||
@ -503,6 +504,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
|
|||||||
parent_type: typ
|
parent_type: typ
|
||||||
has_prev_newline: has_prev_newline
|
has_prev_newline: has_prev_newline
|
||||||
has_break_line: has_break_line
|
has_break_line: has_break_line
|
||||||
|
is_embed: field_name.len > 0 && field_name[0].is_capital()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user