timefold-solver icon indicating copy to clipboard operation
timefold-solver copied to clipboard

jpyinterpreter - LOAD_BUILD_CLASS

Open Christopher-Chianelli opened this issue 1 year ago • 0 comments

Python implement the equivalent of Java's anonymous classes with the LOAD_BUILD_CLASS opcode. It loads the __build_class__ builtin method to the top of the stack. The __build_class__ method has the following signature __build_class__(func: code, name: str, *bases: tuple[type], metaclass: callable = NOOP, **kwargs: dict), where:

  • func is the code object, that when executed, its locals become the (static) fields and (virtual, static and class) methods for the created type.
  • name the name of the created class
  • bases the superclasses of the created class
  • metaclass, it __prepare__ attribute, if present, is called JUST BEFORE the class body is executed (given the name and base classes). prepare returns a dictionary-like object which is used to store the class member definitions during evaluation of the class body. In other words, the class body is evaluated as a function block (just like it is now), except that the local variables dictionary is replaced by the dictionary returned from prepare. This dictionary object can be a regular dictionary or a custom mapping type. Once the class body has finished evaluating, the metaclass will be called (as a callable) with the class dictionary, which is no different from the current metaclass mechanism.
  • kwargs - passed to the metaclass during type instruction (see https://peps.python.org/pep-3115/)

(Source: https://stackoverflow.com/a/1833013)

Note due to the way this is set up, Python will always return a NEW class (that is, if the function is called twice, the classes that got created will be different). To prevent a memory leak, we need to use hidden classes for these classes (https://openjdk.org/jeps/371) ; Hidden classes do have some limitations, namely they cannot be referenced in the bytecode of other classes; so using such classes as type parameter will make them be treated as a generic PythonLikeObject (or their superclass if they have one).

Christopher-Chianelli avatar Mar 04 '24 18:03 Christopher-Chianelli