" Smalltalk/BlockClosure.st -*- Smalltalk -*- " " StaticBlocks contain neither free references nor non-local returns and are idempotent. For each such block in the source a single, unique, shared StaticBlock is created at translation unit initialisation time. " StaticBlock : Object ( _function "compiled code address" _arity "number of arguments (checked in #value)" ) StaticBlock _entry: f _arity: a [ self := self _clone. _function := f. _arity := a. ] StaticBlock arity { return _integerObject((int)((struct t_StaticBlock *)self)->_arity); } StaticBlock value [ { if (0 == (int)((struct t_BlockClosure *)self)->_arity) return ((oop (*)(oop))(((struct t_BlockClosure *)self)->_function))(self); }. ^self primitiveFailed ] StaticBlock value: a [ { if (1 == (int)((struct t_BlockClosure *)self)->_arity) return ((oop (*)(oop, oop))(((struct t_BlockClosure *)self)->_function))(self, v_a); }. ^self primitiveFailed ] StaticBlock value: a value: b [ { if (2 == (int)((struct t_BlockClosure *)self)->_arity) return ((oop (*)(oop, oop, oop))(((struct t_BlockClosure *)self)->_function))(self, v_a, v_b); }. ^self primitiveFailed ] StaticBlock run [ { if (0 == (int)((struct t_BlockClosure *)self)->_arity) return ((oop (*)(oop))(((struct t_BlockClosure *)self)->_function))(self); }. ^self primitiveFailed ] " BlockClosures contain free references; either the receiver (possibly indirectly via receiver variables) or temps/args (defined in an enclosing scope) appear free within the closure and are imported through a _state vector. A new BlockClosure with fresh _state is created every time control passes the block in the source. " BlockClosure : StaticBlock ( receiver "the receiver within the block's creating context" _state "shared state from that context" outer "the creating context's enclosing context" ) BlockClosure _entry: f _arity: a receiver: r state: s outer: o [ self := self _clone. _function := f. _arity := a. receiver := r. _state := s. outer := o. ] " BlockClosureNLRs are BlockClosures that retain a reference to an environment, corresponding to the home context, through which a non-local transfer of control can be made to effect a non-local return. " BlockClosureNLR : BlockClosure ( _envp "saved execution environment for non-local return" ) BlockClosureNLR _entry: f _arity: a receiver: r state: s envp: e [ self := self _clone. _function := f. _arity := a. receiver := r. _state := s. outer := nil. _envp := e. ] BlockClosureNLR cannotReturn: anObject [ { abort(); }. ] BlockClosureNLR return: anObject { _nlReturn(self, ((struct t_BlockClosureNLR *)self)->_envp, v_anObject); }