An Advice Mechanism for Non-local Flow Control Hidehiko Masuhara - - PowerPoint PPT Presentation

an advice mechanism for non local flow control
SMART_READER_LITE
LIVE PREVIEW

An Advice Mechanism for Non-local Flow Control Hidehiko Masuhara - - PowerPoint PPT Presentation

Presented at 15th Workshop on Foundations of Aspect-Oriented Languages (FOAL'16) co-located with Modularity'16, March 15, 2016, Mlaga, Spain An Advice Mechanism for Non-local Flow Control Hidehiko Masuhara Kenta Fujita Tomoyuki Aotani Tokyo


slide-1
SLIDE 1

1

An Advice Mechanism for Non-local Flow Control

Hidehiko Masuhara Kenta Fujita Tomoyuki Aotani Tokyo Tech

Presented at 15th Workshop on Foundations of Aspect-Oriented Languages (FOAL'16) co-located with Modularity'16, March 15, 2016, Málaga, Spain

slide-2
SLIDE 2

Example Scenarios of Non-local Flow Control

2

InitPlugin in your application:

 reads a config. file  downloads a plugin def.  constructs a plugin obj.

Scenarios:

  • 1. no config file  go without plugins
  • 2. network error  start over InitPlugin
  • 3. incompatible plugin  download diff. version

termination retry backtrack

slide-3
SLIDE 3

Non-local Flow Control

  • is a transition of control

between 2 join points e.g., termination, retrying, backtracking

3

slide-4
SLIDE 4

Non-local Flow Control

  • is a transition of control

between 2 join points e.g., termination, retrying, backtracking

4

slide-5
SLIDE 5

"I can write aspects in AspectJ for non-local control flow. Why a new mechanism?" True, but those aspects are not ideal

5

slide-6
SLIDE 6

Termination in AspectJ

6 aspect TerminateLoading { static class NoConfigError extends Error {} Plugin around(): call(* *.loadPlugin(File)) {

try { return proceed(); } catch (NoConfigError e) { return null; }

} before(File f) : call(* *.readFile(File)) && args(f) && if(!f.exists()) {

throw new NoConfigError();

} }

up to where it terminates declare an exception class pointcut to detect a failure throw an exception upon failure catch exception

slide-7
SLIDE 7

Termination in AspectJ

7 aspect TerminateLoading { static class NoConfigError extends Error {} Plugin around(): call(* *.loadPlugin(File)) {

try { return proceed(); } catch (NoConfigError e) { return null; }

} before(File f) : call(* *.readFile(File)) && args(f) && if(!f.exists()) {

throw new NoConfigError();

} }

Problems

  • 2 pieces of advice

for 1 concern

  • Use of exceptions

for pairing

slide-8
SLIDE 8

Problem: 2 pieces of advice

  • clumsy
  • difficult to pass information

8

aspect TerminateLoading { static class NoConfigError extends Error {} Plugin around(): call(* *.loadPlugin(File)) { try { return proceed(); } catch (NoConfigError e) { return null; } } before(File f) : call(* *.readFile(File)) && args(f) && if(!f.exists()) { throw new NoConfigError(); } }

use information there for recovery

create fields in an exception class store information retrieve information

slide-9
SLIDE 9

Problem: use of exceptions

  • indirect
  • requires a unique exception class

for each pair of flow control

  • otherwise, it can

cause accidental catching

9

a c b d

return to a when b happens return to c when d happens

c c t t

slide-10
SLIDE 10

Generic Termination Aspect in AspectJ

10

abstract aspect Termination { class MyException extends Error { ExceptionHandling throwingAspect; Object recorded; MyException(ExceptionHandling throwingAspect, Object recorded) { this.throwingAspect = throwingAspect; this.recorded = recorded; } boolean matches(ExceptionHandling catchingAspect) { return this.throwingAspect == catchingAspect; } } abstract pointcut entry(); abstract pointcut bad(); abstract Object recordInformation(JoinPoint jp); abstract Object recovery(Object recorded); Object around() : entry() { try { return proceed(); } catch (MyException e) { if (e.matches(this)) { return recovery(this.recorded); } else { throw(e); } } } before(): bad() && cflow(entry()) { throw new MyException(this, recordInformation(thisJoinPoint)); } }

slide-11
SLIDE 11

Proposal: Chop&Graft

  • Use pointcut to

specify the extent

  • f cancellation
  • Provide pseudo

functions for resuming/retrying computations

11

advice runs specify by using pct: "chop point" cancel computation return retry graft

slide-12
SLIDE 12

Chop&Graft by Example: chop

  • is a pointcut taking a sub-pointcut

(cf. cflow)

  • terminates computation up to

the matching jp

  • Advice body = a recovery process

12 Plugin around(File f): chop(call(* *.loadPlugin(File))) && call(* *.readFile(File)) && args(f) && if(!f.exists()) { return null; }

slide-13
SLIDE 13

Chop&Graft by Example: retry

  • is a pseudo-function (cf. proceed)
  • restarts the computation

at the chop point

  • can take alternative parameters

13 Plugin around(File f): chop(call(* *.loadPlugin(File))) && call(* *.readFile(File)) && args(f) && if(!f.exists()) { return retry(); }

slide-14
SLIDE 14

Chop&Graft by Example: graft

  • is a pseudo-function (cf. proceed)
  • restarts the cancelled computation up to

chop point

  • Advice can perform computation after graft

14 Plugin around(File f): chop(call(* *.loadPlugin(File))) && call(* *.readFile(File)) && args(f) && if(!f.exists()) { Plugin p = graft(DefaultCnf); p.setVerbose(false); return p; }

graft

inserts computation

slide-15
SLIDE 15

Chop&Graft by Example: backtracking

  • Graft can be called more than once

= going back to the middle of computation

15 Plugin around(String s): chop(call(* *.loadPlugin(File))) && call(* URL.append(String)) && args(_s) { Plugin p = graft(proceed(s)); if (p.isValid()) return p; return graft(proceed(".old")); }

graft

slide-16
SLIDE 16

Implementations

  • 1. By using delimited continuations

[Felleisen'88, Danvy'90]

  • At chop point: (reset (proceed))
  • At advice point: (shift (lambda (graft) body)))

Need multi-prompts for pairing implemented on AspectScheme + Racket

  • 2. By using threads
  • Limitation: can call graft at most once
  • (for now) hand-compiling strategy

16

slide-17
SLIDE 17

Implementation with threads (graft is called)

advice at P1 advice at P2 advice thread advice Body graft(v) return v' return v" proceed start/run GRAFT_END(v') ADVICE_TERM(v") GRAFT(v) return v return v' return v"

run advice body in another thread graft = resume the

  • riginal thread

end of graft = resume the advice body

slide-18
SLIDE 18

Implementation with threads (graft is not called)

advice at P1 advice at P2 advice thread advice Body return v proceed start/run

ADVICE_TERM(v)

throw new NoGraft(v)

return v'

18

end of advice body = throwing an exception catching at chop point

slide-19
SLIDE 19

Related work

  • Aspects for exception handling

[Lippert'00, Colyer'04, Filho'06, Taveira'09, Rebêlo'10]:

  • -- only one side of catching/throwing
  • EJFlow [Cacho'08]
  • -- more precise exception catching
  • Loop, closure, region jps/pointcuts

[Harbulot'06, Bodden'11, Akai'09] --- for "local" flow control

  • Delimited continuations [Felleisen'88, Danvy'90]
  • -- for non-local flow control;

low-level and based on names

19

slide-20
SLIDE 20

Final Remarks

  • Proposed Chop&Graft mechanism

Pointcuts are powerful abstraction to express remote points of control

  • Future work: precise semantics;

full implementation; empirical studies

20