CompletionType evaluate()
    {
        Value* value = getScopeChain()->get("iid");
        if (!value->isString())
        {
            throw getErrorInstance("TypeError");
        }

        const char* iid = value->toString().c_str();

        Reflect::Interface interface;
        try
        {
            interface = es::getInterface(iid);
        }
        catch (...)
        {
            throw getErrorInstance("TypeError");
        }

        // Construct Interface Object
        ObjectValue* object = new ObjectValue;
        object->setCode(new InterfaceConstructor(object, iid));
        object->setPrototype(prototype);
        return CompletionType(CompletionType::Return, object, "");
    }
    std::string decode(std::string& uri, const std::string& reserved)
    {
        std::string result = "";
        int seq = 0;
        int k;
        for (k = 0; k < uri.length(); ++k)
        {
            char c = uri[k];
            if (c == '%')
            {
                if (uri.length() < k + 2)
                {
                    throw getErrorInstance("URIError");
                }

                c = getCode(uri, k);
                k += 2;
                if (seq == 0)
                {
                    while ((c & 1 << (7-seq)) && seq < 8)
                    {
                        ++seq;
                    }
                    if (0 < seq)
                    {
                        --seq;
                    }
                }
                else if (0 < seq)
                {
                    --seq;
                }

                if (reserved.find(c) != std::string::npos)
                {
                    result += uri[k-2];
                    result += uri[k-1];
                    result += uri[k];
                    continue;
                }
            }
            else if (seq)
            {
                throw getErrorInstance("URIError");
            }
            result += c;
        }
        return result;
    }
    std::string encode(std::string& uri, const std::string& unescapedSet)
    {
        int k;
        std::string result = "";
        for (k = 0; k < uri.length(); ++k)
        {
            char c = uri[k];
            if (unescapedSet.find(c) == std::string::npos)
            {
                int seq = 0;
                while ((c & 1 << (7-seq)))
                {
                    if (4 < ++seq)
                    {
                        throw getErrorInstance("URIError");
                    }
                }
                if (seq == 0 && isUnescaped(c, unescapedSet))
                {
                    result += c;
                    continue;
                }

                char escaped[4];
                while (k < uri.length())
                {
                    sprintf(escaped, "%%%02X", static_cast<u8>(uri[k]));
                    result += escaped;
                    if (--seq <= 0)
                    {
                        break;
                    }
                    ++k;
                }
                if (0 < seq)
                {
                    throw getErrorInstance("URIError");
                }
            }
            else
            {
                result += c;
            }
        }

        return result;
    }
 CompletionType evaluate()
 {
     InterfacePointerValue* object = dynamic_cast<InterfacePointerValue*>(getThis());
     if (!object)
     {
         throw getErrorInstance("TypeError");
     }
     ListValue* list = static_cast<ListValue*>(getScopeChain()->get("arguments"));
     Register<Value> value = invoke(iid, number, object, list);
     return CompletionType(CompletionType::Return, value, "");
 }
ObjectValue*
StringValue::toObject()
{
    // Create a new String object
    ObjectValue* string = dynamic_cast<ObjectValue*>(getGlobal()->get("String"));
    if (!string || !string->getCode())
    {
        throw getErrorInstance("TypeError");
    }
    Register<ListValue> list = new ListValue;
    list->push(this);
    return string->construct(list);
};
    // Query interface for this interface.
    CompletionType evaluate()
    {
        if (constructor->hasInstance(getThis()))
        {
            // Constructor
            Object* constructor = es::getConstructor(iid.c_str());
            if (!constructor)
            {
                throw getErrorInstance("TypeError");
            }
            // TODO: Currently only the default constructor is supported
            std::string ciid = iid;
            ciid += "::Constructor";
            Value* value = invoke(ciid.c_str(), 0, reinterpret_cast<InterfaceMethod**>(constructor), 0);
            return CompletionType(CompletionType::Return, value, "");
        }
        else
        {
            // Cast
            InterfacePointerValue* self = dynamic_cast<InterfacePointerValue*>(getScopeChain()->get("object"));
            if (!self)
            {
                throw getErrorInstance("TypeError");
            }

            Object* object;
            object = self->getObject();
            if (!object || !(object = reinterpret_cast<Object*>(object->queryInterface(iid.c_str()))))
            {
                // We should throw an error in case called by a new expression.
                throw getErrorInstance("TypeError");
            }

            ObjectValue* value = new InterfacePointerValue(object);
            value->setPrototype(prototype);
            return CompletionType(CompletionType::Return, value, "");
        }
    }
