Esempio n. 1
0
def check_reference(space, w_ref, fname):
    if not isinstance(w_ref, W_Reference):
        space.ec.hippy_warn("The built-in function %s() takes an argument "
                            "by reference, but didn't get a reference in "
                            "the indirect call" % (fname,))
        w_ref = W_Reference(w_ref)
    return w_ref
Esempio n. 2
0
 def test_call_args(self):
     space = ObjSpace()
     interp = MockInterpreter(space)
     sin = interp.locate_function("sin")
     w_res = space.call_args(sin, [space.wrap(1.2)])
     assert space.float_w(w_res) == math.sin(1.2)
     max = interp.locate_function("max")
     w_res = space.call_args(
         max, [space.wrap(2), space.wrap(15),
               space.wrap(3)])
     assert space.int_w(w_res) == 15
     w_res = space.call_args(
         max, [W_Reference(space.wrap(2)),
               space.wrap(15),
               space.wrap(3)])
     assert space.int_w(w_res) == 15
     str_repeat = interp.locate_function("str_repeat")
     w_res = space.call_args(str_repeat, [space.newstr("a"), space.wrap(3)])
     assert space.str_w(w_res) == "aaa"
     source = """<?php
     function f($a, $b) {
         return $a + 10 * $b;
     }
     """
     bc = compile_php('<input>', source, space, interp)
     interp.run_main(space, bc)
     f = interp.locate_function("f")
     w_res = space.call_args(f, [space.wrap(1), space.wrap(2)])
     assert space.int_w(w_res) == 21
Esempio n. 3
0
 def getvalue(self, space):
     assert self.is_static()
     r_value = self.r_value
     if not isinstance(r_value, W_Reference):
         return W_Reference(r_value.eval_static(space))
     else:
         return r_value
Esempio n. 4
0
def load_ref(space, fp, memo):
    fp.error_pos = fp.pos
    type_ = fp.readchr()
    if type_ == 'a':
        fp.expect(':')
        w_result = load_array(space, fp, memo)
    elif type_ == 'O':
        fp.expect(':')
        w_result = load_object(space, fp, memo)
    elif type_ == 'R':
        w_result = load_reference(fp, memo)
    elif type_ == 'r':
        w_temp = load_reference(fp, memo)
        w_result = W_Reference(w_temp.deref())
    else:
        w_result = W_Reference(load_primitive(space, fp, type_))
        memo.add_object_reference(w_result)
    return w_result
Esempio n. 5
0
 def _lookup_item_ref(self, space, w_arg):
     if self.klass.is_array_access:
         interp = space.ec.interpreter
         w_res = interp.call_method(self, 'offsetGet', [w_arg])
         if isinstance(w_res, W_Reference):
             return w_res
         else:
             if not isinstance(w_res, W_InstanceObject):
                 interp.notice("Indirect modification of overloaded element"
                               " of %s has no effect" % (self.klass.name, ))
             return W_Reference(w_res)
Esempio n. 6
0
    def _setitem_str(self, key, w_value, as_ref, unique_item=False):
        if not as_ref:
            cell = self._get_cell(jit.promote(self._globals_version), key)
            if cell is not None:
                w_old = cell.ref
                assert isinstance(w_old, W_Reference)
                w_old.store(w_value, unique_item)
                return self
            w_value = W_Reference(w_value)
        assert isinstance(w_value, W_Reference)

        self.set_var(key, w_value)
        gframe = self.space.ec.interpreter.global_frame
        if gframe is not None:
            gframe.set_ref_by_name(key, w_value)
        return self
Esempio n. 7
0
 def _create_fixed_iter(self, space, contextclass, byref):
     # not exactly correct, because it computes the list of returned
     # attributes at once.  We might see differences if the object
     # is modified during iteration.  "But well" for now.
     from hippy.objects.arrayiter import W_FixedIterator
     klass = self.getclass()
     items_w = []
     attrs = self.map.get_all_attrs()
     for attr in attrs:
         key = attr.name
         w_value = self.storage_w[attr.index]
         key1 = klass.check_access_and_demangle_property(key, contextclass)
         if key1 is not None:
             if byref and not isinstance(w_value, W_Reference):
                 w_value = W_Reference(w_value)
                 self.storage_w[attr.index] = w_value
             items_w.append((key1, w_value))
     return W_FixedIterator(items_w)
Esempio n. 8
0
 def _make_property(self, prop, w_initial_value):
     if isinstance(prop, tuple):
         name, access_flags = prop
         p = Property(name, self, access_flags)
         self.properties[name] = p
         self.property_decl.append(p)
         if not p.is_static():
             p.value = w_initial_value
         else:
             if not isinstance(w_initial_value, W_Object):
                 r_value = w_initial_value
             else:
                 r_value = W_Reference(w_initial_value)
             p.r_value = r_value
     elif not we_are_translated():  # compile time only
         prop = prop.build(self)
         self.properties[prop.name] = prop
         self.property_decl.append(prop)
