Commits

asuhan committed 1b67339

get rid of special pointer array_of_zpp_ptr; fix a subtle bug with CVs

  • Participants
  • Parent commits 8f1ca60
  • Branches rewrite

Comments (0)

Files changed (4)

File happy_execute.py

 def RETURN_VALUE_USED(opline):
     return not (opline.get_result().EA_type & rad.APCFile.ZEND_znode.EXT_TYPE_UNUSED)
 
+def CV_OF_PTR(EG, i):
+    return EG.current_execute_data.CVs.address_of(i)
+
 def CV_OF(EG, i):
-    return zval_utils.array_of_zpp_ptr(EG.current_execute_data.CVs, i)
+    return CV_OF_PTR(EG, i)
 
 def CV_DEF_OF(EG, i):
     return EG.active_op_array.vars[i]
         raise Exception('Not implemented yet')
     return ptr
 
-# ptr is array_of_zpp_ptr
 def get_zval_cv_lookup(EG, ptr, var, type):
+    assert isinstance(ptr, zval_ptr_ptr_ptr)
     cv = CV_DEF_OF(EG, var)
 
     if (not EG.active_symbol_table) or\
         if type == tphp.ZendExecutor.BP_VAR_W:
             zval_utils.Z_ADDREF(EG.uninitialized_zval)
             if not EG.active_symbol_table:
-                ptr.assign(EG.current_execute_data.CVs[EG.active_op_array.last_var + var])
+                ptr.assign(EG.current_execute_data.CVs.address_of_ext(var))
                 ptr.deref().assign(EG.uninitialized_zval_ptr)
             else:
                 zend_hash_quick_update(EG.active_symbol_table, cv.name, len(cv.name) + 1, cv.hash_value,
                     EG.uninitialized_zval_ptr, 0, ptr)
-            return EG.current_execute_data.CVs[var]
+            return EG.current_execute_data.CVs.get(var)
         else:
             raise Exception('Not implemented!')
     return ptr.deref()
 
 def get_zval_ptr_cv(EG, node, type):
-    ptr = CV_OF(EG, node.var)
+    ptr = CV_OF_PTR(EG, node.var)
 
     if ptr.deref().is_null():
         return get_zval_cv_lookup(EG, ptr, node.var, type).deref()
     return ptr_ptr
 
 def get_zval_ptr_ptr_cv(EG, node, type):
-    ptr = CV_OF(EG, node.var)
+    ptr = CV_OF_PTR(EG, node.var)
 
-    if ptr.deref().deref().is_null():
+    if ptr.deref().is_null():
         return get_zval_cv_lookup(EG, ptr, node.var, type)
 
     return ptr.deref()

File happy_hash.py

 
 def _zend_hash_add_or_update(ht, arKey, nKeyLength, h,
                              pData, nDataSize, pDest, flag):
-    assert isinstance(pDest, array_of_zpp_ptr)
+    assert isinstance(pDest, zval_ptr_ptr_ptr)
     assert isinstance(pData, zval_ptr)
     if nKeyLength <= 0:
         return FAILURE
 
 def _zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h,
                                    pData, nDataSize, pDest, flag):
-    assert isinstance(pDest, array_of_zpp_ptr)
+    assert isinstance(pDest, zval_ptr_ptr_ptr)
     assert isinstance(pData, zval_ptr)
     if not nKeyLength:
         return zend_hash_index_update(ht, h, pData, nDataSize, pDest)
         raise Exception('use is_null() for casting to bool')
 
 
-class array_of_zpp_ptr(ptr):
-    def __init__(self, base, offset):
-        self.base = base
-        self.offset = offset
-
-    def assign(self, zpp):
-        assert isinstance(zpp, zval_ptr_ptr)
-        self.base[self.offset] = zpp
-
-    def deref(self):
-        return self.base[self.offset]
-
-    def is_null(self):
-        return not self.base
-
-    def __nonzero__(self):
-        raise Exception('use is_null() for casting to bool')
-
 class zend_class_entry:
     def __init__(self):
         pass

File targetphpstandalone.py

 null_zval_ptr_ptr = zval_ptr_ptr(null_zval_ptr, True)
 
 
+class CompiledVariables:
+    def __init__(self, cv_count, has_active_symbol_table):
+        # zval_ptr_ptr
+        self.__backend = []
+        for i in range(0, cv_count):
+            self.__backend.append(zval_ptr_ptr_ptr(null_zval_ptr_ptr, False))
+        # zval_ptr
+        self.__backend_ext = []
+        if not has_active_symbol_table:
+            for i in range(0, cv_count):
+                self.__backend_ext.append(zval_ptr_ptr(null_zval_ptr, False))
+
+    def address_of(self, i):
+        return self.__backend[i]
+
+    def address_of_ext(self, i):
+        return self.__backend_ext[i]
+
+    def get(self, i):
+        return self.__backend[i].deref()
+
+    def get_ext(self, i):
+        return self.__backend_ext[i].deref()
+
+
 class zend_execute_data:
     def __init__(self, op_array, has_active_symbol_table):
-        self.CVs = []
         cv_count = op_array.last_var
-        if not has_active_symbol_table:
-            cv_count *= 2
-        for i in range(0, cv_count):
-            self.CVs.append(zval_ptr_ptr(null_zval_ptr, False))
+        self.CVs = CompiledVariables(cv_count, has_active_symbol_table)
         self.Ts = []
         for i in range(0, op_array.T):
             self.Ts.append(temp_variable())
         self.EG.current_execute_data = execute_data.prev_execute_data
         if not self.EG.active_symbol_table:
             for cv_idx in range(execute_data.op_array.last_var):
-                cv = execute_data.CVs[cv_idx]
+                cv = execute_data.CVs.get(cv_idx)
                 if not cv.is_null():
                     zval_ptr_dtor(self.EG, cv)