1.1 --- a/rsvp.py Sat May 16 01:34:03 2009 +0200
1.2 +++ b/rsvp.py Sun May 17 00:58:27 2009 +0200
1.3 @@ -486,40 +486,51 @@
1.4 self.value = None, context # context of context is not interesting
1.5
1.6 def CheckFrame(self):
1.7 - operand = self.operand
1.8 - frame = self.invocation_sp_stack[-1]
1.9 - context, ref = self.value
1.10 - data = self.load(ref)
1.11 + (nargs, ndefaults, has_star) = self.operand
1.12 +
1.13 + # The frame is actually installed as the locals.
1.14 + # Retrieve the context from the first local.
1.15 +
1.16 + frame = self.local_sp_stack[-1]
1.17 + context, ref = self.frame_stack[frame] # + 0
1.18 + nlocals = len(self.frame_stack[frame:])
1.19
1.20 # Support sliding of the frame to exclude any inappropriate context.
1.21
1.22 if context is None:
1.23 - self.invocation_sp_stack[-1] += 1
1.24 - operand -= 1
1.25 + self.local_sp_stack[-1] += 1
1.26 + nlocals -= 1
1.27 else:
1.28 context_data = self.load(context)
1.29 if context_data.attrcode is None: # absent attrcode == class
1.30 - self.invocation_sp_stack[-1] += 1
1.31 - operand -= 1
1.32 + self.local_sp_stack[-1] += 1
1.33 + nlocals -= 1
1.34
1.35 # Test the frame size.
1.36 + # NOTE: Raise a proper exception here.
1.37
1.38 - nargs, ndefaults = data.codedetails
1.39 - if not ((nargs - ndefaults) <= operand <= nargs):
1.40 - raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (self.operand, nargs - ndefaults, operand, nargs)
1.41 + if not ((nargs - ndefaults) <= nlocals and (nlocals <= nargs or has_star)):
1.42 + raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (self.operand, nargs - ndefaults, nlocals, nargs)
1.43 +
1.44 + def FillDefaults(self):
1.45 + (nargs, ndefaults) = self.operand
1.46 +
1.47 + # The frame is actually installed as the locals.
1.48 +
1.49 + frame = self.local_sp_stack[-1]
1.50 + nlocals = len(self.frame_stack[frame:])
1.51
1.52 # Support population of defaults.
1.53 # This involves copying the "attributes" of a function into the frame.
1.54
1.55 - default = operand - (nargs - ndefaults)
1.56 - self.frame_stack.extend([None] * (nargs - operand))
1.57 - pos = self.operand
1.58 + default = nlocals - (nargs - ndefaults)
1.59 + self.frame_stack.extend([None] * (nargs - nlocals))
1.60 + pos = nlocals
1.61
1.62 - while operand < nargs:
1.63 + while pos < nargs:
1.64 self.frame_stack[frame + pos] = self.load(ref + default + 1) # skip header
1.65 default += 1
1.66 pos += 1
1.67 - operand += 1
1.68
1.69 def CheckSelf(self):
1.70 context, ref = self.value
1.71 @@ -534,6 +545,11 @@
1.72 self.local_sp_stack.append(self.invocation_sp_stack[-1]) # adopt the invocation frame
1.73 return self.jump(codeaddr, self.pc + 1) # return to the instruction after this one
1.74
1.75 + def JumpWithFrameDirect(self):
1.76 + operand = self.operand
1.77 + self.local_sp_stack.append(self.invocation_sp_stack[-1]) # adopt the invocation frame
1.78 + return self.jump(operand, self.pc + 1) # return to the instruction after this one
1.79 +
1.80 def ExtendFrame(self):
1.81 self.frame_stack.extend([None] * self.operand)
1.82