Commits

asuhan  committed cbd0b0c

add arg_types_stack

  • Participants
  • Parent commits 152092d

Comments (0)

Files changed (2)

     # It should parse correctly as float
     return W_float(rfloat.rstring_to_float(val_str))
 
+class InterpEntity(object):
+    def __init__(self):
+        pass
+
+class ZendFunction(InterpEntity):
+    def __init__(self, zend_fn):
+        self.zend_fn = zend_fn
+
 class W_object(object):
     def __init__(self):
         pass

File targetphpstandalone.py

         self.extend_vars(10000)
         self.execute_data = []
         self.arg_types_stack = []
+        self.This = None
 
         # args initialization
         top_name_table = self.script_ctx.names_to_idx[0]
         elif val_type == bcp.NULL_VAL:
             return W_null()
         elif val_type == bcp.IS_UNUSED:
-            return W_nothing()
+            return self.global_ctx.nullObject
         return default
 
     def _arrays_diff(self, lhs_array, rhs_array):
                 return const_tuple[0]
 
         # Constant not found
-        return W_nothing()
+        return self.global_ctx.nullObject
 
     def destruct(self, p):
         destroy_idx = p.destroy()
-        if destroy_idx != 0:
+        if destroy_idx:
             interp_func(self, destroy_idx, 0, 0)
 
     def pop_param(self):
         if not result.contains(key):
             result.set_value(key, rhs_wrapped.get_value(key).get_copy())
 
+class ArgTypesStackFrame(object):
+    def __init__(self, zend_fn, instance, class_entry):
+        self.zend_fn = zend_fn
+        self.instance = instance
+        self.class_entry = class_entry
+
 class ExecuteData(object):
     _virtualizable2_ = ['callee_param_count', 'var_count',
                         'var_base']
 
     def get_var_top(self):
         return self.var_base + self.var_count
-   
+
     @jit.unroll_safe
     def unref_params(self):
         for i in range(self.callee_param_count):
         else:
             class_name = class_entry.name.lower()
             method_name_idx = self.script_ctx.class_table[class_name][3]
-        if self.executor_globals.last_fn_name == 0:
+        if not self.executor_globals.last_fn_name:
             self.executor_globals.last_fn_name = method_name_idx
         else:
             self.executor_globals.fn_name_stack.append(
 
     def dispatch_init_method_call(self, opcode_info, opdata_info, pc,
             bytecode_off, current_func):
-        self.executor_globals.arg_types_stack.append(self.fbc)
-        self.executor_globals.arg_types_stack.append(self.object)
-        self.executor_globals.arg_types_stack.append(self.called_scope)
-        instance = self.get_wrapped_value(opcode_info.op1_type,
+        self.executor_globals.arg_types_stack.append(
+            ArgTypesStackFrame(self.fbc, self.object, self.called_scope))
+
+        function_name = self.get_wrapped_value(opcode_info.op2_type,
+            opcode_info.op2_val,
+            self.executor_globals.global_ctx.nullObject).to_str().lower()
+
+        if opcode_info.op1_type != bcp.IS_UNUSED:
+            instance = self.get_wrapped_value(opcode_info.op1_type,
                 opcode_info.op1_val,
                 self.executor_globals.global_ctx.nullObject)
-        method_name = self.get_wrapped_value(opcode_info.op2_type,
-                opcode_info.op2_val,
-                self.executor_globals.global_ctx.nullObject).to_str().lower()
+        else:
+            instance = self.executor_globals.This
+
         # not 100% sure about this
-        if isinstance(instance, W_nothing):
-            instance = self.executor_globals.param_stack[-current_func.callee_param_count]
+        if not instance:
+            raise Exception("Using $this when not in object context")
+
         # entry offset in bytecode array
-        fn_idx = instance.w_cls.vtable[method_name]
+        fn_idx = instance.w_cls.vtable[function_name]
         fn_flags = self.executor_globals.script_ctx.bc_idx_dict[fn_idx][1].op_array.fn_flags
         # this is probably not needed
         if fn_flags & bcp.ZEND_ACC_STATIC:
             instance = self.executor_globals.global_ctx.nullObject
         # put method name on name stack
         method_name_idx = -(fn_idx + 1)
-        if self.executor_globals.last_fn_name == 0:
+        if not self.executor_globals.last_fn_name:
             self.executor_globals.last_fn_name = method_name_idx
         else:
             self.executor_globals.fn_name_stack.append(method_name_idx)
                     self.get_var_top(), callee_param_count)
             if opcode_info.res_val != bcp.INVALID_PC:
                 self.set_var_value(opcode_info.res_val, res_value)
+        self.executor_globals.This = self.object
         return pc + 1
 
     def dispatch_fetch_obj_r(self, opcode_info, opdata_info, pc, bytecode_off):
         class_info = self.get_wrapped_value(opcode_info.op1_type,
                 opcode_info.op1_val,
                 self.executor_globals.global_ctx.nullObject).deref()
-        if self.executor_globals.last_fn_name == 0:
+        if not self.executor_globals.last_fn_name:
             self.executor_globals.last_fn_name = new_idx
         else:
             self.executor_globals.fn_name_stack.append(new_idx)
         obj = W_instance(class_info)
         obj.init_properties(self.script_ctx, self.executor_globals)
         self.set_var_value(opcode_info.res_val, obj, copy=False)
-        if class_info.construct_idx != 0:
+        self.object = obj
+        if class_info.construct_idx:
             interp_func(self.executor_globals, class_info.construct_idx,
                         self.get_var_top(), opcode_info.extended_value)
         return pc + 1
                 opcode_info.op1_val, nullObject).deref()
         rhs_wrapped = self.get_wrapped_value(opcode_info.op2_type,
                 opcode_info.op2_val, nullObject).deref()
-        result = W_nothing()
+        result = self.global_ctx.nullObject
         if  (isinstance(lhs_wrapped, W_array) and
              isinstance(rhs_wrapped, W_array) and
              (opcode_info.opcode == bcp.ZEND_ADD or