Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Task]: Update runtime type creation to support semtypes #42475

Closed
heshanpadmasiri opened this issue Apr 4, 2024 · 1 comment
Closed

[Task]: Update runtime type creation to support semtypes #42475

heshanpadmasiri opened this issue Apr 4, 2024 · 1 comment
Assignees
Labels
Team/jBallerina All the issues related to BIR, JVM backend code generation and runtime Type/Task

Comments

@heshanpadmasiri
Copy link
Member

heshanpadmasiri commented Apr 4, 2024

Description

Background

JBallerina runtime type resolution

  • For potentially recursive types we create separate “constant” classes (see JvmConstantsGen)
  • Each of these classes will have static field for each type and other types that refer to that type will use static field
    • This means we should set a effectively final value to this field before creating the other type
  • Later we use the fact some of the BTypes are effectively mutable to fill in the actual type.
  • For example consider Type F int|F[]. This would be created as follows
    1. Create a static field (say F’) to for the union type F and assign a BUnionType for that
    2. Create each individual members of the union type
    • When it comes to creating the BArrayType for F[] use the the field (F’) since it is already initialized
    1. Use the setMemberTypes method of the BUnionType to set the corresponding members in F’

NBallerina type resolution

We will be using the compile time type resolution instead of the runtime one since NBallerina’s runtime does not support creating new types at runtime and assume all possible type operations are known at the compile time

  • Type resolution happens by recursively visiting the each member of the type and combining them (see resolveTypeDesc)
    • When encountering a potentially recursive type such as a list type for the first time create a “definition” (ListDefinition in this case) and recursively visit its elements
    • If the type is indeed recursive we’ll visit the same type again but this time with a definition, which will then return a pointer to the Environments recursive type array which will get filled in when the first iteration is completed. This solves the infinite recursion problem while keeping the type it self immutable (tuple example)

Problem

  1. We can’t directly adopt the current approach in JBallerina since semtypes are immutable (ie. we can’t create the semtype and later set its members).
    • There is also the potential problem of ordering the type field creations with semtypes
  2. We need some sort of a wrapper for potentially recursive types that’ll hold the “Definition” needed for type resolution.

Proposed solution (SemTypeSupplier)

  • Each SemTypeSupplier would be a Supplier<BSemType>
    • For potentially recurisive cases this would be class containing a the definition as a field
    • For other this would just be a lambda function
  • We’ll support creating SemTypeSuppliers using other SemTypeSuppliers. For example we’ll create the union type using SemTypeSuppliers for each of it’s members similar to how JBallerina create unions.
  • Calling get on one supplier will cause it to resolve the type similar to NBallerina by calling it’s member suppliers. Result of this is a immutable semtype.

Potential optimizations

  • We only need suppliers for user defined types (and language types that can recurse like json)
  • We only need to hold on to the supplier of user defined types and not it’s members so after calculation get rid of them (which is easier to do since we don’t need to create fields for them)
  • Internally cache the results such that if any supplier ends up in some hot section (somewhat unlikely since after initialization in most places we will be directly using the SemType not the supplier) we won’t recalculate the result.

Alternative solutions

Introduce a wrapper object to SemType

This wrapper will provide a method to get the semtype and lazily evaluate the result using the definition. This means this class is mechanically similar to the SemTypeSupplier. However this means TypeChecker will always have to get the semtype from this wrapper for every type check (this could either be a method call or null check + field access). While this in itself is not hugely expensive, I couldn't think of anything this solution can do (perhaps one can argue this is easier to codegen) that proposed solution can’t do that justify this runtime overhead, in a critical section of the code.

Needed for the runtime part of #42425

Describe your task(s)

No response

Related area

-> Runtime

Related issue(s) (optional)

No response

Suggested label(s) (optional)

No response

Suggested assignee(s) (optional)

No response

@heshanpadmasiri heshanpadmasiri self-assigned this Apr 4, 2024
@ballerina-bot ballerina-bot added the Team/jBallerina All the issues related to BIR, JVM backend code generation and runtime label Apr 4, 2024
@heshanpadmasiri heshanpadmasiri changed the title [Task]: Update runtime type codegen to support semtypes [Task]: Update runtime type creation to support semtypes Apr 4, 2024
@heshanpadmasiri heshanpadmasiri moved this from In Progress to On Hold in Ballerina Team Main Board Apr 9, 2024
@heshanpadmasiri
Copy link
Member Author

Due to design in #40512 we shouldn't need this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team/jBallerina All the issues related to BIR, JVM backend code generation and runtime Type/Task
Projects
Archived in project
Development

No branches or pull requests

2 participants