Skip to content

Commit

Permalink
Merge branch 'master' of github.com:JuliaLang/julia
Browse files Browse the repository at this point in the history
* 'master' of github.com:JuliaLang/julia:
  fixing issue #91. spawn needs to capture the right set of variable bindings.
  • Loading branch information
StefanKarpinski committed Jun 30, 2011
2 parents ec4f202 + 1a751bb commit f41c20f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 13 deletions.
44 changes: 31 additions & 13 deletions j/multi.j
Original file line number Diff line number Diff line change
Expand Up @@ -1068,25 +1068,43 @@ let lastp = 1
lastp = 1
end
end
if p==myid()
# for local spawn, simulate semantics of copying bindings
if isa(env,Tuple)
env = map(x->(isa(x,Box)?Box(x.contents):x), env)
linfo = ccall(:jl_closure_linfo, Any, (Any,), thunk)
thunk = ccall(:jl_new_closure_internal, Any, (Any, Any),
linfo, env)::Function
end
end
spawnat(p, thunk)
end
end

macro spawn(thk)
:(spawn(()->($thk)))
find_vars(e) = find_vars(e, {})
function find_vars(e, lst)
if isa(e,Symbol)
if isbound(e) && isgeneric(eval(e))
# exclude global generic functions
else
push(lst, e)
end
elseif isa(e,Expr)
foreach(x->find_vars(x,lst), e.args)
end
lst
end

# wrap an expression in "let a=a,b=b,..." for each var it references
function localize_vars(expr)
v = find_vars(expr)
# requires a special feature of the front end that knows how to insert
# the correct variables. the list of free variables cannot be computed
# from a macro.
Expr(:localize,
{:(()->($expr)), v...},
Any)
end

macro spawn(expr)
expr = localize_vars(:(()->($expr)))
:(spawn($expr))
end

macro spawnlocal(thk)
:(spawnat(LocalProcess(), ()->($thk)))
macro spawnlocal(expr)
expr = localize_vars(:(()->($expr)))
:(spawnat(LocalProcess(), $expr))
end

at_each(f, args...) = at_each(PGRP, f, args...)
Expand Down
13 changes: 13 additions & 0 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,19 @@ So far only the second case can actually occur.
`(lambda ,args
(vinf ,(caddr e) ,vi ,cv ())
,bod)))
((eq? (car e) 'localize)
;; special feature for @spawn that wraps a piece of code in a "let"
;; binding each free variable.
(let ((env-vars (map vinfo:name env))
(localize-vars (cddr e)))
(let ((vs (filter
(lambda (v) (or (memq v localize-vars)
(memq v env-vars)))
(free-vars (cadr e)))))
(analyze-vars
`(call (lambda ,vs ,(caddr (cadr e)) ,(cadddr (cadr e)))
,@vs)
env))))
(else (cons (car e)
(map (lambda (x) (analyze-vars x env))
(cdr e))))))
Expand Down

0 comments on commit f41c20f

Please sign in to comment.