static Value* invoke(const char* iid, int number, InterfacePointerValue* object, ListValue* list)
{
    InterfaceMethod** self = reinterpret_cast<InterfaceMethod**>(object->getObject());
    if (!self)
    {
        throw getErrorInstance("TypeError");
    }
    Value* value = invoke(iid, number, self, list);
    if (strcmp(iid, Object::iid()) == 0 && number == 2)   // Object::release()
    {
        object->clearObject();
    }
    return value;
}
Exemple #8
0
void
MsgHandler::initOutputOptions(bool gui)
{
    OptionsCont& oc = OptionsCont::getOptions();
    //getMessageInstance()->report2cout(!gui && oc.getBool("verbose"));
    getMessageInstance()->report2cout(true);
    getWarningInstance()->report2cerr(!gui && !oc.getBool("suppress-warnings"));
    // build the logger if possible
    if (oc.isSet("log-file")) {
        try {
            OutputDevice *logFile = &OutputDevice::getDevice(oc.getString("log-file"));
            getErrorInstance()->addRetriever(logFile);
            getWarningInstance()->addRetriever(logFile);
            getMessageInstance()->addRetriever(logFile);
        } catch (IOError &) {
            throw ProcessError("Could not build logging file '" + oc.getString("log-file") + "'");
        }
    }
    if (oc.isSet("message-log")) {
        try {
            OutputDevice *logFile = &OutputDevice::getDevice(oc.getString("message-log"));
            getMessageInstance()->addRetriever(logFile);
        } catch (IOError &) {
            throw ProcessError("Could not build logging file '" + oc.getString("message-log") + "'");
        }
    }
    if (oc.isSet("error-log")) {
        try {
            OutputDevice *logFile = &OutputDevice::getDevice(oc.getString("error-log"));
            getErrorInstance()->addRetriever(logFile);
            getWarningInstance()->addRetriever(logFile);
        } catch (IOError &) {
            throw ProcessError("Could not build logging file '" + oc.getString("error-log") + "'");
        }
    }
}
    int getInt(char hex)
    {
        if (!isxdigit(hex))
        {
            return -1;
        }
        if ('0' <= hex && hex <= '9')
        {
            return hex - '0';
        }
        if ('a' <= hex && hex <= 'f')
        {
            return hex - 'a' + 0x0A;
        }
        if ('A' <= hex && hex <= 'F')
        {
            return hex - 'A' + 0x0A;
        }

        throw getErrorInstance("URIError");
    }