Esempio n. 9
0
 def call_args(self,
               interp,
               args_w,
               w_this=None,
               thisclass=None,
               closureargs=None):
     from hippy.interpreter import Frame
     from hippy.objects.instanceobject import W_InstanceObject
     # XXX warn if too many arguments and this function does not call
     # func_get_arg() & friends
     if w_this is not None:
         assert isinstance(w_this, W_InstanceObject)
     newframe = Frame(interp, self.bytecode, self, thisclass, w_this)
     newframe.args_w = args_w  # save it for later, for func_get_args
     nb_args = len(args_w)
     for i in range(len(self.types)):
         if i < nb_args:
             # this argument was provided
             w_argument = args_w[i]
             if self.needs_value(i) and isinstance(w_argument, W_Reference):
                 w_argument = w_argument.deref()
         else:
             arg = self.defaults_w[i]
             if arg is None:
                 interp.warn("Missing argument %d for %s()" %
                             (i + 1, self.get_fullname()))
                 interp.notice("Undefined variable: %s" % (self.names[i]))
                 w_argument = interp.space.w_Null
             else:
                 w_argument = arg.eval_static(interp.space)
         newframe.vars_w[i] = w_argument
     if closureargs is not None:
         assert len(closureargs) == len(self.closuredecls)
         cl_start = len(self.types)
         if self.bytecode.this_var_num >= 0:
             cl_start += 1
         for i, decl in enumerate(self.closuredecls):
             r_var = closureargs[i]
             if not isinstance(r_var, W_Reference):
                 r_var = W_Reference(r_var)
             newframe.vars_w[cl_start + i] = r_var
     w_res = interp.interpret(newframe)
     assert w_res is not None
     return w_res
Esempio n. 10
0
 def do_get(self, interp, w_obj, attr, isref):
     key = (w_obj, attr)
     recursion = rec_custom_get_set
     if key in recursion:
         interp.notice("Undefined property: %s::$%s" % (self.name, attr))
         w_res = interp.space.w_Null
     else:
         recursion[key] = None
         try:
             method = self.method__get
             space = interp.space
             w_res = method.method_func.call_args(interp,
                                                  [space.newstr(attr)],
                                                  w_this=w_obj,
                                                  thisclass=self)
         finally:
             del recursion[key]
     if isref and not isinstance(w_res, W_Reference):
         interp.notice("Indirect modification of overloaded property "
                       "%s::$%s has no effect" % (self.name, attr))
         w_res = W_Reference(w_res)
     return w_res
Esempio n. 11
0
 def empty_ref(self):
     return W_Reference(self.w_Null)
