def byte_MAKE_CLOSURE(self, argc): name = None closure, code = self.popn(2) defaults = self.popn(argc) globs = self.frame.f_globals fn = Function(name, code, globs, defaults, closure, self) self.push(fn)
def byte_MAKE_FUNCTION(self, argc): """Make a runtime object from a types.CodeObject, typically in a .pyc file.""" name = None code = self.pop() defaults = self.popn(argc) globs = self.frame.f_globals fn = Function(name, code, globs, defaults, None, self) self.push(fn)
def byte_MAKE_FUNCTION(self, argc): if PY3: name = self.pop() else: name = None code = self.pop() defaults = self.popn(argc) globs = self.frame.f_globals fn = Function(name, code, globs, defaults, None, self) self.push(fn)
def byte_MAKE_CLOSURE(self, argc): if PY3: # TODO: the py3 docs don't mention this change. name = self.pop() else: name = None closure, code = self.popn(2) defaults = self.popn(argc) globs = self.frame.f_globals fn = Function(name, code, globs, defaults, closure, self) self.push(fn)
def call_function(self, arg, args, kwargs): lenKw, lenPos = divmod(arg, 256) namedargs = {} for i in range(lenKw): key, val = self.popn(2) namedargs[key] = val namedargs.update(kwargs) posargs = self.popn(lenPos) posargs.extend(args) func = self.pop() frame = self.frame if hasattr(func, 'im_func'): # Methods get self as an implicit first parameter. if func.im_self: posargs.insert(0, func.im_self) # The first parameter must be the correct type. if not isinstance(posargs[0], func.im_class): raise TypeError( 'unbound method %s() must be called with %s instance ' 'as first argument (got %s instance instead)' % ( func.im_func.func_name, func.im_class.__name__, type(posargs[0]).__name__, ) ) func = func.im_func # BUG FIX: The callable must be a pyobj.Function, not a native Python # function (types.FunctionType). The latter will be executed using the # HOST CPython interpreter rather than the byterun interpreter. # Cases: # 1. builtin functions like int(). We want to use the host here. # 2. User-defined functions from this module. These are created with # MAKE_FUNCTION, which properly turns them into pyobj.Function. # 3. User-defined function from another module. These are created with # __import__, which yields a native function. if isinstance(func, types.FunctionType): defaults = func.func_defaults or () byterun_func = Function( func.func_name, func.func_code, func.func_globals, defaults, func.func_closure, self) else: byterun_func = func retval = byterun_func(*posargs, **namedargs) self.push(retval)
def call_function(self, arg, args, kwargs): lenKw, lenPos = divmod(arg, 256) namedargs = {} for i in range(lenKw): key, val = self.popn(2) namedargs[key] = val namedargs.update(kwargs) posargs = self.popn(lenPos) posargs.extend(args) #debug('*** call_function stack = %s', self.frame.stack) func = self.pop() #debug1('*** call_function POPPED %s', func) if getattr(func, 'func_name', None) == 'decode_next': raise AssertionError('BAD: %s' % func) frame = self.frame if hasattr(func, 'im_func'): # Methods get self as an implicit first parameter. #debug('') #debug('im_self %r', (func.im_self,)) #debug('posargs %r', (posargs,)) if func.im_self is not None: posargs.insert(0, func.im_self) #debug('posargs AFTER %r', (posargs,)) # TODO: We have the frame here, but I also want the location. # dis has it! # The first parameter must be the correct type. if not isinstance(posargs[0], func.im_class): # Must match Python interpreter to pass unit tests! if self.more_info: # More informative error that shows the frame. raise TypeError( 'unbound method %s() must be called with %s instance ' 'as first argument, was called with %s instance ' '(frame: %s)' % ( func.im_func.func_name, func.im_class.__name__, type(posargs[0]).__name__, #posargs[0], self.frame, ) ) else: raise TypeError( 'unbound method %s() must be called with %s instance ' 'as first argument (got %s instance instead)' % ( func.im_func.func_name, func.im_class.__name__, type(posargs[0]).__name__, ) ) func = func.im_func # BUG FIX: The callable must be a pyobj.Function, not a native Python # function (types.FunctionType). The latter will be executed using the # HOST CPython interpreter rather than the byterun interpreter. # Cases: # 1. builtin functions like int(). We want to use the host here. # 2. User-defined functions from this module. These are created with # MAKE_FUNCTION, which properly turns them into pyobj.Function. # 3. User-defined function from another module. These are created with # __import__, which yields a native function. # 4. pyobj.Generator is on the stack, and you get its next() value. # We should do something smarter. # This check is broken! # next() and send() that is a native python function. We dO NOt need # to wrap it. do_wrap = False #debug1('FUNC %s', dir(func)) if isinstance(func, types.FunctionType): do_wrap = True # Hack for case #4. if getattr(func, '__doc__', None) == 'DO_NOT_INTERPRET': do_wrap = False #raise AssertionError #debug1('do_wrap: %s', do_wrap) if do_wrap: #debug1('*** WRAPPING %s', func) #debug1('%s', dir(func)) #debug1('__doc__ %s', func.__doc__) defaults = func.func_defaults or () byterun_func = Function( func.func_name, func.func_code, func.func_globals, defaults, func.func_closure, self) else: byterun_func = func #debug1(' Calling: %s', byterun_func) retval = byterun_func(*posargs, **namedargs) self.push(retval)