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

Transformation: try...catch #7

Open
RealyUniqueName opened this issue Sep 18, 2017 · 2 comments
Open

Transformation: try...catch #7

RealyUniqueName opened this issue Sep 18, 2017 · 2 comments

Comments

@RealyUniqueName
Copy link

RealyUniqueName commented Sep 18, 2017

Source

try {
	doSomething();
} catch(e:String) {
	catchString();
} catch(e:Int) {
	catchInt();
} catch(e:Dynamic) {
	catchDynamic();
}

Short legend for next snippet:

  • __ctx__ is a context of state machine (holds current variable values and other data)
  • ${id} is a unique id for current transformation

Preprocessed into:

//This line indicates that next state should be executed inside of a `try...catch` to handle exceptions; 
//and `@state @catchBegin ${id}` is a state which should be executed on exception
__ctx__.enterTry(@state @catchBegin ${id});
//this line finishes current state and advances state machine to specified state
@goto @tryBegin ${id};
//this line indicates that a new state starts here. In the end it will be replaced with `case ${id}:`
@label @tryBegin ${id}
//actual code of `try` block
doSomething();
//this line indicates that exception handling should be turned off now.
__ctx__.leaveTry();
//if we reached this line, it means there were no exceptions, and we should skip `catch` and go to the line after last `catch` block.
@goto @tryCatchEnd ${id}
//this line indicates a start of a state with `catch` blocks
@label @catchBegin ${id}
//each catch is transformed to a type checking of caught exception
//transforming `if`s is a topic for another transformation.
if(Std.is(__ctx__.exception, String)) {
	catchString();
} else if(Std.is(__ctx__.exception, Int)) {
	catchInt();
} else {
	catchDynamic();
	//if no `catch(e:Dynamic)` is defined in user code, then this block is replaced with
	//__ctx__.notCaught()
	//which rethrows exception if current context is not awaited or propagates exception to a caller context otherwise
}
//indicates a start of next state
@label @tryCatchEnd ${id}
//some cleanup if needed
__ctx__.leaveTryCatch();
@nadako
Copy link
Owner

nadako commented Sep 18, 2017

It would be nice to look at what this generates in the end. For example, I think current Kotlin implementation would generate something like this:

// state-machine context
var __state = 0;
var __exceptionState = 2;
var __exception = null;

do {
	try {
		switch (__state) {
			case 0:
				__exceptionState = 1;
				doSomething();
				return;
			case 1:
				__exceptionState = 2;
				var e = __exception;
				if ((e is String)) {
					catchString();
				} else if ((e is Int)) {
					catchInt();
				} else {
					catchDynamic();
				}
				return;
			case 2: // default one: rethrow
				throw __exception;
		}
	} catch (e:Dynamic) {
		if (__exceptionState == 2)
			throw e; // rethrow
		__state = __exceptionState;
		__exception = e;
	}
} while (true);

@RealyUniqueName
Copy link
Author

It's pretty much the same as your snippet, except try..catch is not getenerated, but state machine is executed inside of a try...catch instead when entering corresponding state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants