Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • G general-issue-tracker
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 47
    • Issues 47
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Container Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • mumu
  • general-issue-tracker
  • Issues
  • #42
Closed
Open
Issue created Oct 01, 2015 by John Zhang@u5157779Developer

Redesign the undefined function handler API

Created by: wks

Current status

Currently there are two handlers: trap handler and undefined function handler. They are different.

In trap handlers:

  • Thread is temporarily unbound from the stack, and is rebound after trap handling.
  • Stack is unbound and is ready for introspection.
  • OSR (pop frame, push frame) is possible.

In undefined function handlers:

  • Thread is, conceptually, still executing the CALL instruction that calls the undefined function.
  • The stack is in the RUNNING state, not available for introspection or OSR
  • The client must define the function. Then CALL will be tried again. i.e. If the client does not define the function, it will loop forever.

This asymmetry is complicating the interface.

  1. The undefined function handling API leaves no room for errors in loading the bundle. If, in Java, the client puts a stub for an unloaded method, and there is an error when loading the class, then the client has no other things to do than "defining" the method as "doing nothing but throwing an exception". This isn't very nice.
  2. It leaves the stack and the thread in a strange state: they cannot continue, but still "RUNNING".
  3. Introspection and OSR are impossible.

Proposed change

I propose unifying the two interfaces.

Let undefined functions behave like:

.funcdef @undefined_function VERSION noversion <sig> (a1 a2 a3 ...) {
  %entry:
    TRAP <void> KEEPALIVE (a1 a2 a3...)
    undefined behaviour after TRAP
}

That is, an undefined function behaves like executing a trap with all parameters as keep-alive variables.

Add an extra API call:

MuID (*cur_func)(MuCtx *ctx, MuStackRefValue stack, int frame)

It returns the ID of the function of the current frame. It works even if the function is not defined. Return 0 if the frame is native.

Modify the cur_func_ver API call: It returns 0 when the frame is a frame without version (undefined function).

So a client can identify an undefined function by "cur_func != 0 && cur_func_ver == 0". FYI:

  • cur_func != 0 && cur_func_ver != 0: a defined Mu function
  • cur_func != 0 && cur_func_ver == 0: an undefiend Mu function
  • cur_func == 0 && cur_func_ver == 0: native frame
  • cur_func == 0 && cur_func_ver != 0: impossible

Modify the cur_inst API call: It returns 0 if the frame is just created (before the first instruction), is native, or if the function is not defined.

Modify the dump_keepalives API call: It dumps keep-alive variables for OSR point instructions, or the arguments to an undefined function. Cannot be used on native frames or a just-created frame.

The pop_frame and the push_frame API behave like before. Specifically to undefined functions, popping an undefined function frame reveals its caller to the top of the stack. After loading a bundle that defines the function, a push_frame can re-creates the callee frame, but this time the callee is defined. The client can also choose not to rebind to the same stack, but swap away. Or just throw an exception (probably ClassNotFoundException) to the caller without defining the callee.

About the NEWSTACK instruction

Creation of the stack will be successful, but it will trap when executing the undefined function after binding the stack to a thread.

Assignee
Assign to
Time tracking