static Value* invoke(const char* iid, int number, InterfaceMethod** self, ListValue* list)
{
    if (!self)
    {
        throw getErrorInstance("TypeError");
    }

    Reflect::Interface interface = es::getInterface(iid);
    Reflect::Method method(interface.getMethod(number));
    PRINTF("invoke %s.%s(%p)\n", interface.getName().c_str(), method.getName().c_str(), self);

    // Set up parameters
    Any argv[9];
    Any* argp = argv;
    int ext = 0;    // extra parameter count

    // Set this
    *argp++ = Any(reinterpret_cast<intptr_t>(self));

    // In the following implementation, we assume no out nor inout attribute is
    // used for parameters.

    Reflect::Type returnType = method.getReturnType();
    switch (returnType.getType())
    {
    case Reflect::kAny:
        // Any op(void* buf, int len, ...);
        // FALL THROUGH
    case Reflect::kString:
        // const char* op(xxx* buf, int len, ...);
        *argp++ = Any(reinterpret_cast<intptr_t>(heap));
        *argp++ = Any(sizeof(heap));
        break;
    case Reflect::kSequence:
        // int op(xxx* buf, int len, ...);
        *argp++ = Any(reinterpret_cast<intptr_t>(heap));
        ++ext;
        *argp++ = Any(static_cast<int32_t>(((*list)[0])->toNumber()));
        break;
    case Reflect::kArray:
        // void op(xxx[x] buf, ...);
        *argp++ = Any(reinterpret_cast<intptr_t>(heap));
        break;
    }

    Reflect::Parameter param = method.listParameter();
    for (int i = ext; param.next(); ++i, ++argp)
    {
        Reflect::Type type(param.getType());
        Value* value = (*list)[i];
        switch (type.getType())
        {
        case Reflect::kAny:
            // Any variant, ...
            switch (value->getType()) {
            case Value::BoolType:
                *argp = Any(static_cast<bool>(value->toBoolean()));
                break;
            case Value::StringType:
                *argp = Any(value->toString().c_str());
                break;
            case Value::NumberType:
                *argp = Any(static_cast<double>(value->toNumber()));
                break;
            case Value::ObjectType:
                if (InterfacePointerValue* unknown = dynamic_cast<InterfacePointerValue*>(value))
                {
                    *argp = Any(unknown->getObject());
                }
                else
                {
                    // XXX expose ECMAScript object
                    *argp = Any(static_cast<Object*>(0));
                }
                break;
            default:
                *argp = Any();
                break;
            }
            argp->makeVariant();
            break;
        case Reflect::kSequence:
            // xxx* buf, int len, ...
            // XXX Assume sequence<octet> now...
            *argp++ = Any(reinterpret_cast<intptr_t>(value->toString().c_str()));
            value = (*list)[++i];
            *argp = Any(static_cast<int32_t>(value->toNumber()));
            break;
        case Reflect::kString:
            *argp = Any(value->toString().c_str());
            break;
        case Reflect::kArray:
            // void op(xxx[x] buf, ...);
            // XXX expand data
            break;
        case Reflect::kObject:
            if (InterfacePointerValue* unknown = dynamic_cast<InterfacePointerValue*>(value))
            {
                *argp = Any(unknown->getObject());
            }
            else
            {
                *argp = Any(static_cast<Object*>(0));
            }
            break;
        case Reflect::kBoolean:
            *argp = Any(static_cast<bool>(value->toBoolean()));
            break;
        case Reflect::kPointer:
            *argp = Any(static_cast<intptr_t>(value->toNumber()));
            break;
        case Reflect::kShort:
            *argp = Any(static_cast<int16_t>(value->toNumber()));
            break;
        case Reflect::kLong:
            *argp = Any(static_cast<int32_t>(value->toNumber()));
            break;
        case Reflect::kOctet:
            *argp = Any(static_cast<uint8_t>(value->toNumber()));
            break;
        case Reflect::kUnsignedShort:
            *argp = Any(static_cast<uint16_t>(value->toNumber()));
            break;
        case Reflect::kUnsignedLong:
            *argp = Any(static_cast<uint32_t>(value->toNumber()));
            break;
        case Reflect::kLongLong:
            *argp = Any(static_cast<int64_t>(value->toNumber()));
            break;
        case Reflect::kUnsignedLongLong:
            *argp = Any(static_cast<uint64_t>(value->toNumber()));
            break;
        case Reflect::kFloat:
            *argp = Any(static_cast<float>(value->toNumber()));
            break;
        case Reflect::kDouble:
            *argp = Any(static_cast<double>(value->toNumber()));
            break;
        default:
            break;
        }
    }

    // Invoke method
    Register<Value> value;
    unsigned methodNumber = interface.getInheritedMethodCount() + number;
    int argc = argp - argv;
    switch (returnType.getType())
    {
    case Reflect::kAny:
        {
            Any result = apply(argc, argv, (Any (*)()) ((*self)[methodNumber]));
            switch (result.getType())
            {
            case Any::TypeVoid:
                value = NullValue::getInstance();
                break;
            case Any::TypeBool:
                value = BoolValue::getInstance(static_cast<bool>(result));
                break;
            case Any::TypeOctet:
                value = new NumberValue(static_cast<uint8_t>(result));
                break;
            case Any::TypeShort:
                value = new NumberValue(static_cast<int16_t>(result));
                break;
            case Any::TypeUnsignedShort:
                value = new NumberValue(static_cast<uint16_t>(result));
                break;
            case Any::TypeLong:
                value = new NumberValue(static_cast<int32_t>(result));
                break;
            case Any::TypeUnsignedLong:
                value = new NumberValue(static_cast<uint32_t>(result));
                break;
            case Any::TypeLongLong:
                value = new NumberValue(static_cast<int64_t>(result));
                break;
            case Any::TypeUnsignedLongLong:
                value = new NumberValue(static_cast<uint64_t>(result));
                break;
            case Any::TypeFloat:
                value = new NumberValue(static_cast<float>(result));
                break;
            case Any::TypeDouble:
                value = new NumberValue(static_cast<double>(result));
                break;
            case Any::TypeString:
                if (const char* string = static_cast<const char*>(result))
                {
                    value = new StringValue(string);
                }
                else
                {
                    value = NullValue::getInstance();
                }
                break;
            case Any::TypeObject:
                if (Object* unknown = static_cast<Object*>(result))
                {
                    ObjectValue* instance = new InterfacePointerValue(unknown);
                    instance->setPrototype(getGlobal()->get(es::getInterface(Object::iid()).getName())->get("prototype"));   // XXX Should use IID
                    value = instance;
                }
                else
                {
                    value = NullValue::getInstance();
                }
                break;
            default:
                value = NullValue::getInstance();
                break;
            }
        }
        break;
    case Reflect::kBoolean:
        value = BoolValue::getInstance(static_cast<bool>(apply(argc, argv, (bool (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kOctet:
        value = new NumberValue(static_cast<uint8_t>(apply(argc, argv, (uint8_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kShort:
        value = new NumberValue(static_cast<int16_t>(apply(argc, argv, (int16_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kUnsignedShort:
        value = new NumberValue(static_cast<uint16_t>(apply(argc, argv, (uint16_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kLong:
        value = new NumberValue(static_cast<int32_t>(apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kUnsignedLong:
        value = new NumberValue(static_cast<uint32_t>(apply(argc, argv, (uint32_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kLongLong:
        value = new NumberValue(static_cast<int64_t>(apply(argc, argv, (int64_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kUnsignedLongLong:
        value = new NumberValue(static_cast<uint64_t>(apply(argc, argv, (uint64_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kFloat:
        value = new NumberValue(static_cast<float>(apply(argc, argv, (float (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kDouble:
        value = new NumberValue(apply(argc, argv, (double (*)()) ((*self)[methodNumber])));
        break;
    case Reflect::kPointer:
        value = new NumberValue(static_cast<intptr_t>(apply(argc, argv, (intptr_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kString:
        {
            heap[0] = '\0';
            Any result = apply(argc, argv, (const char* (*)()) ((*self)[methodNumber]));
            if (const char* string = static_cast<const char*>(result))
            {
                value = new StringValue(string);
            }
            else
            {
                value = NullValue::getInstance();
            }
        }
        break;
    case Reflect::kSequence:
        {
            // XXX Assume sequence<octet> now...
            int32_t count = apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber]));
            if (count < 0)
            {
                count = 0;
            }
            heap[count] = '\0';
            value = new StringValue(heap);
        }
        break;
    case Reflect::kObject:
        if (Object* unknown = apply(argc, argv, (Object* (*)()) ((*self)[methodNumber])))
        {
            ObjectValue* instance = new InterfacePointerValue(unknown);
            // TODO: check Object and others
            instance->setPrototype(getGlobal()->get(es::getInterface(returnType.getQualifiedName().c_str()).getName())->get("prototype"));   // XXX Should use IID
            value = instance;
        }
        else
        {
            value = NullValue::getInstance();
        }
        break;
    case Reflect::kVoid:
        apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber]));
        value = NullValue::getInstance();
        break;
    }
    return value;
}
 CompletionType evaluate()
 {
     Register<Value> value;
     switch (method)
     {
     case ToString:
     case ValueOf:
         if (!getThis()->isObject())
         {
             throw getErrorInstance("TypeError");
         }
         value = static_cast<ObjectValue*>(getThis())->getValueProperty();
         if (!value->isString())
         {
             throw getErrorInstance("TypeError");
         }
         break;
     case CharAt:
         value = charAt();
         break;
     case CharCodeAt:
         value = charCodeAt();
         break;
     case Concat:
         value = concat(getThis());
         break;
     case IndexOf:
         value = indexOf(getThis());
         break;
     case LastIndexOf:
         value = lastIndexOf(getThis());
         break;
     case LocaleCompare:
         value = localeCompare(getThis());
         break;
     case Match:
         value = stringMatch();
         break;
     case Replace:
         value = stringReplace();
         break;
     case Search:
         value = stringSearch();
         break;
     case Slice:
         value = slice(getThis());
         break;
     case Split:
         value = stringSplit();
         break;
     case Substring:
         value = substring(getThis());
         break;
     case Substr:
         value = substr(getThis());
         break;
     case ToLowerCase:
     case ToLocaleLowerCase:
         value = toLowerCase(getThis());
         break;
     case ToUpperCase:
     case ToLocaleUpperCase:
         value = toUpperCase(getThis());
         break;
     }
     return CompletionType(CompletionType::Return, value, "");
 }