Esempio n. 12
0
        cls = self.getclass()
        try:
            name = cls.lookup_property_name(LOOKUP_GETATTR, interp, self, attr,
                                            contextclass)
        except VisibilityError, e:
            if cls.method__get is not None:
                return cls.do_get(interp, self, attr, isref)
            raise e.reraise_property(interp)
        except SpecialPropertyReturn, e:
            return e.w_value
        mapattr = self.map.lookup(name)
        if mapattr is not None:
            w_value = self.storage_w[mapattr.index]
            if w_value is not None:
                if isref and not isinstance(w_value, W_Reference):
                    w_value = W_Reference(w_value)
                    self.storage_w[mapattr.index] = w_value
                return w_value
        if cls.method__get is not None:
            return cls.do_get(interp, self, attr, isref)
        if give_notice:
            interp.notice("Undefined property: %s::$%s" % (cls.name, attr))
        if isref:
            r_value = interp.space.empty_ref()
            self._create_attr(name, r_value)
            return r_value
        else:
            return interp.space.w_Null

    def getattr(self, interp, attr, contextclass=None, give_notice=False):
        return self._getattr(interp,
Esempio n. 13
0
def load_object(fp):
    fp.next_reference_obj -= 1
    needs_ref = (fp.next_reference_obj == 0)
    #
    fp.error_pos = fp.pos
    try:
        i = fp.consume(2)
    except SerializerError:
        i = fp.consume(1)
        if fp.s[i] == '}':
            fp.space.ec.notice("unserialize(): "
                               "Unexpected end of serialized data")
        raise
    s = fp.s
    tp = s[i]
    check_nonneg(i)
    check_nonneg(fp.pos)
    #
    if tp == 'i':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        i = fp.read_int_until(';')
        w_result = fp.space.wrap(i)
    #
    elif tp == 's':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        w_result = fp.space.newstr(load_str(fp, ';'))
    #
    elif tp == 'd':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        data = fp.read_substring_until(';')
        if data == 'INF':
            w_result = fp.space.wrap(rfloat.INFINITY)
        elif data == '-INF':
            w_result = fp.space.wrap(-rfloat.INFINITY)
        elif data == 'NAN':
            w_result = fp.space.wrap(rfloat.NAN)
        else:
            w_number, valid = convert_string_to_number(data)
            if not valid:
                raise SerializerError('bad double')
            w_result = fp.space.newfloat(w_number.float_w(fp.space))
    #
    elif tp == 'b':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        i = fp.consume(2)
        digit = s[i]
        if digit == '0':
            w_result = fp.space.w_False
        elif digit == '1':
            w_result = fp.space.w_True
        else:
            raise SerializerError('bad bool')
        if s[i + 1] != ';':
            raise SerializerError("';' expected")
    #
    elif tp == 'N':
        if s[i + 1] != ';':
            raise SerializerError("';' expected")
        w_result = fp.space.w_Null
    #
    elif tp == 'a':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        length = fp.read_int_until(':', can_be_negative=False)
        if length < 0:
            raise SerializerError("integer overflow")
        i = fp.consume(1)
        if s[i] != '{':
            raise SerializerError("'{' expected")
        w_result = None
        if needs_ref:
            w_result = fp.space.empty_ref()
            fp.save_reference(w_result)
        # first try to load the array as a direct list
        lst_w = []
        expected = ['i', ':', '0', ';']
        for n in range(length):
            i = fp.pos
            if i + len(expected) >= len(s):
                break
            for j in range(len(expected)):
                if s[i] != expected[j]:
                    break
                i += 1
            else:
                # ok, we got exactly 'i:N;' where N is the expected index
                fp.pos = i
                lst_w.append(load_object(fp))
                # increment the expected counter
                j = len(expected) - 2
                while j >= 2:
                    if expected[j] != '9':
                        expected[j] = chr(ord(expected[j]) + 1)
                        break
                    expected[j] = '0'
                    j -= 1
                else:
                    expected = ['i', ':', '1'] + expected[2:]
                continue
            break
        else:
            # we succeeded in loading the complete array as a list
            n = length
            _succeeded_as_a_list()   # for tests
        # fill in the remaining entries, if any, the slow way
        w_array = fp.space.new_array_from_list(lst_w)
        for n in range(n, length):
            w_key = load_array_key(fp)
            w_value = load_object(fp)
            w_array = fp.space.setitem_maybe_inplace(w_array, w_key, w_value)
        fp.expect_closing_brace()
        if w_result is not None:    # needs_ref
            w_result.store(w_array, unique=True)
            return w_result
        else:
            return w_array
    #
    elif tp == 'R':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        return load_reference(fp)
    #
    elif tp == 'r':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        return load_reference(fp).deref()
    #
    elif tp == 'O':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        klass_name = load_str(fp, ':')
        space = fp.space
        interp = space.ec.interpreter
        klass = interp.lookup_class_or_intf(klass_name)
        if klass is None:
            klass = k_incomplete
            w_instance = klass.get_empty_instance(space)
            w_instance.setattr(interp, '__PHP_Incomplete_Class_Name',
                               space.wrap(klass_name), None)
        else:
            w_instance = klass.get_empty_instance(space)
        w_result = w_instance
        if needs_ref:
            w_result = W_Reference(w_instance)
            fp.save_reference(w_result)
        count_attrs = fp.read_int_until(':')    # negative value accepted :-(
        i = fp.consume(1)
        if s[i] != '{':
            raise SerializerError("'{' expected")
        attrs = {}
        for i in xrange(count_attrs):
            w_attr = load_array_key(fp)
            w_value = load_object(fp)
            attr_name = space.str_w(w_attr)
            attrs[attr_name] = w_value
            w_instance.setattr(interp, attr_name, w_value, None)
        fp.expect_closing_brace()

        w_instance.unserialize(space, attrs)

        if '__wakeup' in klass.methods:
            klass.methods['__wakeup'].method_func.call_args(space.ec.interpreter,
                                                            [], w_this=w_instance,
                                                            thisclass=klass)
        return w_result
    #
    else:
        if tp == '}':
            fp.space.ec.notice("unserialize(): "
                               "Unexpected end of serialized data")
        raise SerializerError('malformed input')

    # this is for primitive types only; complex types 'return' above
    if needs_ref:
        w_result = W_Reference(w_result)
        fp.save_reference(w_result)
    return w_result
Esempio n. 14
0
 def reset_initial_value(self):
     self.value = self.w_initial_value
     if self.src is not None:
         self.r_value = self.src.r_value
     else:
         self.r_value = W_Reference(None)  # a new ref, lazily filled
Esempio n. 15
0
 def unset_ref(self, interp):
     self.store_ref(interp, W_Reference(interp.space.w_Null))
Esempio n. 16
0
 def store(self, interp, w_value, unique_item=False, give_notice=True):
     assert not give_notice
     return W_Reference(w_value)
Esempio n. 17
0
 def get_ref(self, interp, err_is_ref=True):
     return W_Reference(self.w_obj)
Esempio n. 18
0
 def lookup_ref(self, interp):
     return W_Reference(self.w_obj)