►
From YouTube: Is it safe to add fluid scopes to an ocap language? (AsyncContext Security Review: Part 3)
Description
Discussion at friam led by Mark Miller.
This discussion is motivated by the proposal to add so-called "AsyncContext" to JavaScript. The question is how does this affect the safety of Hardened JS, the use of JavaScript as an object-capability language.
The discussion makes use of the examples at https://github.com/endojs/endo/pull/1424 . This PR will continue to evolve as our understanding does.
friam is a group of object-capability experts who have been meeting continually since the mid 1990s. This discussion examined the larger question of the safety of these mechanisms if added to ocap languages in general.
A
Okay,
we're
recording
and
I
should
proceed.
Yep.
Okay,
very,
very
good.
Okay
today
is
January
13th
I'm,
presenting
about
async
context,
The
tc39,
Proposal
presenting
to
the
fry
am
group.
A
A
Today
it
is
a
form
of
fluid
scoping
and
it
necessarily
to
achieve
its
functionality,
breaks
the
existing
object
capability
rules,
but
it
was
written
to
meet
all
of
the
object
capability
safety
concerns,
which
raises
a
terrifying
question,
which
is
the
it's
a
terrifying
question
for
us,
which
is
we've
spent
decades
coming
to
appreciate
these
safety
benefits
the
security,
the
security
benefits,
which
is
safety,
Plus
expressiveness
benefits
of
living
within
the
object
capability
rules.
A
So
if
you
weaken
the
rules,
it's
very
hard
to
evaluate
whether
you've
lost
anything
that
you
really
care
about,
and
that's
exactly
what
the
question
that
I
want
us
to
be
discussing
today
and
I
will
be
making
an
argument
that,
in
fact,
with
some
explicit
qualifications
which
I'll
be
explaining,
that
we
actually
don't
lose
anything
and
that
we
gain
exactly
the
expressiveness.
A
That
is
the
reason
why
Justin
has
been
proposing
this
okay,
so
the
best
way
to
understand
what.
A
Oh
I'm,
sorry
I
I,
don't
know.
Oh
I
can
yes,
Kevin
yeah.
A
Okay,
this
piece
of
hardened
JavaScript
code
represents
the
simplest
expression
of
Justin's
API
in
Hardware
JavaScript,
without
breaking
any
rules
and
because
it's
not
breaking
any
rules,
it's
also
missing
the
critical
part
of
Justin's
desired
expressiveness,
but
this
does
achieve.
This
does
provide
fluid
scoping.
So
let
me
explain
what
it's
doing
the.
A
I'm
going
to
start
actually
I'm
going
to
start
before,
I
explain
this
code,
who
must
I'm
going
to
start
with
a
bit
of
History
in
the
history
of
lisp
languages,
starting
with
McCarthy's
lisp
in
the
late
1950s
lisps
were
historically
dynamically
scoped
all
modern
languages,
including
modern
lists,
like
scheme,
are
lexically
scoped
the
in.
A
In
both
cases
you
can,
you
can
think
of
the
scoping
as
binding
a
variable
to
a
value
within
an
interval
where
the
intervals
nest,
so
that
the
shadowing
of
a
variable
is
the
rebinding
of
the
same
variable
in
a
nested
interval.
A
So
in
a
lexical
scope,
language,
which
is
you
know
what
all
modern
programmers
Now
understand,
the
intervals
are
textual
intervals
in
JavaScript,
considering
only
blocks
and
const.
The
scope
interval
begins
with
an
open,
curly
and
ends
with
a
close
curly.
A
So
a
const
declaration
between
the
curlies
brings
that
variable
name
into
scope
in
that
textual
interval,
except
for
any
nested
text
text
textual
intervals,
any
nested
blocks
in
which
the
same
variable
is
redefined
with
a
different
binding.
So
any
use
occurrence
of
a
variable
to
understand
the
use
occurrence.
You
have
to
figure
out
what
the
corresponding
defining
occurrence
is
and
then
that
defining
occurrence
I'm
only
talking
about
const,
not
let
that
defining
occurrence
binds
that
variable
name
to
a
value
in
that
textual
interval.
A
Dynamic
scoping
is
yeah
bill.
D
A
So
in
lexical,
scoping
I
mean
the
same
name
and
in
Dynamic,
scoping
I
also
mean
the
same
name,
but
in
fluid
scoping
I
mean
something
else
which
I
will
be
getting
to
in
a
moment.
Okay,
so
thank.
D
A
So
in
Dynamic
scoping
the
intervals
were
not
texturable,
we're
not
static.
The
intervals
were
temporal,
so
the
when
you
had
a
use
occurrence
of
a
variable.
What
you
did
is
what
what
the
lisp
implementation
did.
Is
it
actually
looked
backward
up.
The
call
stack
to
a
caller
on
the
call
stack
that
bound
that
variable
name
to
a
different
to
a
value
so,
and
there
were
nested
intervals
because
the
dynamic
extent,
the
temporal
extent
of
a
function
call
is,
is
temporarily
nested
by
call
return.
A
Now
the
dynamic
scoping
is
as
unstructured
as
it
sounds
like,
and
you
got
into
all
of
the
same
trouble
that
by
modern
eyeballs.
You
would
expect
to
get
into
with
something
that
was
that
anti-modular
so
scheme
programmers,
starting
with
a
purely
lexically
sculpt
language,
but
trying
to
recover
some
of
the
expressive.
Expressivity
benefits
they
associated
with
Dynamic
scoping
invented
fluid
scoping,
but
they
did
that
within
object,
capability
rules
and
the
difference
between
Dynamic
scoping
and
fluid
scoping.
A
Is
that
the
the
thing
that
we
think
of
as
a
fluid
variable
is
no
longer
a
variable
name?
It
is
now
a
first
class
object
that
you
either
have
a
capability
to
that
object
or
you
do
not.
A
So
in
the
case
of
Justin's
proposal,
just
I
should
say:
Justin's
code
is
expressed
in
more
traditional
JavaScript
with
classes
and
I'm
I've
Rewritten
Justin's
API
using
Doug
Crawford's
objects
as
closure,
syntax
and
Rewritten
it
in
the
style
in
which
we
favor
for
hardened
JavaScript.
That's
maximally
friendly
for
understanding,
object,
capability,
safety
issues,
but
the
but
the
the
transition
from
classes
to
objects,
as
closures
is
just
a
a
Clarity
issue.
A
It
doesn't
change
anything
fundamentally
here,
so
there
is
a
outer
maker
that
is
assumed
to
be
ambiently
available
and
is
therefore
assumed
to
be
immutable
and
Powerless
and
by
this
definition,
in
fact,
is
immutable
in
powerless.
So
this
maker
make
async
context,
creates
and
returns
a
new
object,
which
is
an.
A
Context
instance
represents
a
distinct
fluid
variable
and
in
order
to
read
the
so
so
the
idea
is
that
the
variable
represented
by
each
instance,
has
a
binding
over
a
temp,
a
temporal
context
where
the
temporal
context
is
the
limited
by
the
time
between
when
a
function
a
called
function
starts
executing
and
when
the
called
function
completes,
irrespective
of
whether
it
completes
with
a
return,
you
know
a
normal
return
or
it
completes
with
a
throne
exception.
A
So
to
read
the
current
binding
of
the
fluid
variable.
One
says
to
the
synced
context:
instance
invokes
its
get
method,
and
that
returns
the
current
state
of
this
encapsulated
State
variable
and
to
bind
it
The
Binding
operation.
Is
this
run
method
on
the
I'm
just
going
to
call
the
fluid
con?
The
the
sync
context,
instances
I'm
just
going
to
refer
to
them
from
now
on,
as
the
fluid
variable,
where
we
under
all
understand
that
the
variable
is
a
first
class
object.
A
So,
aside
from
the
fluid
binding
Dynamics
aside
from
that
calling
run,
you're
calling
the
fluid
variable
dot
rung
of
value,
comma
callback,
comma
args
is
just
like
calling
the
callback
with
the
arguments
spread
out.
The
only
difference
between
the
two
is
what
it's
doing
with
regard
to
The
Binding
of
the
of
the
fluid
variable
context.
So,
what's
going
on
here
in
the
shallow
binding
implementation
of
fluid
scoping
is
to
rebind
the
fluid
variable
over
a
temporal
context.
You
stack
up
the
previous
current
binding
into
this
pred
variable
prev.
A
Then
you
rebind
the
state
variable
to
to
the
to
the
current
value
that
you
want
over
the
new
temporal
the
new
nested
temporal
interval.
You
do
the
function,
call
you!
Whatever
the
outcome
of
the
function
call.
Is
you
make
that
the
outcome
of
the
Run,
but
you
enclose
it
in
a
cry?
Finally,
so
that
before
propagating
that
outcome,
your
restore
state
to
what
it
to
what
it
was
outside
the
nested
temporal
interval
and
we've
all
written
code
like
this,
including
when
writing
code
in
object
capability
languages.
A
F
Now
so
is,
is
callback
assumed
to
have
access
to
this
run
facet
as
well?
Yes,.
A
Since
I
started
it,
since
you
asked
I'll,
start
I'll
start
by
answering
you,
but
then
let's
go
through
the
entire
queue
before
I
come
back
to
the
presentation,
so
you
asked
exactly
the
right
question,
which
is:
it
is
not
assumed.
It
is
assumed
that
it
might
have
access
to
it.
So
that's
the
critical
transition
from
Dynamic
scoping
to
fluid
scoping,
which
is
whether
you
have
access
to
the
to
the
instance
whether
you
have
access
to
the
fluid
variable
object
itself
is
simply
governed
by
object
capability
rules.
A
However,
the
the
the
interesting
thing
is
that
the
Callback
itself
might
not
have
access,
but
the
Callback
might
in
turn
call
something
that
does
have
access.
So
in
that
case,
what's
happening
is
the
Callback
the
Callback
object.
The
Callback
function
cannot
access
the
fluid
variable
binding,
but
something
that
it
calls
can
access
the
current
fluid
variable
binding
because
it
has
access
to
the
fluid
variable
object.
A
C
Yeah
I
just
wanted
to
observe
that
this
is
not.
This
is
not
strange
in
that,
like
things
like,
this
are
an
extremely
common
pattern,
for
you
know
very
sorts
of
you
know,
logging
or
or
task
execution
contexts
kind
of
things,
and
in
particular
it
is
often
the
case
that
the
state
cell
is
actually
a
thread
local
variable,
which
makes
it
so
that
in
that
case,
this
this
this
one
object,
has
a
distinct
state
for
every
thread
that
it
might
be
used
in,
which
is
slightly
different.
But
you
can
also
Imagine.
A
And
in
fact,
where
Justin
and
the
and
and
that
team
started,
was
the
Justin
correct
me
if
this
is
wrong
but
started
with
thread
local
variables
as
the
inspiration
for
for
this
abstraction.
G
Yeah
so
node
has
its
own
implementation.
That's
very,
very
similar,
like
almost
exactly
the
same
thing
as
a
thread:
local
variable.
We
have
a
minimized
version.
That
node
did
that
eliminates
some
of
the
bugs
you
can
have
with
a
thread
local,
it's
not
possible
to
leak
a
value
with
this
current
design,
whereas
with
a
thread
local,
it
is
absolutely
possible
and
it
happens
constantly.
G
H
Yeah
so
I
I
assume
the
access
to
this.
To
this
fluid
variable
could
be
through
static,
scoping,
lexical,
scoping
somewhere
else,
yes
or
or
in
fact
it
could
be
passed
as
one
of
the
arguments
to
the
Callback.
Is
that
correct
that.
A
H
Way
of
sharing
bindings,
yeah
yeah.
A
B
A
Okay,
so
so
none
of
this
is
surprising
so
far.
Let
me
now
get
to
the
the
additional
primitive
that
makes
this
different.
It
makes
this
something
that
is
scary
from
an
object
capability
perspective,
so.
G
A
Yeah
so
so
I'm
going
to
show
five,
but
but
in
order
to
show
five,
let
me
make
the
point
make
a
point
by
showing
one
first,
so
this
code
is
essentially
the
code
from
Justin's
slide,
six
and
I,
and
you
can
see
it's
written
in
class
file,
but
it's
but
other
than
you
know,
cosmetic
things
like
class
versus
objects,
disclosure.
This
is
this.
A
A
The
fact
that
it
closes
over
mutable
State
Breaks,
the
Rules,
but
the
equivalence
to
the
code
that
we
were
showing
shows
that,
even
though
it's
breaking
the
rules,
it's
it
has
exactly
the
semantics
of
something
that
by
construction
we
know
to
be
safe,
then
the
the
next
one
is
that
going
from
zero
to
five.
A
This
reflects
Justin's
slide,
11
plus
slide
13.,
in
which
this
is
exactly
the
same
as
the
as
the
class
code
that
we
were
just
seeing,
except
for
the
renaming
of
sync
context
to
async
context
and
then
just
in
slide
13
adds
this
wrap
method,
which
is
the
thing
that
creates
a
semantics
that
cannot
be
implemented
directly
within
the
rules
of
Pardon
JavaScript,
so
the
and
and
this
rap
method
is
making
use
of
this
storage
variable.
A
So
let
me
talk
through
conceptually,
what's
going
on
here,
without
getting
too
deeply
into
the
specifics
of
How
It's
implemented,
because
I
want
to
shift
to
an
a
the
implementation.
I
wrote
in
the
last
hour
that
I
think
makes
the
semantics
clearer
and
makes
the
case
for
safety
clear.
A
So
the
with
these
temporal
intervals,
there's
two
Dimensions
that
we
need
to
be
considered
in
the
two
yeah
two
Dimensions
that
we
need
to
concern
about.
One
dimension
is
the
temporal
Dimension
and
the
other
dimension
is
the
fluid
variable
identity,
because
the
binding
to
a
value
is
The.
Binding
of
a
fluid
variable
object
over
an
interval
of
time,
so
the
the
value
binding
is
looked
up
in
a
point
in
both
of
those
dimensions.
A
The
Global
variable
here
is
the
thing:
that's
being
changed
according
to
the
nested
intervals
of
time,
but
this
is
shared
among
all
of
the
fluid
variable
objects.
All
of
the
instances
of
async
context
are
sharing
the
same:
a
storage
variant,
the
same
sharing
the
same
Global
Storage
variable.
So
this
is
only
varying
with
the
temporal
dimension.
A
So
then,
what
rap
does
is
it's
doing
the
in
the
same
way
that
lexical
scoping,
plus
closure
capture
is
the
thing
that
makes
lexical
scoping
so
powerful
before
scheme
languages
like
algol
and
Pascal,
had
lexical
scoping
and
had
downward
closures,
but
they
did
not
have
closures
that
could
outlive
the
call
frame
that
they
were
created
and
therefore
did
not
have
the
expressiveness
of
objects.
A
It's
with
scheme
and
the
dependence
of
the
the
descendants
of
skin
that
a
function
created
an
electrical
scope
could
Outlast
the
context
it
was
created
in
that's
called,
so
we
can
think
of
that
as
closure
capture
of
lexical
bindings.
What
rap
is
doing
is
an
analogous
closure
capture
of
temporal
bindings.
D
Bill
I
guess
word
as
a
historical
note.
When
we
were
developing
Caicos
in
the
very
early
days,
we
were
using
alcohol
68
as
a
design
language,
and
we
very
quickly
decided
that
in
algol
68
activation
records
were
not
allocated
on
a
stack
they
were
allocated
to
the
Heap
and
that
made
the
problems
go
away
and
since
we
weren't
trying
to
run
the
code,
it
wasn't
a
problem.
A
Yeah
I've
actually
read
believe
it
or
not.
I've
actually
read
the
algol
68
spec,
or
at
least
the
relevant
parts
of
it
and
I
remember
being
confused
about
whether
in
the
actual
language
as
specified,
none
of
the
language
is
implemented
when
the
language
is
specified.
Whether
that
was
the
case,
because
the
language
was
allegedly
memory
safe,.
D
Or
there
was
a
something
in
the
report
that
said,
basically,
you
had
to
do
it
on
a
stack.
It
was
very
obscure
and
it
was
only
a
sentence
or
two,
but.
A
D
That
is
illegal
and
I'm,
not
sure
how
how
they
made
those
references
turned
into
something
that
you
could.
That
would
cause
us
an
exception.
Okay,.
A
In
Pascal,
they
were
made
illegal
by
a
textual
static
rule,
which
is
that
the
variables
that
could
hold
on
to
nested
functions
were
not
first
class
and
could
only
be
passed
downwards.
A
Okay,
the
so
in
any
case,
so
let's
take
a
look
so
so,
just
given
the
understanding
that
storage
represents
the
nested
temporal
context,
that's
shared
across
all
fluid
variables.
We
can
Now
understand
how
rap
does
a
temporal
closure
capture
when
you
call
rap
with
a
function.
A
A
I'm
sorry,
it
restores
that
it's
it
restores
the
temporal
context
over
here
on
line.
43
calls
the
function
with
the
restored
attempt
with
with
having
restored
the
temporal
context
in
which,
from
which
rap
was
called,
and
then
on.
Exit
from
this
nested
interval
restores
whatever
the
temporal
context
was
before
the
wrapper
function
was
called.
A
A
But
what
it's
manipulating
is
the
is
is
all
of
the
fluid
bindings
together
in
aggregate
that
the
user
of
rap
does
not
have
access
to
so
over.
Here
we
mentioned
that
the
Callback
might
not
have
access
to
a
given
fluid
binding
and
if
it
doesn't
have
access
to
the
given
fluid
sorry
given
fluid
variable,
it
doesn't
have
access
to
the
variable.
It
can
neither
perceive
its
current
value,
nor
can
it
rebind
it
on
a
further
nested
context
with
rap.
A
It
is
still
the
case
that
the
Callback
cannot
perceive
it,
but
it
is
the
case
that
a
callback
by
using
rap,
which
is
assumed
to
be
pervasively
available,
can
rebind
it
without
rebind
all
of
the
fluid
variable
behind
things
without
knowing
about
any
of
the
fluid
variables
and
to
demonstrate
that
I
think
probably
the
next
most
informative
thing
to
look
at
is
the
attack.
F
C
Know
the
very
the
global
variable
is,
you
know
equivalent
to
you
know
it's
a
bundling
together
all
of
these
individual
set
and
reset
fluent
variables.
However,
by
introducing
rap,
you
have
now
made
it
the
case
that
this
particular
manipulation,
or
that
this
particular
choice
of
of
a
continuity
of
scope
is
now
shared
among
all
variables.
So
this
implementation
in
critical
is
now
no
longer
equivalent
to
the
set
and
reset
implementation,
and
this
is
not
necessarily
bad,
but
this
is
something
that
any
user
needs
to
be
aware
of.
That's.
A
Exactly
correct,
I
I
endorse
every
single
word
of
what
you
just
said.
It
might
or
might
not
be
bad.
It's
not
necessarily
bad.
That's
the
question
that
I'm
bringing
to
the
group
with
an
argument
that
it's
not
bad,
but
it
is
certainly
not
obviously
not
bad.
A
It
is
breaking
the
ocap
rules,
it's
doing
it
in
an
irreducible
manner
it
there.
You
cannot
rewrite
this
as
equivalent
code
within
the
ocap
rules
and
a
Defender.
Somebody
writing
defensive
code
that
does
not
know
about
this
can
be
attacked
in
order
to
write
code
that
that
is
successfully
defensive.
C
A
A
G
I
wanted
to
clarify
one
important
part
here:
the
attack
is
going
to
be
demonstrated
here
and
the
defense
that
you
have
to
perform
in
the
defense,
particularly
you
have
to
know
the
async
context,
is
a
thing
that
exists.
You
don't
have
to
know
about
any
individual
async
context.
Instance
right.
You
do
not
have
to
have
access
to
all
async
contacts.
You
just
have
to
know.
The
async
context
exists
and
use
rap
defensively.
A
Yeah
that
that
that's
exactly
correct
it's
it's
like
we
have
changed
the
ground
rules
from
ocap
language,
a
to
ocap
language
B
and
if
you're
in
ocap
language,
B
and
your
attacker
is
in
ocap
language
B.
Then,
when
you
write
defensive
code
in
ocap
language
B,
if
you
do
it,
knowing
that
you're
an
ocap
language
B,
then
you
can
be
safe
and
you
can
be
safe
by
ocap
for
ocap
concerns,
which
is
why
I
would
argue
that
ocap
language
B
is
an
ocap
language.
A
But
the
attack
that
I'm
about
to
show
is
an
attack
by
on
Carol,
where
Carol
is
writing
defensive
code
for
ocap
language,
a
while
Carol's
attackers,
while
Carol
and
her
attackers
are
actually
running.
You
know
cap
language
B,
so
the
attackers
are
only
succeeding
at
the
attack
if
Carol
doesn't
know
that
she's
actually
running
an
ocap
language
B
and
is
not
succeeding
at
doing
what
she
needs
to
defend
herself
in
her
cat
language
being
and
that's
all
very
obscure
and
will
become
clear
in
a
moment
as
I
show
the
attack
code.
A
G
Then
a
test
attack
is
the
one
that's
successful.
Okay,
this
is
async,
which
is
considerably
more
difficult
to
understand,
because
it's
promise
based.
A
So
Alice
and
Bob
are
supposedly
are
both
created
by
Carol
from
Alice
and
Bob
source
code
assumed
created
in
separate
compartments
such
that
they
should
have.
They
should
be
completely
isolated
from
each
other,
except
by
Communications
channels
that
Carol
controls
and
that,
but
Alice
and
Bob
are
in
cahoots
they're,
trying
to
communicate
in
ways
that
subverts
Carol's
safety
intentions,
Mike.
F
What
is
the
impediment
to
implementing
the
asynchronous
version
using
lexical
scoping,
as
opposed
to
a
global
variable.
A
A
And,
however,
the
use
of
rap
is
capturing
all
of
the
bindings
of
a
given
that
that
were
present
in
the
temporal
context
at
the
Time
Rap
was
called
and
restores
all
of
those
bindings
during
the
temporal
context
in
which
the
the
the
wrapper
function
is
called
and
there's
under
the
assumption
that
rap
has
no
access
to
mutable
state
there's
and
that
and
that
the
the
the
maker
of
fluid
variables
likewise
has
no
access
to
a
mutable
State.
A
F
A
F
A
If,
if,
if,
if
all
rap
did
is
it
is,
if
rap
took
as
an
additional
argument,
the
specific
fluid
variables
that
we
want,
whose
bindings
we
wanted
the
closure
to
capture,
and
then
it
rebound
only
those
during
the
call
to
the
wrapped
function,
then
again,
there
would
be
no
magic
and
that
actually
anticipates
the
new
rewrite
that
I
did
in
the
hour
before
the
call,
but
but
yeah
that's.
That
is.
That
is
the
case.
The
the
thing
that
makes
rap
magic
is
it's
re.
F
G
So
imagine
you
have
you
have
a
context
and
then
you're
calling
some
callback
that
callback
then
called
other
code
in
order
for
wrapping
to
properly
work
the
I'm.
Sorry.
In
order
for
this
to
properly
work,
you
should
not
need
to
pass
the
context
down
from
your
callback
to
the
other
callback.
The
other
callback
should
be
able
to
access
the
value
immediately
implicitly,
because
it
has
a
reference
to
the
context
instance.
It
should
be
able
to
read
the
current
value
of
the
context
instance
and
so
there's
a
context
that
run
your
code.
G
Other
code.
Other
code
should
be
able
to
access
the
value
that
I
stored
in
the
top
level
run
if
we
were
to
have
a
wrap
here
which
is
going
to
be
necessary
in
order
to
introduce
asynchronicity
into
our
into
our
code,
we're
going
to
pause
at
some
point
between
the
run
and
the
other
code
that
has
access
to
the
current
value
via
access
to
the
async
context.
G
C
A
Yep
yeah,
so
so
wrap
is
actually
more
powerful.
Rap
as
exposed
is
a
slightly
more
powerful
than
wrap,
as
used
only
by
the
Transformer.
So
the
turn
Spawner
in
JavaScript
is
the
internal,
then
method
which
is
exposed
as
promised.prototype
as
the
sort
of
the
internal
then
function
whose
functionality
is
exposed
as
promise.prototype.net,
then
instance,
method
on
all
promises.
It
also
exposed
through
the
await
syntax.
A
If
you
don't
know
enough
JavaScript
to
know
what
those
are
just
think
of
this
as
the
turn
score,
so
the
then
method,
the
the
then
operation,
the
current
spawner
takes
callbacks
as
arguments
and
then
later,
when
the
promise
is
settled,
it
calls
one
of
those
callbacks
and
the
implicit
use
of
rap
to
propagate
fluid
contexts
across
terms
what
it
does
is
it
internally
calls
wrap
on
the
callbacks
at
the
time
that
then,
is
called
at
the
time
that
the
callbacks
are
registered,
so
not
at
the
time
that
the
turn
is
spawned.
A
This
is
actually
important,
but
at
the
time
that
the
callbacks
are
registered
by
using
then
then
at
some
later
time
the
Callback
is
spawned
and
a
call
back
to
spawned
by
a
top
level,
call
to
the
to
the
wrapper
function,
the
wrapped
callback
at
the
beginning
of
the
new
turn.
A
So
that
restores
the
temporal
context.
The
the
aggregate
set
of
all
fluid
Bindings
that
were
in
Force
at
the
moment
that
the
Callback
was
registered.
A
Okay,
so
getting
back
to
our
attack
here,
let's
not
read
the
Alice
and
Bob's
source
code
itself.
Yet,
let's,
let's
talk
about
the
view?
The
view
from
the
defender
with
the
defender
Carol
was
trying
to
accomplish.
So
this
is
source
code
that
out
that
Carol
is
going
to
instantiate
in
one
compartment.
Bob
is
Source,
make
Bob
the
source
code
that
Carol
is
going
to
instantiate
in
a
separate
compartment.
I
should
actually
go
ahead
and
rewrite
this,
since
it's
all
written
in
heart
and
JavaScript
anyway.
E
A
You
know
contact
I'm
about
to
Yes
and
then
okay,
very,
very
okay,
so
yeah.
So
there
is
all
of
Carol,
so
Carol
so
make
Carol
is
going
to
be
used
in
our
test
down
here
make
Carol
is
parameterized
with
a
secret
that
she's
going
to
pass
to
Alice
so
make
Carol
to
make.
You
know,
she's
going
to
make
and
return.
This
carol
object
down
here.
A
That
has
two
methods,
law
get
log
and
get
secret,
and
so
during
so
during
make
Harold
she
she
makes
a
new
Alice
in
a
fresh
compartment
passing
the
secret
in
question
to
Alice.
A
A
In
fact,
the
secret
of
these
tests
is
only
the
variables
zero
and
one
we're
not
trying
to
defend
against
possible
other
values
for
the
sequel,
the
and
then
we
Carol
makes
a
fresh
Bob
and
a
separate
compartment,
and
then
she
she's,
assuming
that
the
Alice
object,
has
methods
for
Bob
and
from
Bob
and
that
the
Bob
object
has
methods
from
Alice
and
for
Alice
and
gets
Secret,
and
let's
not
worry
about
what
those
methods
are.
A
A
The
the
these
are,
the
the
four
four
Bob
from
Alice
and
for
Alice
from
Bob
are
the
mediating
methods
or
the
the
the
functions
that
any
communication.
As
far
as
Carol
knows,
any
communication
has
to
go
through
these
functions
and
these
functions
notice
that
they
have
no
argument
and
their
curly
bracket
with
no
return.
So
they
have
no
argue,
no
argument,
no
arguments
and
no
return
value.
They're.
A
Only
communicating
by
virtue
of
being
called
at
all-
and
they
they
add
to
this
log,
variable
the
record
of
when
the
when
the
call
started
to
the
counterparty
and
when
the
call
ended
and
likewise
in
the
other
direction,
and
then
Carol
herself
is
an
odd.
Is
you
know
having
having
done
all
of
this
introduction,
then
the
Carol
object.
A
You
can
ask
it.
Okay,
give
me
the
log,
that's
the
complete
record
of
this
interaction
between
Alice
and
Bob,
and
also
ask
Bob
what
he
thinks
the
secret
is.
A
So
the
challenge
for
Alice
and
Bob
is
for
Alice
to
communicate
the
secret
to
bomb
without
Carol
being
able
to
tell
that
there
was
anything
about
the
communication
between
Alice
and
Bob.
That
was
dependent
on
the
secret,
and
so
here
is
the
demonstration
of
the
successful
attack
successful
under
the
assumptions
that
I
stated,
which
is
over
here
we
make
Carol.
A
We
make
a
Carol
with
the
you
with
the
secret
zero.
We
then
ask
Carol
to
ask
Bob
what
the
secret
is,
that
Bob
knows:
Bob
successfully
reports
that
it's
zero
and
then
we
ask
Carol.
What's
the
log
of
interaction
between
Alice
and
Bob,
and
it's
exactly
and
the
log
is
exactly
this
golden
log,
then
we
do
exactly
the
same
thing,
except
that
the
secret
that
we're
asking
Carol
to
give
to
Alice
is
one.
A
We
verify
that
the
secret
that
Carol
obtains
for
Bob
is
one,
but
the
log
of
interaction
between
the
two
is
exactly
the
same
thing
and
therefore
Alice
and
Bob
have
succeeded
at
communicating
the
secret
between
them
by
making
a
series
of
Carol
mediated
calls
that
seem
independent
of
the
secret
I.
Don't
see
any
hands
raised,
but
are
there
any
questions
at
this
point?
Is
this
clear.
A
A
A
A
So
the.
A
So
once
again,
we
assume
that
okay,
let's,
let's
take
a
look
now
more
closely
at
the
protocol.
We
assume
that
Alice
has
a
four
bot
for
Bob
method
that
that
Carol
assumes
accurately
in
this
case
is
a
no
argument
method
with
no
return
result.
A
So
there's
nothing
communicated
by
arguments
and
there's
nothing
communicated
by
the
return
there.
Let's
also
I
should
have
I
should
have
done
code
to
do
this
explicitly.
But
let
me
just
State:
there
is
no
use
of
the
exceptional
throw
channel
the
difference
between
a
successful
return
and
throw
no
use
of
that
anywhere
in
this
code.
That
would
have
been
a
means
to
communicate
an
additional
bit
and
that
that
that
additional
bit
potential
communication
is
not
being
used
here.
A
A
Mcbob
has
a
four
Alice
method
that
has
no
arguments
and
no
results
has
a
from
Alice
method
that
takes
a
callback
and
and
from
Alice
should
assume
that
the
Callback
is
going
to
be
provided
by
Carol
and
will
be
a
function.
That
has
no
arguments
and
no
results
so
should
only
be
called
under.
Those
assumptions
is
all
that
clear.
A
Okay,
so
now
here's
the
Carol
mediated
connectivity,
the
means
by
which
Carol
introduces
Alice
and
Bob
only
as
mediated
by
Carol,
and
you
can
think
of
these
two
functions
as
being
a
degenerate
membrane,
so
in
the
same
sense
that
a
membrane
prevents
any
connectivity
other
than
through
the
membrane.
This
is
a
degenerate
membrane,
since
we're
from
for
Bob
from
Alice
is
essentially
a
proxy
for
Alice's,
for
Bob
method
and
and
and
Carol
provides
that
proxy
to
Bob,
using
the
Bob
from
Alice
method.
A
Likewise,
for
Alice
from
Bob
is
a
proxy
for
Bob's
for
Alice
method
and
Carol
provides
that
proxy
to
Alice
by
calling
Alice's
from
Bob
method,
because
the
proxies
have
no
arguments
and
no
results.
This
can
be
a
complete
membrane
in
the
sense
of
isolation,
because
without
passing
any
arguments
or
any
results,
there's
nothing
else
that
ever
needs
to
be
wrapped.
E
A
J
D
I
think
that
the
question
right-
that's
most
interesting
me
is
what
does
Carol
have
to
do
to
protect
herself
against
this
attack,
and
can
she
do
it
in
a
in
the
traditional
language.
A
So
so
the
answer
is
so
so:
Justin
wrote
the
answers
to
that
which
I
will
be
showing
momentarily
okay,
all
right,
but
to
to
to
give
you
the
high
level
answer
on
that
is.
It
is
easy
for
Carol
to
defend
herself
there's
two
there's
two
senses.
A
There's
two
coherent
kinds
of
Defense
Justin
wrote
both
of
them,
but
the
defense
must
use
the
the
new
magic.
Must
you.
The
defense
must
use
async
context,
which
are
the
same
Primitives
used
by
the
attacker,
so
Carol
can
defend
herself
only
by
being
written
by
by
knowing
that
she's
running
an
object
in
the
enhanced
object
capability
language
and
by
using
the
New
Primitives
that
are
made
available
in
this
new
object
capability.
Language.
A
So
so
that
I
mean
that's,
that's
the
the
interesting
thing
here
is
that
if
Carol
thinks
she's
running
in
the
unenhanced
language
or
what
the
hardened
JavaScript
without
fluid
scoping
and
Alice
and
Bob
are,
are
written
not.
E
A
She
was
running
in
when
she
wrote
the
defensive
code.
Kevin.
C
Yeah,
so
I
have
two
thoughts
like
one.
Is
that,
like
the
a
subjective
argument,
this
is,
in
fact
a
terrible
idea.
Is
that
is
just
our
experience
in
the
kaha
world,
where
we
had,
we
wrote
had
all
sorts
of
you
know,
troubles
and
disasters
from
you
know.
Oh,
it
turns
out
that
the
browser
has
this
magic
feature
that
we
didn't
know
about
yeah.
C
My
second
observation,
which
is
more
in
the
direction
of
this,
is
actually
okay
is
just
that
I
think
in
general,
it's
like
a
really
fragile
thing
to
be
trying
to
protect
some
information
against
wall
banging
it
out
and
I
don't
mean
that
in
the
sense
of
like
you
know,
timing
side
channels,
but
in
the
sense
of
like
what,
like,
like
you
You,
observe
that
this
code
is
not
deal
considering,
exceptions
and
exceptions,
or
rather
the
possibility
of
failure,
are,
can
be
a
way
to
bang
out
a
message.
C
A
I,
I
frankly,
did
not
understand
all
of
that,
so
the
one,
but
let
me
start
by
answering
the
part
that
I
did
understand,
which
is
that
the
the
issue
of
whether
it
is
a
good
idea
and
and
the
fact
that
you
are
able
to
make
arguments
both
ways
is
actually
kind
of
indicative
of.
Why
I'm
taking
it
to
this
group
and
why
I
find
the
whole
question
scary
and
because
I
can
I
can
argue
it
both
ways
in
my
head
as
well.
A
The
the
exception
channel
is
actually
answered
here,
which
is
the
if
the
exception
Channel
were
made
use
of
by
either
party.
We
would
not
get
this
long.
This
log
shows
balanced,
beginning
of
calls
and
end
of
calls
if
an
exception
had
been
thrown
through
Carol.
We
wouldn't
see
this
balance.
We'd
see
it
dangling
open
here,
because
the
closes
didn't
do.
I
didn't
do
this
with
on
purpose,
but
but
fortuitously
I
did
not
use
a
try.
A
Finally,
around
the
call
around
these
nested
calls
so
that
the
law,
the
closed
log,
is
not
being
done
in
a
finally,
it's
just
being
done
afterwards
and
would
have
been
skipped
if
either
of
these
things
had
thrown.
So
we
actually
know
from
the
golden
that
that
it
hasn't
been
made
use
of
the
and
so
Kevin
I'm.
Just
going
to
ask
you
to
re-ask
whatever
was
in
your
question
that
I
have
not
yet
answered.
C
C
So
the
the
exception
channel
is
an
example
of
how
Alice
or
Bob
can
manipulate
future
events,
and
obviously
you
can
handle
exceptions.
You
can
choose
to
suppress
the
immediate
consequence
on
the
next
actually
code
flow
of
the
of
control
flow,
but
what
I'm
saying
is,
but
why
I'm
thinking
more
generally,
is
that
when
you,
when
you
write
an
application
that
has
you
know
it
has,
you
know
lots
of
code
in
it?
That
is
not.
You
know
this
very
small
example.
C
I
think
it
generally
turns
out
to
be
a
case
that
there
will
be
edge
cases
that
you
haven't
thought
of
where
you
know
something
happens
differently
and
therefore
the
problem
set
out
here
to
make
sure
that
nothing
can
happen.
Differently
is
very
hard
and
it
should
not
be
an
extreme
concern
that
doing
it
is
that
doing
it
correctly
is
difficult,
and
you
know
this
in
so
first
possibly
you
should
make
the
app
like
the
security
of
your
application,
not
depending
on
having
this
kind
of
wall
banging
property.
Okay,.
A
Good
good,
so
let
me
be
I
am
almost
completely
in
agreement
with
that
and
and
that's
the
that's
part
of
why
I'm
inclined
towards
accepting
Justin's
proposal
into
JavaScript,
proving
it
to
tc39
and
then
whitelisting
it
in
hardened
JavaScript,
as
a
pervasively
available
assumed,
powerless
API
is
because
writing
this
example
writing
a
writing.
A
A
successful
attack
was
a
very
hard
I
mean
it's
not
a
lot
of
code
once
written,
but
it
was
very
hard
to
figure
out
how
to
demonstrate
a
successful
attack
and,
having
done
it,
thinking
back
over
all
of
the
object
capability
code
that
I've
written
over
essentially
my
entire
career
over
many
decades
and
all
of
the
object
capability
code
that
I've
been
exposed
to
I
cannot
think
of
a
case
where,
where
I've
written
code
like
Carol
in
ignorance
of
fluid
scoping,
where,
if
Carol
had
been
run
in
ocaps
with
fluid
scoping
with
exactly
this
form
of
fluid
scope,
it
was
fluid
scoping
designed
with
all
the
safety
considerations
that
Justin
has
designed
where
the
difference
is
one
that
I
would
care
about
where
the
difference
became.
A
An
attack
as
far
as
I
can
tell
all
of
the
security
assumptions
made
by
the
defensive
code
that
I've
written
would
remain
successfully
defensive
with
regard
to
the
issues
that
he
cared
about
after
the
introduction
of
after
the
hypothetical
introduction
of
fluid
scoping
of
this
form
into
the
base
language.
A
B
My
I
have
more
of
a
meta
question:
what
is
the
benefit
of
fluid
scoping
right?
You
mentioned
that
I
could
call
someone
who
has
no
access
to
the
variable,
who
calls
someone
who
does
seems
to
me
that
could
be
achieved
with
sealed
boxes.
Is
there?
Is
there
something
else?
Some
other
motivation.
G
I
can
answer
this
if
you'd
like?
Yes,
please,
okay,
so,
yes,
everything
possible
in
food
scoping
is
possible
if
you
were
to
close
your
wrap
everything.
G
My
company
runs
a
server
platform,
and
one
of
the
requirements
for
us
is
that
we
have
to
patch
a
well-known
Global
API,
to
enhance
it
with
more
functionality,
to
the
all
that
all
code
is
able
to
directly
access
that
Global
API
and
it's
standardized
across
all
code.
Everyone
knows
how
to
call
this
function.
We
cannot
change
the
parameters
to
this
function
or
change
its
behavior
explicitly.
It
has
to
be
done
implicitly
by
automatically.
G
In
order
for
me
to
provide
this
enhanced
API
for
a
global
function.
I
would
need
to
wrap
all
of
my
users
code,
the
people
who
are
actually
running
on
my
platform
and
it's
very,
very
large
code.
It
can
be
several
megabytes
and
I
would
then
need
to
re-evaluate
their
entire
code
base
for
every
single
function
call,
and
so
it's
a
performance
benefit
here.
In
order
to
do
this
correctly
in
the
current
system,
I
need
to
run
megabytes
of
code
every
single
time
in
order
to
do
it
with
this
new
capability.
G
G
B
Thanks,
hey
Terry.
H
H
A
A
So
Carol
is
so
code.
Written
by
Carol
was
calling
that,
but.
H
A
H
A
A
No
for
Bob
well,
Carol
has
created
all
abouts,
but
it's
the
Alice
code
that
defines
and
makes
available
on
the
Alice
instance
a
for
Bob
method.
H
E
A
H
A
In
particular
that
they're,
that
that
you're,
creating
them
and
they're
completely
isolated
from
each
other.
So
at
the
point
so
after
they're
created
at
this
point,
they're
both
created,
but
they
have
not
been
introduced
to
each
other.
They
have
no
ability
to
signal
right,
okay
and-
and
the
thing
that
brings
about
the
connectivity
is
the
call
the
call
here
on
line
53
and
the
call
here
on
line
61..
That's
how
they
get
introduced
right.
H
A
The
for
Alice
from
Bob
type
is
no
arguments,
no
result.
The
for
Bob,
the
Bob
for
Alice
method
is
no
arguments
no
result,
and
so
basically
all
of
the
you
know
the
the
the
the
before
the
you
know.
Four
Bob
and
four
Alice
had
no
argument,
no
result
and.
A
A
A
If
you're
doing
this,
let's
say
in
Joey
or
Midori
M
sharp
a
statically,
typed
ocap
language,
then
you
could
enforce
the
type
system
that
all
of
the
functions
in
question
had
no
arguments
and
no
results,
although
still
have
to
to
worry
about
the
exceptional
Chapel,
and
then
the
golden
here
reveals
kind
of
what
the
what
the
trick
is,
which
is
Bob,
invokes
Alice's
for
Bob
method
twice
and
then
after
two
invocations
two
separate
invocations
Alice
then
calls
Bob's
for
Alice
method.
Once.
E
A
Is
correct?
That
is
exactly
correct,
so
the
key
is
that
these
two
calls
from
Bob
to
Alice
are
made
in
two
different
fluid
context:
two
different
temporal
scoping
contexts
that
that
only
Bob
consents,
but
that
Alice,
even
though
she
can't
sense
it,
she
can
still
manipulate
it
using
rap.
B
C
C
In
the
absence
of
EQ,
there
were
all
sorts
of
programs
written
that
used
the
that
used,
you
know,
call
you
know,
Alice
calls
Bob
while
having
set
a
variable
right
and
some
of
these
had
you
know
some
of
these
turn
later
turned
out
to
be
wrong
to
have
attacks,
and
this
just
you
know,
I
think.
If
there's
you
know,
if
there's
a
problem
with
this
proposal,
it's
going
to
be
shaped
like
that
yeah,
it's
going
to
be
some
of
these
trying
to
use
these
things
and
I.
C
Furthermore,
think
that,
like
the
way
in
which
it's
the
the
kind
of
situation
where
this
is
going
to
would
come
up,
if
it
comes
up,
is
essentially
somebody
didn't
expect
their
scope
to
outlive
some
end
condition.
That
is
the
they.
They
assumed
that
the
fluent
variable
that
the
value
they
inserted
is
going
to
you
live
for
some
extent
and
that
it
would
end
and
like
in
the
in.
A
I
got
it,
I,
got
it
and
and
you're
right.
That's
that's
where
to
look
for
problems.
I
have
not
found
a
problem
by
looking
there,
but
I've
also
only
been
living
with
this.
For,
for
you
know
a
week
and
a
half
now
or
two
weeks
or
something
I
think
you
know,
let's
say
two
weeks
of
really
thinking
about
your
heart,
Jazz,
I'm,
I'm
actual
because
it
is
11,
40
or
42
and
we're
stopping
it
at
noon
or
many
people
will
leave
at
noon.
A
I
want
to
postpone
taking
further
questions
from
the
floor
on
until
I
show
the
punchline,
because
I
haven't
gotten
to
my
punch
line.
Yet
is
that
okay
Jazz.
A
Okay,
I
accept
that
interruption.
A
That
I
think
makes
it
very
clear
what
the
relationship
is
between
the
two
levels
of
object
capability,
language,
and
that
is
by
imagining
a
source-to-source
transformation,
very
analogous
to
the
way
that
we
explain,
call
return
semantics
by
CPS,
transform
so
CPS
transform
continuation
style,
transform
if
you
just
do
the
transform
globally
you're
explaining
call
return
semantics
in
terms
of
a
language
with
one
one-way
invocation.
A
But
then
having
done
that
explanation,
you
can
then
introduce
Primitives
like
call
CC
that
cannot
be
written
in
the
pre-transformed
language,
but
can
be
written
manually
in
the
post-transformed
language
to
be
used
from
the
pre-transformed
language,
so
I'm
going
to
to
so
I'm
in
this
slide,
I'm
going
to
introduce
the
concept
of
the
fluid
the
FPS
transform
the
fluid
passing
style
transform,
which
works
as
follows:
rewrite
every
pre
FPS
variable
by
prete
by
prepending,
an
underbar
I.
Do
that
and
you
can
imagine
the
same.
A
You
did
the
same
kind
of
thing
for
CPS
Transformer.
Any
of
these
language
to
language
transforms
to
just
make
it
clear
what
code
can
can
reference
which
variable
and
then
for
each
pre-fps
function.
Definition
like
this.
This
is
assumed
to
be
a
function
in
the
pre-transformed
language,
we're
going
to
transform.
A
A
So
so
you
know
all
the
identifiers
here
have
been
prepended
with
an
underbar
in.
In
addition
for
each
function,
definition,
we've
added
a
parameter
named
f
and
for
each
function
call
we've
added
an
argument
named
f.
A
So
what
we're
doing
here
is,
if
you
do
nothing
else
other
than
this
transform,
so
you're
basically
doing
nothing
else
other
than
these
first
three
bullets,
then,
obviously,
you
haven't
changed
anything
because
nothing
in
the
pre-transformed
language
can
be
sensitive
to
the
f.
So
passing
the
F
through
everything
hasn't
done
anything.
A
But
then
we
add
to
this
a
we
take
Justin's
Primitives
and
we
write
it
in
the
post,
fpf
FPS
language
manually
to
be
available
to
be
invocable
from
the
pre-fpf
fpfs
FPS
language,
I
hadn't
realized
how
hard
that
was
going
to
be
to
pronounce
so
that
like
call
CC
we're
making
use
of
this
lifting
of
of
one
language
into
the
other,
so
that
the
so
that
the
pre
F
FPS
language
has
additional
expressiveness.
A
Even
though
it's
Rewritten
to
a
post,
FPS
language,
where
the
post,
FPS
FPS
language
is
exactly
a
normal
object
capability
language
in
this
case,
exactly
the
post
FPS
language
here-
could
be
hardened
JavaScript
as
it
is
today
without
Justin's
proposal
now.
So
so
all
of
the
magic
is
brought
about
by
this
thing,
that's
manually,
written
in
the
in
the
post-transform
language,
but
made
available
to
the
pre-transformed
source
code.
So
let's
take
a
look
at
that.
A
So
what
I've
done
here
is
for
all
of
those
capital
F
variables,
I've
just
numbered
them,
so
that
they're
all
distinct
variables,
I
didn't
need
to
by
the
by
the
rules
of
the
transformation
lexical
shadowing,
would
have
done
everything
I
needed.
Oh
I'm!
Sorry,
that's
not
true!
That's
not
true!
A
I
I
still
need
wrap,
still
needs
to
distinguish
them,
but
any
case
numbering
them
does
not
buy
since,
since
we're
assuming
this
one's
manually
written
in
the
post-transform
language,
I
didn't
violate
any
rules
by
Nate
by
giving
them
distinct
names,
so
under
bar
async
content.
Make
acid
context
is
the
thing
that
would
be
called
by
pre-transfer
code,
calling
make
Ace
in
context.
A
Make
Ace
in
context
has
no
no
parameters,
so
this
one
has
an
F1
parameter.
This
F1
is
never
further
referenced,
so
this
one
is
actually
actually
doesn't
matter.
It
does
not
matter.
What
temporal
context
is
is
current
at
the
time
that
make
async
context
is
called
as
your
battle
I
mentioned.
This
is
completely
non-wool
breaking
code
by
heart
and
JavaScript
rules.
There's
no
Global
State
here.
A
Okay,
then
the
run
method
there
takes
as
a
first
argument.
Some
you
know
a
a
a
this
first
parameter
that
represents
the
fluid
scope
at
the
moment
that
one
was
called.
What
run
then
does?
Is
it
constructs
the
new
fluid
scope,
essentially
by
pushing
onto
the
I'm
sorry,
each
of
the
fluid
Scopes
in
the
in
this
in
this
form
are
actually
represented
as
a
function
of
a
map,
and
so
over.
A
Here
F3
is
a
function
of
a
map
variable
and
what
it
will
do
is,
and
this
is
of
a
of
a
map-
that's
assumed,
to
be
at
the
implementation
level.
So
I
was
assumed
the
UN,
the
unprefixed
form
of
each
of
these
globals
are
assumed
to
be
just
globals
of
the
of
the
the
base
language,
the
post-transformed
language
and
because
I'm
writing
them
without
underbars.
I'm
writing,
I'm.
Writing
to
the
real
Primitives,
not
the
lifted
Primitives.
A
So
in
any
case,
given
a
map
look
up
the
captured
key
in
the
map
and
if
the
key
is
in
this
map,
then
the
return
to
Value
associated
with
that
key
in
this
map.
Otherwise,
you
pass
the
map
down
to
the
previous
fluid
scope,
the
fluid
scope
that
was
in
Force
at
the
moment
that
one
was
called
notice
by
the
way.
Another
very
peculiar
thing
in
this
rewrite
is
we
got
rid
of
all
the
tri-finalings
there's
no
try.
Finally
around
this
call
and
there's
no
try.
A
A
Thank
you.
Thank
you.
Yes,
this
is
the
Yoda
transform
you've
now
named
it
the
so.
So
the
things
to
notice
here
is
that
there
is
a
transposed
map
created.
Her
call
to
make
a
sync
context,
in
other
words,
transpose
map.
There's
one
of
those
her
fluid
variable.
A
There
is
the
key
is
created
as
a
empty
Frozen
object,
which
is
therefore
completely
Authority
free,
it's
it's.
It
has
only
identity,
it
has
no
ability
to
cause
effects
of
any
kind.
The
scope
objects
here.
The
fluid
scope
objects
like
F3,
that's
a
closure
that
is
capturing
only
key
and
the
previous
fluid
scope,
F2
and
therefore
the
the
and
the
and
therefore
this
closure
F3,
is
completely
immutable
in
perilous,
given
that
F2
is
completely
immutable
in
perilous.
A
So
by
induction,
given
that,
given
that
we're
that
we
only
start
with
a
fluid
scope
representing
the
empty
scope,
that
is
immutable
and
perilous,
all
of
our
fluid
Scopes
are
immutable
and
Powerless,
so
passing
them
through.
As
the
implicit
first
argument
here
cannot
be
communicating
anything
other
than
information,
they
are
not
communicating
the
ability
to
cause
effects,
so
we
cannot.
We
can
no
longer
so
at
the
level
at
which
we
we're
doing
this
level.
A
Lifting
we
no
longer
at
this
in
this
explanation
understand
rap
as
causing
an
effect
which
is
really
key
to
why
to
the
safety
or
to
to
the
stronger
safety
argument.
The
safety
argument
that
I'm
making
here
that's
stronger
than
my
previous
safety
arguments
so
over
here
we're
saying,
trans
we're
doing
the
so
The
Binding
of
the
fluid
variable
to
a
value
is
a
binding
that
has
to
be
specific
to
both
dimensions.
It's
specific
to
the
temporal
dimension
and
it's
specific
to
the
fluid
variable.
A
There
is
one
transposed
map
per
fluid
variable
and
there's
one
key
per
binding
event.
So
by
setting
the
by
by
setting
to
the
map
associated
with
the
fluid
variable,
a
binding
from
this
key
to
this
value.
That
binding
is
specific
to
this
call
to
run
and
then
having
created
this
nested
fluid
scope
purely
in
a
purely
functional
manner.
A
I
there's
the
so.
The
rewrite
is
really
a
only
making
use
of
pure
functional
Notions
in
the
language
of
that
day.
We're
now
taking
the
nested
scope
and
passing
it
to
the
Callback
and
then
the
get
method,
the
in
the
in
the
transform
we're
passing
some
current
fluid
scope
to
the
get
method,
the
get
method,
then
you
passes
the
transform
that
represents
the
current
fluid
variable.
This
fluid
variable,
the
fluid
variable.
A
That's
the
instance
that
you're
doing
calling
get
on
takes
the
map
that
is
specific
to
that
variable
and
passes
it
to
to
the
fluid
scope,
to
look
up
the
corresponding
value.
A
And
that
will
get
passed
down
the
stack
until
it
forget
the
fines
of
binding
for
the
for
that
key
okay.
So
then
the
magic
happens
with
rap
and
rap
is
very
easy
to
understand.
The
this
part
over
here
is
just
boilerplate.
A
The
extra
parameter
of
the
call
to
the
wrapper,
but
rather
the
extra
the
the
value
of
the
extra
parameter
during
the
call
to
wrap
and
that
the
the
fact
that
this
says
F5
rather
than
F6,
is
the
entire
extent
of
the
magic
is
the
thing.
That
is
the
reason
why
this
lifting,
through
the
fluid
passing
style
transformation,
has
introduced
Magic.
H
The
Baseline
carrot,
yeah
I'll
I'll,
just
observe
that
this
is
giving
me
flashbacks
to
looking
at
Haskell,
State,
moan,
ads
and
and
the
method
that
that,
where
a
state
gets
threaded
through
things
without
you
actually
seeing
it,
you
know
the
state
Monet
is
said
well
and
several
note
ads
are
like
that.
Where
there's
this
behind
the
scenes
thing
that
and
and
in
that
case,
get
let's
see,
they're
called
get
and
put
I
guess
in
in
the
state.
Monad
they've
got
the
current
state
and
they
put
a
value
into
State.
H
Those
are
the
special
functions
that
give
you
the
Magic.
In
that
case
they
give
you
access
to
the
underlying
stuff,
but
whereas
the
rest
of
it
appears
mostly
as
as
a
normal
functional
language,
you
know
without
you,
don't
really
see
all
of
the
rest
of
the
plumbing
in
action,
so
it
it.
This
is
just
popping
out
at
me
like
that.
I,
don't
know
whether
that
helps
anybody
else,
but
I.
Certainly
you
know
the
fact
that
you're
replacing
Netflix
with
F5
there,
you
know
that's
changing
what
state
we're
dealing
with
you.
E
D
H
A
It
it
it
helps
me
a
little
bit.
The
the
CPS
transform
plus
call
CC
is
from
for
me
the
stronger
analogy,
but
I
think
I
see
the
analogy.
You're
making.
H
H
Well,
that's
exactly
what
the
state
monad
is
doing
is
it's
doing
all
of
its
stuff
very
functionally,
and
in
Haskell
I
mean
it
has
to
be.
There
is
no
mutability
in
Haskell,
and
and
what,
if
you
look
at
how
state
monad
is
is
implemented,
you
add
a
an
argument
to
the
function.
You
know
you
turn
everything
into
a
function
that
takes
a
state
as
its
first
argument,
okay,
which
is
very
much
in
parallel
with
what
you're
doing
here
right.
H
You
know
you
just
you're,
passing
in
the
state
as
the
first
argument,
almost
yeah
and
and
so
I
see
very,
very
much
parallel
things.
I
forget
how
the
continuation
mode
ad
do
you
get
a
continuation
as
the
first
argument
implicitly
I
forget
how
it
works,
but
it's
you
know
it
it.
Similarly,
you
know
adds
extra
extra
things
that
you
get
access
to
using
call
CC
yeah.
G
I
mean
it
is
currently
possible
to
accomplish
via
sorcery
writing,
but
then
I
have
to
own
all
of
the
code
that
is
going
to
be
running
and
I
have
to
transform
it
before
I
can
run
any
of
it.
I
can't
then
like
I
have
to
own
the
entire
program
and
I
have
to
own
all
the
code.
That's
going
to
be
served
by
my
server
and
everything
else.
That
could
possibly
happen
that
works
for
me.
G
C
I,
so
your
analogy
to
CPS
transform
is
like
concerning
in
the
sense
that
there's
a
sense.
You
know
such
yes,
you,
yes,
if
you
rewrite
the
language,
you
can
make
anything
possible
and
that
doesn't
mean
that
it's
six,
the
original
language,
however,
like
as
you
say,
you
know
it
is
not
nearly
as
concerning
so
the
I
think
a
thought
that
I
had
when
I
was
introduced.
Oh
yes,
Markham
are
you
done
with
the
material
that
you
wanted
to
present.
A
Are
if
we're
either
there's
many
so
so
because
of
the
time
I'm
done
with
okay,
showing
slides
at
my
initiative,
but
I'm
going
to
keep
this
up
in
case
I
need
the
slides
to
answer
a
question.
Okay,.
C
So
what
I
was
thinking
like
I
was
thinking
at
the
very
beginning
when
you
introduced
rap
was
like,
if
you
imagine,
introducing
this
to
a
system
which
you
did
not
previously
have
it
then
somebody's
going
to
be
of
the
opinion.
Like
you
know,
hey
I
want
I.
Don't
do
that
to
my
variable.
I
want
to
be
I
want
to
be
able
to
preserve
the
original
that
the
the
the
immediate
caller
value,
because
you
know
like
in
particular,
I'm
thinking
of
like
tracing
and
walking
systems
which
actually
might
might
even
want,
might
want
both.
C
That
is
to
look
at
the
code
that
you're
presenting
now
they
want
both
F6
and
F5.
Now
you
can't
actually
do
that
in
a
clean
in
a
clear
fashion,
because
you
have
to
Define
how
you
F6
and
F5
get
combined
like
even
at
a
single
variable
that
implies
executing
code,
so
it's
a
non-starter
but
I'm
just
I'm.
Just
you
know
given.
G
So
in
JavaScript
itself,
the
what
we're
wrapping
here
is
promise
prototype.net
because
of
the
semantics
of
Promise
prototype.din
F6
is
guaranteed
to
be
empty.
F6
always
executes
in
a
brand
new
call
stack
and
it's
impossible
for
anything
to
be
stored
in
the
mapping
in
F6.
Okay,.
E
A
A
I
want
to
interrupt
at
this
point
to
to
unretract
Kevin's
retraction
Justin.
Your
answer
isn't
a
complete
answer
to
just
to
Kevin's
issue,
because
you're
promoted
proposing
that
rap
itself
be
directly
available,
not
just
available
implicitly
through
that.
Okay.
G
G
C
Right,
I'm,
not
sure,
yeah
and
notice
that
somebody
who
wants
you
know
who
wants
F6
but
not
F5,
can
just
completely
ignore
this
mechanism
and
use
you
know
regular
Global
state
right.
A
I
For
for
the
rewriting
stuff,
there
often
you
don't
have
to
own
the
code.
Let's
say
you
just
have
to
have
a
rewrite:
the
be
part
of
the
loader
that
loads
the
code.
That's
all
I
was
gonna,
say.
A
E
A
So
yeah
the
the
there
were
two
punch
lines.
I
only
showed
one
of
them.
Next,
one
I
showed
was
the
explanation
of
Justin's
proposed
semantics
using
the
FPS,
the
FPS
transform.
Let
me
show
you
the
other
punchline,
which
is
how
Bob
succeeded
at
the
attack.
A
Okay,
so
what
Bob
does
is
Bob
creates
a
fluid
variable
that
only
Bob
can
perceive.
You
know
that
Bob
cannot
communicate
this
fluid
variable
to
Alice,
so
Alice
doesn't
has,
has
no
awareness
of
the
fluid
variable
Bob
then
uses
the
fluid
variable
run
method
twice
once
established,
calling
the
callback
with
no
arguments.
A
There's,
there's
no
args
here,
calling
the
Callback
with
Bob's
own
fluid
variable
bound
to
zero
in
the
in
the
temporal
scope
in
which
it
is
Bob,
is
making
the
Callback
to
CB
and
then
doing
it
a
second
time
with
the
fluid
binding
being
one
and
then
Bob,
and
then.
A
And
then
Bob
is
making
available
to
Alice
this
control
signal,
so
that
Alice
can
then
call
Bob
back
from
some
temporal
context
in
which
of
of
out
where
the,
where
which
temporal
context
it
is,
is
of
Alice's
control.
Even
though
Alice
is
ignorant
to
fluid
VAR
and
within
the
temporal
context,
determined
by
Alice.
Bob
then
reads
the
fluid
variable
and
stores
it
in
his
secret
variable
so
that
when
Carol
asks
Bob,
what
secret
did
you
learn
from
Alice
Bob?
A
A
So
in
other
words,
each
element
of
snapshot
is
a
function
of
one
argument,
which
is
a
callback
argument,
and
it's
then
going
to
wrap
the
Callback
at
the
time.
You
know,
and
also
it's
called
that
it's
a
function
of
a
callback
argument,
but
it's
one
that
has
captured
the
fluid
scope
at
the
moment
that
it
was
pushed
onto
the
snapshots
buses.
A
G
The
person
who
is
recording
is
about
to
leave,
so
if
we
want
anything
recorded,
you
have
to
do
it
very
quickly.
Okay,.
A
A
That
gives
Alice
the
authority
to
to
invoke
Bob's
four
Alice
method
with
no
arguments
uses
the
wrapped
callback
calling
function
that
she's
stored
in
snapshots
looks
up
that
function
according
to
the
secret,
restoring
that
captured
temporal
context
and
then
calls
callback
with
no
arguments
in
the
restored,
fluid
context
and
Jazz.
Let's
see
how
far
we
can
get
before
Mike
has
to
leave.
J
Is
the
are
we
replacing
Justin's
difficult
problem
by
making
it
Carol's
difficult
problem
here?
By
forcing
her
to
do
the
set
of
Transformations
I
did
not
follow
entirely
yeah
yeah.
A
We're
saying
that
an
innocent
Carol,
a
Carol
that
thinks
she's
programming
in
an
unenhanced
language,
is
subject
to
this
attack.
So
if
this
is
an
attack,
she
cares
about
which
I'm
further
claiming
is
almost
completely
is,
is
extremely
obscure.
Is
that
I
cannot
think
of
any
realist?
Any
actual
example
that
I've
ever
encountered
in
which
Carol
would
care
about
the
attack,
but
if
Carol
does
care
about
the
attack
and
she's,
she
thinks
she's
ripped
being
she's
writing
code.
A
J
And
the
transformation
for
Carol,
so
it's
certainly
a
smaller
load
in
that
we
only
need
to
transform
as
a
smaller
set
of
users.
Is
that
transformation
any
different
from
the
transformation
we
would
need
to
do
like
by.
A
Simply
is
the
trends
from
We're,
assuming
that
all
code,
written
by
users,
all
code
written
by
users
in
the
FPS
explanation,
all
of
that
code
is
transformed
that
the
only
thing
untransformed
is
the
implementation
of
the
fluid
scoping
mechanism
itself.
So
let
me
show
you
Justin
wrote
two
defenses
for
Carol
to
use,
so
one
defense
is
that
Carol
can
make
use.
Carol
herself
can
make
use
of
fluid
scoping.
A
That's
one
defense
and
the
other
defense
is
that
Carol
can
make
use
of
the
fluid
scoping
so
that
in
order
to
censor
the
communication,
so
that
no
secret
can
be
leaked
and
both
of
these
you
know
both
of
these
are
General
defenses
Carol,
knowing
these
that
she's
re
being
written
in
the
enhanced
language
can
use
fluid
scoping
rap
to
engage
in
either
of
these
defenses.
According
to
what
Carol
is
interested
in
defending
Jazz.
Was
that
clear,
before
I
go
into
Kevin.
J
C
Okay,
so
the
the
defense,
the
the
sensor
defense,
as
you
call
it
is
also
you
can
also
be
implemented
in
the
frame
of
perform
of
you
know,
run
the
other
party
in
another
in
their
own
turn,
so
that
they
can't
ever
observe
the
lack
of
rapping,
and
this
is
also
a
defense
against
you
know
many
other
things
which
we
bump
into
the
bucket
of
plan
interference,
so
I
think
so
that's
a
useful
argument
towards
you
know.
This
is
okay,
because
you
like
that
you
likely
have
other
hazards.
C
If
you
are
invoking
untrusted
code,
if
you
are
invoking,
you
know,
you
know
a
party
you
are
suspicious
of
you
know
in
response
to
being
called
by
another
party,
you
know
and
including,
like
now,
Services
the
obvious
one,
but
you
know
there's
a
other
possible
considerations
from
that,
and
so,
if
you
run
in
a
new
turn,
then
you
have
none
of
these
problems.
Not
even
this
new.
When
we're
proposing
introducing
yeah.
G
I
wanted
to
add
a
couple
of
points.
Can
you
highlight
line
62
through
64.
G
So
this
is
one
of
the
defenses
that
I
wrote,
and
this
is
the
entire
extent
of
the
defense
in
order
for
Carol
to
ensure
that
Bob
and
Alice
cannot
communicate
actually,
there's
line
52
and
54
I'm.
Sorry,
so
there's
two
parts
to
this
defense.
G
She
can
force
their
communication
to
happen
in
a
context
that
she
controls,
and
so
it's
a
what
literally,
if
you
were
to
delete
line,
52,
54,
62
and
64..
That
was
the
original
code
and
the
new
code
is
just
adding
those
four
lines
in
and
then
she's
completely
defended
against
the
attack.
G
Other
defense,
which
Mark
showed
before,
but
it's
not
currently
being
shown,
is
similar
amount
of
code,
it's
four
extra
lines
and
some
setup
that
happens,
and
it's
extremely
easy
for
Carol
to
defend
against
in
order
to
prevent
this
communication
from
happening
without
her
knowledge
or
for
it
to
happen
at
all.
G
The
second
point
that
I
want
to
highlight
is
that
this
attack
does
not
leak
in
object
reference,
and
so
you
can't
use
it
to
gain
more
capabilities.
You
can
only
use
it
to
leak
a
single
bit
and
you
can
do
it
multiple
times
to
make
bytes
or
whatever
you
want.
So
you
can
pass
a
message,
but
that
message
does
not
carry
any
capability.
A
The
yeah,
that
is
by
the
way
why
I
use
the
transform
the
transposed
map,
which
made
the
rewrite
a
little
bit
more
complicated
than
it
needed
to
be
just
to
be
a
rewrite.
Here's
the
transpose
map,
so
that
all
of
the
F's
that
were
being
passed
hadn't
were
completely
powerless
and
transitively
immutable,
and
that
kind
of
establishes
that
the
extra
communication
here
is
not
communicating
even
through
an
ignorant
Carol
is
not
communicating
anything
more
than
information.
Kevin.