class Interpreter(object): _immutable_fields_ = ['space'] def __init__(self): self.space = ObjectSpace(global_functions) self.output_buffer = [] self.superglobals = [] def run(self, bytecode): frame = Frame(self, bytecode) self.execute(bytecode, frame) # close any remaining buffers while len(self.output_buffer) > 0: buffer = self.end_buffer() self.output(buffer) def run_return(self, bytecode): self.start_buffering() frame = Frame(self, bytecode) self.execute(bytecode, frame) # close any remaining buffers while len(self.output_buffer) > 0: buffer = self.end_buffer() if len(self.output_buffer) > 0: self.output(buffer) else: return buffer @jit.unroll_safe def setup(self, request): get_ = {} for key, value in request.get.iteritems(): get_[unicode(key)] = self.space.wrap(value) get = self.space.newdictarray(get_) getref = W_Reference(get) # structure of this list needs to match pyhp.scopes.SUPERGLOBALS # SUPERGLOBALS = [u'$_GET', u'$_POST'] self.superglobals = [getref, None] def execute(self, bytecode, frame): from pyhp.bytecode import ByteCode assert(isinstance(bytecode, ByteCode)) from pyhp.frame import Frame assert(isinstance(frame, Frame)) if bytecode._opcode_count() == 0: return None pc = 0 while True: # required hint indicating this is the top of the opcode dispatch driver.jit_merge_point(pc=pc, bytecode=bytecode, self=self, frame=frame) if pc >= bytecode._opcode_count(): return None opcode = bytecode._get_opcode(pc) if isinstance(opcode, RETURN): return frame.pop() opcode.eval(self, bytecode, frame, self.space) if isinstance(opcode, BaseJump): new_pc = opcode.do_jump(frame, pc) if new_pc < pc: driver.can_enter_jit(pc=new_pc, bytecode=bytecode, self=self, frame=frame) pc = new_pc continue else: pc += 1 def start_buffering(self): self.output_buffer.append(UnicodeBuilder()) def end_buffer(self): buffer = self.output_buffer[-1].build() self.output_buffer.pop() return buffer def output(self, string, buffer=True): if buffer and len(self.output_buffer) > 0: self.output_buffer[-1].append(string) else: self._output(string) def _output(self, string): assert isinstance(string, unicode) # 1 here represents stdout os.write(1, string.encode('utf-8'))