示例#1
0
eCodes WsEncoder::encode()
{
    PARROT_ASSERT(_currPkt.get());

    eCodes res    = eCodes::ST_Ok;
    auto   opCode = _currPkt->getOpCode();

    if (opCode == eOpCode::Binary)
    {
        // Encode binary data.
        res = encodeDataPacket();
    }
    else if (opCode == eOpCode::Close)
    {
        // Encode close packet.
        res = encodeClosePacket();
    }
    else if (opCode == eOpCode::Ping || opCode == eOpCode::Pong)
    {
        // Encode heartbeat packet.
        res = encodePingPong();
    }
    else
    {
        PARROT_ASSERT(false);
    }

    return res;
}
示例#2
0
void SslServerConn::createSsl()
{
    if (_ssl)
    {
        PARROT_ASSERT(false);
    }
    _ssl = SslHelper::genSsl(_sslCtx);
    PARROT_ASSERT(_ssl);
    BIO* bio = BIO_new_socket(getFd(), BIO_NOCLOSE);
    SSL_set_bio(_ssl, bio, bio);
}
示例#3
0
文件: list.c 项目: Cristofor/parrot
PARROT_EXPORT
PARROT_CAN_RETURN_NULL
List_Item_Header*
Parrot_list_remove(SHIM_INTERP, ARGMOD(Linked_List *list), ARGMOD(List_Item_Header *item))
{
    ASSERT_ARGS(Parrot_list_remove)

    List_Item_Header *next = item->next;
    List_Item_Header *prev = item->prev;

    PARROT_ASSERT(list == item->owner);

    /* First item */
    if (list->first == item)
        list->first = next;

    if (list->last == item)
        list->last = prev;

    if (prev)
        prev->next = next;
    if (next)
        next->prev = prev;

    list->count--;
    return item;
}
示例#4
0
文件: list.c 项目: Cristofor/parrot
PARROT_EXPORT
INTVAL
Parrot_list_check(SHIM_INTERP, ARGIN(Linked_List *list))
{
    ASSERT_ARGS(Parrot_list_check)

    List_Item_Header *tmp = list->first;
    size_t counter = 0;

    while (tmp) {
        List_Item_Header *next = tmp->next;
        PARROT_ASSERT(tmp->owner == list);
        tmp = next;
        ++counter;
        PARROT_ASSERT(counter <= list->count);
    }

    return 1;
}
示例#5
0
文件: piremit.c 项目: parrot/pirc
/*

=item C<void print_target(lexer_state * const lexer, target * const t)>

Print the target C<t>; if C<t> has a key, that key is
printed as well. Examples:

 S1, P1[42]

=cut

*/
void
print_target(ARGIN(lexer_state * const lexer),  ARGIN(target * const t))
{
    ASSERT_ARGS(print_target)
    PARROT_ASSERT(t->info);
    fprintf(out, "%c%d", pir_register_types[t->info->type], t->info->color);

    /* if the target has a key, print that too */
    if (t->key)
        print_key(lexer, t->key);
}
示例#6
0
static void
mark_interp(PARROT_INTERP)
{
    ASSERT_ARGS(mark_interp)
    PObj *obj;
    /* mark the list of iglobals */
    Parrot_gc_mark_PMC_alive(interp, interp->iglobals);

    /* mark the current continuation */
    obj = (PObj *)interp->current_cont;
    if (obj && obj != (PObj *)NEED_CONTINUATION)
        Parrot_gc_mark_PMC_alive(interp, (PMC *)obj);

    /* mark the current context. */
    Parrot_gc_mark_PMC_alive(interp, CURRENT_CONTEXT(interp));

    /* mark the vtables: the data, Class PMCs, etc. */
    Parrot_vtbl_mark_vtables(interp);

    /* mark the root_namespace */
    Parrot_gc_mark_PMC_alive(interp, interp->root_namespace);

    /* mark the concurrency scheduler */
    Parrot_gc_mark_PMC_alive(interp, interp->scheduler);

    /* mark caches and freelists */
    mark_object_cache(interp);

    /* Now mark the class hash */
    Parrot_gc_mark_PMC_alive(interp, interp->class_hash);

    /* Now mark the HLL stuff */
    Parrot_gc_mark_PMC_alive(interp, interp->HLL_info);
    Parrot_gc_mark_PMC_alive(interp, interp->HLL_namespace);

    /* Mark the registry */
    PARROT_ASSERT(interp->gc_registry);
    Parrot_gc_mark_PMC_alive(interp, interp->gc_registry);

    /* Mark the MMD cache. */
    if (interp->op_mmd_cache)
        Parrot_mmd_cache_mark(interp, interp->op_mmd_cache);

    /* Walk the iodata */
    Parrot_IOData_mark(interp, interp->piodata);

    if (!PMC_IS_NULL(interp->final_exception))
        Parrot_gc_mark_PMC_alive(interp, interp->final_exception);

    if (interp->parent_interpreter)
        mark_interp(interp->parent_interpreter);
}
示例#7
0
void
imcc_init_tables(PARROT_INTERP)
{
    ASSERT_ARGS(imcc_init_tables)
    const char *writes[] = {
        "cleari", "clearn", "clearp", "clears",
    };
    /* init opnums */
    if (!w_special[0]) {
        size_t i;
        for (i = 0; i < N_ELEMENTS(writes); i++) {
            const int n = interp->op_lib->op_code(writes[i], 1);
            PARROT_ASSERT(n);
            w_special[i] = n;
        }
    }
}
示例#8
0
eCodes WsEncoder::loadBuff()
{
    eCodes res;

    while (!_pktList.empty())
    {
        if (!_currPkt)
        {
            _currPkt = std::move(*_pktList.begin());
            _pktList.pop_front();
        }

        res = encode();

        // Reset mask begin pointer. The packet was encoded, or the buffer
        // is full, we need to send the packet next time.
        _maskBeginPtr = nullptr;

        if (res == eCodes::ST_BufferFull)
        {
            _needSendLen = _currPtr - &(*_sendVec.begin());
            _currPtr     = &(*_sendVec.begin());
            return eCodes::ST_Ok;
        }
        else if (res == eCodes::ST_Complete)
        {
            _writeState = eWriteState::None;
            _srcPtr     = nullptr;
            _srcEndPtr  = nullptr;

            _sysJsonStr.clear();
            _jsonStr.clear();
            _currPkt.reset();
        }
        else
        {
            PARROT_ASSERT(false);
        }
    }

    // If here, no packet left in pkt list.
    return eCodes::ST_Complete;
}
示例#9
0
void
mark_special(PARROT_INTERP, ARGMOD(Memory_Pools *mem_pools), ARGIN(PMC *obj))
{
    ASSERT_ARGS(mark_special)

    PObj_get_FLAGS(obj) |= PObj_custom_GC_FLAG;

    /* clearing the flag is much more expensive then testing */
    if (!PObj_needs_early_gc_TEST(obj))
        PObj_high_priority_gc_CLEAR(obj);

    /* mark properties */
    Parrot_gc_mark_PMC_alive(interp, PMC_metadata(obj));

    if (PObj_custom_mark_TEST(obj)) {
        PARROT_ASSERT(!PObj_on_free_list_TEST(obj));
        VTABLE_mark(interp, obj);
    }
}
示例#10
0
int
Parrot_gc_trace_root(PARROT_INTERP,
        ARGMOD(Memory_Pools *mem_pools),
        Parrot_gc_trace_type trace)
{
    ASSERT_ARGS(Parrot_gc_trace_root)
    PObj    *obj;

    /* note: adding locals here did cause increased GC runs */
    mark_context_start();

    if (trace == GC_TRACE_SYSTEM_ONLY) {
        trace_system_areas(interp, mem_pools);
        return 0;
    }

    /* We have to start somewhere; the interpreter globals is a good place */
    if (!mem_pools->gc_mark_start) {
        mem_pools->gc_mark_start
            = mem_pools->gc_mark_ptr
            = interp->iglobals;
    }

    /* mark the list of iglobals */
    Parrot_gc_mark_PMC_alive(interp, interp->iglobals);

    /* mark the current continuation */
    obj = (PObj *)interp->current_cont;
    if (obj && obj != (PObj *)NEED_CONTINUATION)
        Parrot_gc_mark_PMC_alive(interp, (PMC *)obj);

    /* mark the current context. */
    Parrot_gc_mark_PMC_alive(interp, CURRENT_CONTEXT(interp));

    /* mark the dynamic environment. */
    Parrot_gc_mark_PMC_alive(interp, interp->dynamic_env);

    /* mark the vtables: the data, Class PMCs, etc. */
    mark_vtables(interp);

    /* mark the root_namespace */
    Parrot_gc_mark_PMC_alive(interp, interp->root_namespace);

    /* mark the concurrency scheduler */
    Parrot_gc_mark_PMC_alive(interp, interp->scheduler);

    /* s. packfile.c */
    mark_const_subs(interp);

    /* mark caches and freelists */
    mark_object_cache(interp);

    /* Now mark the class hash */
    Parrot_gc_mark_PMC_alive(interp, interp->class_hash);

    /* Now mark the HLL stuff */
    Parrot_gc_mark_PMC_alive(interp, interp->HLL_info);
    Parrot_gc_mark_PMC_alive(interp, interp->HLL_namespace);

    /* Mark the registry */
    PARROT_ASSERT(interp->gc_registry);
    Parrot_gc_mark_PMC_alive(interp, interp->gc_registry);

    /* Mark the MMD cache. */
    if (interp->op_mmd_cache)
        Parrot_mmd_cache_mark(interp, interp->op_mmd_cache);

    /* Walk the iodata */
    Parrot_IOData_mark(interp, interp->piodata);

    if (trace == GC_TRACE_FULL)
        trace_system_areas(interp, mem_pools);

    /* quick check to see if we have already marked all impatient PMCs. If we
       have, return 0 and exit here. This will alert other parts of the GC
       that if we are in a lazy run we can just stop it. */
    if (mem_pools->lazy_gc
    &&  mem_pools->num_early_PMCs_seen >= mem_pools->num_early_gc_PMCs)
        return 0;

    return 1;
}
示例#11
0
eIoAction SslServerConn::handleIoEvent()
{
    while (true)
    {
        switch (_state)
        {
            case eSslState::Handshake:
            {
                createSsl();
                eCodes code = doSslAccept();

                if (code == eCodes::ST_RetryWhenWritable)
                {
                    return eIoAction::Write;
                }
                else if (code == eCodes::ST_RetryWhenReadable)
                {
                    return eIoAction::Read;
                }
                else if (code == eCodes::ST_Ok)
                {
                    _state = eSslState::Connected;
                    return _ioHandler->onConnected();
                }
                else
                {
                    return eIoAction::Remove;
                }
            }
            break;

            case eSslState::Connected:
            {
                if (isError() || isEof())
                {
                    // Todo: Notifier uplayer
                    _ioHandler->onError(_errorCode);
                    return eIoAction::Remove;
                }

                eIoAction act;
                if (isWriteAvail())
                {
                    act = _ioHandler->onWritable();
                    if (act == eIoAction::Remove)
                    {
                        _state = eSslState::Shutdown;
                        continue;
                    }
                    return act;
                }

                if (isReadAvail())
                {
                    act = _ioHandler->onReadable();
                    if (act == eIoAction::Remove)
                    {
                        _state = eSslState::Shutdown;
                        continue;
                    }
                    return act;
                }

                PARROT_ASSERT(false);
                return eIoAction::None;
            }
            break;

            case eSslState::Shutdown:
            {
                eCodes code = SslHelper::closeSsl(_ssl);
                if (code == eCodes::ST_RetryWhenReadable)
                {
                    return eIoAction::Read;
                }
                else if (code == eCodes::ST_RetryWhenWritable)
                {
                    return eIoAction::Write;
                }
                else
                {
                    return eIoAction::Remove;
                }
            }
            break;

            default:
            {
                PARROT_ASSERT(false);
            }
        }
    }
}
示例#12
0
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static STRING *
to_encoding(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
{
    ASSERT_ARGS(to_encoding)
#if PARROT_HAS_ICU
    UErrorCode err;
    int dest_len;
    UChar *p;
#endif
    int src_len;
    int in_place = dest == NULL;
    STRING *result;

    if (src->encoding == Parrot_utf16_encoding_ptr ||
            src->encoding == Parrot_ucs2_encoding_ptr)
        return in_place ? src : Parrot_str_copy(interp, src);
    /*
     * TODO adapt string creation functions
     */
    src_len = src->strlen;
    if (in_place) {
        result = src;
    }
    else {
        result = dest;
    }
    if (!src_len) {
        result->charset  = Parrot_unicode_charset_ptr;
        result->encoding = Parrot_ucs2_encoding_ptr;
        result->strlen = result->bufused = 0;
        return result;
    }
    /*
       u_strFromUTF8(UChar *dest,
       int32_t destCapacity,
       int32_t *pDestLength,
       const char *src,
       int32_t srcLength,
       UErrorCode *pErrorCode);
       */
#if PARROT_HAS_ICU
    if (in_place) {
        /* need intermediate memory */
        p = (UChar *)mem_sys_allocate(src_len * sizeof (UChar));
    }
    else {
        Parrot_gc_reallocate_string_storage(interp, dest, sizeof (UChar) * src_len);
        p = (UChar *)dest->strstart;
    }
    if (src->charset == Parrot_iso_8859_1_charset_ptr ||
            src->charset == Parrot_ascii_charset_ptr) {
        for (dest_len = 0; dest_len < (int)src->strlen; ++dest_len) {
            p[dest_len] = (UChar)((unsigned char*)src->strstart)[dest_len];
        }
    }
    else {
        err = U_ZERO_ERROR;
        u_strFromUTF8(p, src_len,
                &dest_len, src->strstart, src->bufused, &err);
        if (!U_SUCCESS(err)) {
            /*
             * have to resize - required len in UChars is in dest_len
             */
            if (in_place)
                p = (UChar *)mem_sys_realloc(p, dest_len * sizeof (UChar));
            else {
                result->bufused = dest_len * sizeof (UChar);
                Parrot_gc_reallocate_string_storage(interp, dest,
                                         sizeof (UChar) * dest_len);
                p = (UChar *)dest->strstart;
            }
            u_strFromUTF8(p, dest_len,
                    &dest_len, src->strstart, src->bufused, &err);
            PARROT_ASSERT(U_SUCCESS(err));
        }
    }
    result->bufused = dest_len * sizeof (UChar);
    if (in_place) {
        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
        memcpy(src->strstart, p, src->bufused);
        mem_sys_free(p);
    }
    result->charset  = Parrot_unicode_charset_ptr;
    result->encoding = Parrot_utf16_encoding_ptr;
    result->strlen = src_len;

    /* downgrade if possible */
    if (dest_len == (int)src->strlen)
        result->encoding = Parrot_ucs2_encoding_ptr;
    return result;
#else
    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
        "no ICU lib loaded");
#endif
}
示例#13
0
eCodes WsEncoder::encodeRawPacket()
{
    switch (_writeState)
    {
        case eWriteState::None:
        {
            auto& raw = _currPkt->getPayload();
            PARROT_ASSERT(!raw.empty());
            computeComponentLen(raw.size());

            _writeState  = eWriteState::Header;
            _srcPtr      = &(*raw.begin());
            _srcEndPtr   = &(*raw.end());
            _firstPacket = true;
        }
        // No break;

        case eWriteState::Header:
        {
            if ((_sendVecEndPtr - _currPtr) < _headerLen)
            {
                // Left space is not enough.
                return eCodes::ST_BufferFull;
            }

            bool fin = true;
            if (_fragmented)
            {
                if (static_cast<uint64_t>(_srcEndPtr - _srcPtr) <= _payloadLen)
                {
                    // The last packet. fin should be true.

                    _payloadLen = _srcEndPtr - _srcPtr;
                }
                else
                {
                    fin = false;
                }
            }

            writeHeader(_firstPacket, fin);
            if (_firstPacket)
            {
                _firstPacket = false;
            }

            _writeState        = eWriteState::Raw;
            _maskKeyIdx        = 0;
            _payloadEncodedLen = 0;
        }
        // No break;

        case eWriteState::Raw:
        {
            _maskBeginPtr = _currPtr;
            for (;
                 _payloadEncodedLen < _payloadLen && _currPtr != _sendVecEndPtr;
                 ++_payloadEncodedLen, ++_currPtr)
            {
                *_currPtr = _srcPtr[_payloadEncodedLen];
            }

            if (_needMask)
            {
                maskPacket(_maskBeginPtr, _currPtr);
            }

            if (_payloadEncodedLen == _payloadLen)
            {
                // Encoded one packet.
                _srcPtr += _payloadEncodedLen;
                if (_srcPtr == _srcEndPtr)
                {
                    // WsPacket has been encoded.
                    return eCodes::ST_Complete;
                }

                // The WsPacket has been fragmented, we need to encode
                // another packet, write header next.
                _writeState = eWriteState::Header;
                return encodeRawPacket();
            }
            else
            {
                // Not enough space to encode a packet.
                return eCodes::ST_BufferFull;
            }
        }
        break;

        default:
        {
            PARROT_ASSERT(false);
        }
    }

    // Should never be here.
    PARROT_ASSERT(false);
    return eCodes::ST_Ok;
}
示例#14
0
eCodes WsEncoder::encodeMeta()
{
    if (!_maskBeginPtr)
    {
        _maskBeginPtr = _currPtr;
    }

    uint8_t copyLen = (_sendVecEndPtr - _currPtr > _srcEndPtr - _currPtr)
                          ? (_srcEndPtr - _currPtr)
                          : (_sendVecEndPtr - _currPtr);

    std::memcpy(_currPtr, _srcPtr, copyLen);
    _payloadEncodedLen += copyLen;
    _encodedLen += copyLen;
    _currPtr += copyLen;
    _srcPtr += copyLen;

    PARROT_ASSERT(_payloadEncodedLen < _payloadLen);

    if (_currPtr == _sendVecEndPtr)
    {
        // Not enough space to encode a packet.
        if (_needMask)
        {
            maskPacket(_maskBeginPtr, _currPtr);
        }
        return eCodes::ST_BufferFull;
    }

    // Meta has been encoded.
    switch (_writeState)
    {
        case eWriteState::SysJsonMeta:
        {
            _writeState = eWriteState::SysJson;
            _srcPtr = reinterpret_cast<unsigned char*>(&(*_sysJsonStr.begin()));
            _srcEndPtr =
                reinterpret_cast<unsigned char*>(&(*_sysJsonStr.end()));
        }
        break;

        case eWriteState::JsonMeta:
        {
            _writeState = eWriteState::Json;
            _srcPtr    = reinterpret_cast<unsigned char*>(&(*_jsonStr.begin()));
            _srcEndPtr = reinterpret_cast<unsigned char*>(&(*_jsonStr.end()));
        }
        break;

        case eWriteState::BinaryMeta:
        {
            auto& bin   = _currPkt->getBinary();
            _writeState = eWriteState::Binary;
            _srcPtr = reinterpret_cast<const unsigned char*>(&(*bin.begin()));
            _srcEndPtr = reinterpret_cast<const unsigned char*>(&(*bin.end()));
        }
        break;

        default:
        {
            PARROT_ASSERT(false);
        }
    }
    return eCodes::ST_Ok;
}
示例#15
0
void RpcServerThread::run()
{
    uint32_t eventNum = 0;
    uint32_t idx      = 0;
    IoEvent* ev       = nullptr;
    eIoAction act     = eIoAction::None;

    try
    {
        while (!isStopping())
        {
            _now = std::time(nullptr);

            RSConnMgr::_timeoutMgr->checkTimeout(_now);
            RSConnMgr::addConnToNotifier();

            eventNum = _notifier->waitIoEvents(5000);

            // Here handle events.
            for (idx = 0; idx != eventNum; ++idx)
            {
                // We are sure that the IoEvnet is WsServerConn,
                // so we can use static_cast.
                ev  = _notifier->getIoEvent(idx);
                act = ev->handleIoEvent();
                ev->setNextAction(act);

                switch (act)
                {
                    case eIoAction::Read:
                    case eIoAction::ReadWrite:
                    {
                        if (ev->isConnection())
                        {
                            RSConnMgr::updateTimeout(
                                static_cast<RpcServerConn*>(
                                    ev->getDerivedPtr()),
                                _now);
                        }
                    }
                    // No break;
                    case eIoAction::Write:
                    {
                        _notifier->updateEventAction(ev);
                    }
                    break;

                    case eIoAction::Remove:
                    {
                        RSConnMgr::removeConn(
                            static_cast<RpcServerConn*>(ev->getDerivedPtr()));
                    }
                    break;

                    default:
                    {
                        PARROT_ASSERT(false);
                    }
                    break;
                } // switch
            }     // for

            // Append packet which needs to be sent to connections.
            handleJobs();
        } // while
    }
    catch (const std::system_error& e)
    {
        LOG_ERROR("RpcServerThread::run: Errno is "
                  << e.code().message() << ". Meaning " << e.what());
        // There's nothing we can do here ...
        PARROT_ASSERT(false);
    }
}
示例#16
0
eCodes WsEncoder::encodePlainPacket()
{
    eCodes code = eCodes::ST_Ok;

    switch (_writeState)
    {
        case eWriteState::None:
        {
            computeLength();
            _writeState  = eWriteState::Header;
            _firstPacket = true;
            _encodedLen  = 0;
        }
        // No break;

        case eWriteState::Header:
        {
            if ((_sendVecEndPtr - _currPtr) < _headerLen)
            {
                // Left space is not enough.
                return eCodes::ST_BufferFull;
            }

            bool fin = true;
            if (_fragmented)
            {
                if (_totalLen - _encodedLen <= _payloadLen)
                {
                    // The last packet. fin should be true.
                    _payloadLen = _totalLen - _encodedLen;
                }
                else
                {
                    fin = false;
                }
            }

            writeHeader(_firstPacket, fin);

            // Reset mask function related variables.
            _maskKeyIdx   = 0;
            _maskBeginPtr = _currPtr;

            if (_firstPacket)
            {
                _firstPacket = false;
                getMetaData(ePayloadItem::SysJson, _sysJsonStr.size());
                _writeState = eWriteState::SysJsonMeta;
                _srcPtr     = &(*_metaData.begin());
                _srcEndPtr  = &(*_metaData.end());
            }
            else
            {
                _writeState = _prevWriteState;
                return encodePlainPacket();
            }
        }
        // No break;

        case eWriteState::SysJsonMeta:
        {
            code = encodeMeta();
            if (code == eCodes::ST_BufferFull)
            {
                return code;
            }
        }
        // no break;

        case eWriteState::SysJson:
        {
            code = encodeData();
            if (code == eCodes::ST_BufferFull || code == eCodes::ST_Complete)
            {
                return code;
            }
        }
        // no break;

        case eWriteState::JsonMeta:
        {
            code = encodeMeta();
            if (code == eCodes::ST_BufferFull)
            {
                return code;
            }
        }
        // no break;

        case eWriteState::Json:
        {
            code = encodeData();
            if (code == eCodes::ST_BufferFull || code == eCodes::ST_Complete)
            {
                return code;
            }
        }
        // no break;

        case eWriteState::BinaryMeta:
        {
            code = encodeMeta();
            if (code == eCodes::ST_BufferFull)
            {
                return code;
            }
        }
        // no break;

        case eWriteState::Binary:
        {
            code = encodeData();
            if (code == eCodes::ST_BufferFull || code == eCodes::ST_Complete)
            {
                return code;
            }
        }
        break;

        default:
        {
            PARROT_ASSERT(false);
        }
    }

    return code;
}
示例#17
0
eCodes WsEncoder::encodeData()
{
    if (!_maskBeginPtr)
    {
        _maskBeginPtr = _currPtr;
    }

    uint64_t copyLen = static_cast<uint64_t>(_sendVecEndPtr - _currPtr) >
                               (_payloadLen - _payloadEncodedLen)
                           ? (_payloadLen - _payloadEncodedLen)
                           : (_sendVecEndPtr - _currPtr);

    copyLen = copyLen > static_cast<uint64_t>(_srcEndPtr - _srcPtr)
                  ? (_srcEndPtr - _srcPtr)
                  : copyLen;

    std::memcpy(_currPtr, _srcPtr, copyLen);

    _payloadEncodedLen += copyLen;
    _currPtr += copyLen;
    _srcPtr += copyLen;
    _encodedLen += copyLen;

    if (_encodedLen == _totalLen)
    {
        // Completed, we have encoded all data.
        if (_needMask)
        {
            maskPacket(_maskBeginPtr, _currPtr);
        }
        return eCodes::ST_Complete;
    }

    if (_currPtr == _sendVecEndPtr)
    {
        // Still has data to encode, but buffer is full.
        if (_needMask)
        {
            maskPacket(_maskBeginPtr, _currPtr);
        }
        return eCodes::ST_BufferFull;
    }
    else
    {
        if (_payloadEncodedLen == _payloadLen)
        {
            // Packet is fragmented.
            _prevWriteState = _writeState;
            _writeState     = eWriteState::Header;
            return encodePlainPacket();
        }
        else
        {
            switch (_writeState)
            {
                case eWriteState::SysJson:
                {
                    PARROT_ASSERT(_currPtr == _srcEndPtr);
                    // SysJson is encoded.
                    if (!_jsonStr.empty())
                    {
                        getMetaData(ePayloadItem::Json, _sysJsonStr.size());
                        _writeState = eWriteState::JsonMeta;
                    }
                    else if (!_currPkt->getBinary().empty())
                    {
                        getMetaData(ePayloadItem::Binary,
                                    _currPkt->getBinary().size());
                        _writeState = eWriteState::BinaryMeta;
                    }
                    else
                    {
                        PARROT_ASSERT(false);
                    }

                    _srcPtr    = &(*_metaData.begin());
                    _srcEndPtr = &(*_metaData.end());
                }
                break;

                case eWriteState::Json:
                {
                    PARROT_ASSERT(_currPtr == _srcEndPtr);
                    auto& bin = _currPkt->getBinary();
                    PARROT_ASSERT(!bin.empty());

                    getMetaData(ePayloadItem::Binary, bin.size());
                    _writeState = eWriteState::BinaryMeta;
                    _srcPtr     = &(*_metaData.begin());
                    _srcEndPtr  = &(*_metaData.end());
                }
                break;

                case eWriteState::Binary:
                {
                }
                break;

                default:
                {
                    PARROT_ASSERT(false);
                }
            }
        }
    }

    return eCodes::ST_Ok;
}
示例#18
0
PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
PMC *
Parrot_nci_parse_signature(PARROT_INTERP, ARGIN(STRING *sig_str))
{
    ASSERT_ARGS(Parrot_nci_parse_signature)

    const size_t  sig_length = Parrot_str_byte_length(interp, sig_str);
    PMC          *sig_pmc    = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray,
                                                               sig_length);
    size_t i;

    if (!sig_length) {
        sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, 1);
        VTABLE_set_integer_keyed_int(interp, sig_pmc, 0, enum_type_void);
        return sig_pmc;
    }

    for (i = 0; i < sig_length; ++i) {
        const INTVAL c = Parrot_str_indexed(interp, sig_str, i);
        PARROT_DATA_TYPE e;

        PARROT_ASSERT(c == (char)c);

        switch ((char)c) {
          case 'f':
            e = enum_type_float;
            break;
          case 'd':
            e = enum_type_double;
            break;
          case 'N':
            e = enum_type_FLOATVAL;
            break;

          case 'c':   /* char */
            e = enum_type_char;
            break;
          case 's':   /* short */
            e = enum_type_short;
            break;
          case 'i':   /* int */
            e = enum_type_int;
            break;
          case 'l':   /* long */
            e = enum_type_long;
            break;
          case 'I':   /* INTVAL */
            e = enum_type_INTVAL;
            break;
          case '2':   /* short PMC */
            e = enum_type_pshort;
            break;
          case '3':   /* int PMC */
            e = enum_type_pint;
            break;
          case '4':   /* long PMC */
            e = enum_type_plong;
            break;

          case 'S':
            e = enum_type_STRING;
            break;
          case 't':   /* string as cstring */
            e = enum_type_cstr;
            break;

          case 'p':   /* push pmc->data */
            e = enum_type_ptr;
            break;
          case 'O':   /* PMC invocant */
          case 'P':   /* push PMC * */
            e = enum_type_PMC;
            break;

          case 'v':
            e = enum_type_void;
            break;
          default:
            Parrot_ex_throw_from_c_args(interp, NULL,
                    EXCEPTION_JIT_ERROR,
                    "Unknown param Signature %c\n", (char)c);
            break;
        }

        VTABLE_set_integer_keyed_int(interp, sig_pmc, i, e);
    }

    return sig_pmc;
}
示例#19
0
eCodes WsEncoder::encodePingPong()
{
    // According to the RFC6455, the heartbeat may have 'application data'.
    // But pong must have the extact same data of ping. But the RFC doesn't
    // point out what the data will be. So we use binary if the payload exists.
    // And ping pong packets must not be fragmented.

    switch (_writeState)
    {
        case eWriteState::None:
        {
            auto payloadLen = _currPkt->getBinary().size();
            // No fragment. Up layer should check the length.
            PARROT_ASSERT(payloadLen <= WsConfig::_maxPayloadLen);

            // Compute _headerLen and _payloadLen.
            computeComponentLen(payloadLen);

            _writeState = eWriteState::Header;
            if ((_sendVecEndPtr - _currPtr) < _headerLen)
            {
                // Buffer is full. Return here and let translayer send
                // the data.

                return eCodes::ST_BufferFull;
            }

            // Fall through, next, encode header.
        }
        // No break;

        case eWriteState::Header:
        {
            writeHeader(true, true);

            _writeState = eWriteState::Binary;
            auto& bin   = _currPkt->getBinary();
            if (bin.empty())
            {
                return eCodes::ST_Complete;
            }

            _srcPtr     = &(*bin.begin());
            _srcEndPtr  = &(*bin.end());
            _maskKeyIdx = 0;
            // Fall through here.
        }
        // No break;

        case eWriteState::Binary:
        {
            // Encode
            _maskBeginPtr = _currPtr;
            for (; _srcPtr != _srcEndPtr && _currPtr != &(*_sendVec.end());
                 ++_srcPtr, ++_currPtr)
            {
                *_currPtr = *_srcPtr;
            }

            if (_needMask)
            {
                maskPacket(_maskBeginPtr, _currPtr);
            }

            if (_srcPtr != _srcEndPtr)
            {
                return eCodes::ST_BufferFull;
            }
        }
        break;

        default:
        {
            PARROT_ASSERT(false);
        }
        break;
    }

    return eCodes::ST_Complete;
}
示例#20
0
文件: api.c 项目: dafrito/parrot
PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
PMC *
Parrot_io_open_handle(PARROT_INTERP, ARGIN(PMC *pmc), ARGIN(STRING *path), ARGIN(STRING *mode))
{
    ASSERT_ARGS(Parrot_io_open_handle)
    PMC *filehandle;
    const INTVAL typenum = Parrot_hll_get_ctx_HLL_type(interp,
                                                   Parrot_PMC_typenum(interp, "FileHandle"));
    if (PMC_IS_NULL(pmc)) {
        filehandle = Parrot_pmc_new(interp, typenum);
    }
    else
        filehandle = pmc;

    if (STRING_IS_NULL(path))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                        "Cannot open filehandle, no path");

    if (filehandle->vtable->base_type == typenum) {
        INTVAL    flags     = Parrot_io_parse_open_flags(interp, mode);
        PIOHANDLE os_handle;

        /* TODO: a filehandle shouldn't allow a NULL path. */

        PARROT_ASSERT(filehandle->vtable->base_type == typenum);

        if (flags & PIO_F_PIPE) {
            const int f_read  = (flags & PIO_F_READ) != 0;
            const int f_write = (flags & PIO_F_WRITE) != 0;
            INTVAL    pid;

            if (f_read == f_write)
                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                    "Invalid pipe mode: %X", flags);

            os_handle = PIO_OPEN_PIPE(interp, path, flags, &pid);

            /* Save the pid of the child, we'll wait for it when closing */
            VTABLE_set_integer_keyed_int(interp, filehandle, 0, pid);
        }
        else {
            if ((flags & (PIO_F_WRITE | PIO_F_READ)) == 0)
                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                    "Invalid mode for file open");

            os_handle = PIO_OPEN(interp, path, flags);

            if (os_handle == PIO_INVALID_HANDLE)
                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                    "Unable to open filehandle from path '%Ss'", path);

            flags |= PIO_F_FILE;

            /* Set generic flag here if is a terminal then
             * FileHandle can know how to setup buffering.
             * STDIN, STDOUT, STDERR would be in this case
             * so we would setup linebuffering.
             */
            if (PIO_IS_TTY(interp, os_handle))
                flags |= PIO_F_CONSOLE;
        }

        if (STRING_IS_NULL(mode))
            mode = CONST_STRING(interp, "r");
        else if (STRING_index(interp, mode, CONST_STRING(interp, "b"), 0) >= 0)
            SETATTR_FileHandle_encoding(interp, filehandle, CONST_STRING(interp, "binary"));

        SETATTR_FileHandle_os_handle(interp, filehandle, os_handle);
        SETATTR_FileHandle_flags(interp, filehandle, flags);
        SETATTR_FileHandle_filename(interp, filehandle, path);
        SETATTR_FileHandle_mode(interp, filehandle, mode);

        Parrot_io_setbuf(interp, filehandle, PIO_UNBOUND);
    }
    else
        Parrot_pcc_invoke_method_from_c_args(interp, filehandle, CONST_STRING(interp, "open"), "SS->P", path, mode, &filehandle);
    return filehandle;
}
示例#21
0
SSL_CTX* SslHelper::genSslCtx(const std::string& keyPath,
                              const std::string& certPath,
                              const std::string& caPath,
                              const std::string& caFile,
                              bool               verifyPeer,
                              int                depth)
{
    /* This method supprots from SSLv3 to newest TLS. SSLv3 will be disabled
     * below. */
    const SSL_METHOD* m      = TLS_method();
    SSL_CTX*          sslCtx = SSL_CTX_new(m);

    if (!sslCtx)
    {
        /* If here, did you forget to call SslHelper::init()? */
        PARROT_ASSERT(0);
    }

    const char* caFilePtr = nullptr;
    const char* caPathPtr = nullptr;

    if (caFile.length() > 0)
    {
        caFilePtr = caFile.c_str();
    }

    if (caPath.length() > 0)
    {
        caPathPtr = caPath.c_str();
    }

    /* Add ca-cert to SSL_CTX. */
    if (caFilePtr || caPathPtr)
    {
        /* Add ca-cert file. */
        if (SSL_CTX_load_verify_locations(sslCtx, caFilePtr, caPathPtr) != 1)
        {
            PARROT_ASSERT(0);
        }
    }

    /* Add cert to SSL_CTX. */
    if (caPath.length() > 0 &&
        SSL_CTX_use_certificate_file(sslCtx, certPath.c_str(),
                                     SSL_FILETYPE_PEM) <= 0)
    {
        PARROT_ASSERT(0);
    }

    // Add private key to SSL_CTX.
    if (keyPath.length() > 0 &&
        SSL_CTX_use_PrivateKey_file(sslCtx, keyPath.c_str(),
                                    SSL_FILETYPE_PEM) != 1)
    {
        PARROT_ASSERT(0);
    }

    // Enable nonblock.
    SSL_CTX_set_mode(sslCtx, SSL_MODE_ENABLE_PARTIAL_WRITE |
                                 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

    if (verifyPeer)
    {
        /* We need to verify peer, but the client doesn't tell us where
         * to find the ca-certs, we use default. */
        if (caPath.empty())
        {
            if (SSL_CTX_set_default_verify_paths(sslCtx) != 1)
            {
                PARROT_ASSERT(0);
            }
        }

        SSL_CTX_set_verify(
            sslCtx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
        SSL_CTX_set_verify_depth(sslCtx, depth);
    }
    else
    {
        SSL_CTX_set_verify(sslCtx, SSL_VERIFY_NONE, nullptr);
    }

    /* TLSv1.0 is the minimal requirement. SSLv3.0 will not be supported. */
    PARROT_ASSERT(SSL_CTX_set_min_proto_version(sslCtx, TLS1_VERSION) == 1);

    return sslCtx;
}
示例#22
0
文件: oo.c 项目: ashgti/parrot
PARROT_CANNOT_RETURN_NULL
PMC *
Parrot_oo_clone_object(PARROT_INTERP, ARGIN(PMC *pmc), ARGMOD_NULLOK(PMC *dest))
{
    ASSERT_ARGS(Parrot_oo_clone_object)
    Parrot_Object_attributes *obj = PARROT_OBJECT(pmc);
    Parrot_Object_attributes *cloned_guts;
    Parrot_Class_attributes  *_class;
    PMC                      *cloned;
    INTVAL                    num_classes;
    INTVAL                    i, num_attrs;

    if (!PMC_IS_NULL(dest)) {
        cloned = dest;
    }
    else {
        cloned = Parrot_pmc_new_noinit(interp, enum_class_Object);
    }

    _class = PARROT_CLASS(obj->_class);
    PARROT_ASSERT(_class);
    num_classes = VTABLE_elements(interp, _class->all_parents);

    /* Set custom GC mark and destroy on the object. */
    PObj_custom_mark_SET(cloned);
    PObj_custom_destroy_SET(cloned);

    /* Flag that it is an object */
    PObj_is_object_SET(cloned);

    /* Now clone attributes list.class. */
    cloned_guts               = (Parrot_Object_attributes *) PMC_data(cloned);
    cloned_guts->_class       = obj->_class;
    cloned_guts->attrib_store = VTABLE_clone(interp, obj->attrib_store);
    num_attrs                 = VTABLE_elements(interp, cloned_guts->attrib_store);
    for (i = 0; i < num_attrs; ++i) {
        PMC * const to_clone = VTABLE_get_pmc_keyed_int(interp, cloned_guts->attrib_store, i);
        if (!PMC_IS_NULL(to_clone)) {
            VTABLE_set_pmc_keyed_int(interp, cloned_guts->attrib_store, i,
                    VTABLE_clone(interp, to_clone));
        }
    }

    /* Some of the attributes may have been the PMCs providing storage for any
     * PMCs we inherited from; also need to clone those. */
    if (CLASS_has_alien_parents_TEST(obj->_class)) {
        int j;
        /* Locate any PMC parents. */
        for (j = 0; j < num_classes; ++j) {
            PMC * const cur_class = VTABLE_get_pmc_keyed_int(interp, _class->all_parents, j);
            if (cur_class->vtable->base_type == enum_class_PMCProxy) {
                /* Clone this PMC too. */
                STRING * const proxy = CONST_STRING(interp, "proxy");
                VTABLE_set_attr_keyed(interp, cloned, cur_class, proxy,
                    VTABLE_clone(interp,
                        VTABLE_get_attr_keyed(interp, cloned, cur_class, proxy)));
            }
        }
    }

    /* And we have ourselves a clone. */
    return cloned;
}
示例#23
0
 void
Parrot_nci_load_core_thunks(PARROT_INTERP) {
    PMC * const iglobals = interp->iglobals;
    PMC *nci_funcs;
    PMC *temp_pmc;

    PARROT_ASSERT(!(PMC_IS_NULL(iglobals)));

    nci_funcs = VTABLE_get_pmc_keyed_int(interp, iglobals, IGLOBALS_NCI_FUNCS);
    PARROT_ASSERT(!(PMC_IS_NULL(nci_funcs)));

    {
        const int n = 1;
        static const int sig[] = { 5, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_char);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 5, 6, 5, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_char_short_char);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 16, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_double);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 16, 16, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_double_double);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 15, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_float);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 15, 15, 15, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_float_float_float);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 7, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 4;
        static const int sig[] = { 7, 7, 7, 7, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_int_int_int);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 7, 30, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_ptr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 7, 30, 30, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_ptr_ptr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 7, 6, 5, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_short_char);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 7, 31, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_cstr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 8, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_long);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 30, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 30, 7, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 30, 7, 7, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int_int);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 5;
        static const int sig[] = { 30, 7, 7, 7, 7, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int_int_int_int);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 30, 7, 30, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int_ptr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 30, 30, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_ptr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 30, 30, 3, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_ptr_STRING);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 6, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_short);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 6, 6, 5, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_short_short_char);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 31, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_cstr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 31, 31, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_cstr_cstr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 31, 31, 31, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_cstr_cstr_cstr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 1;
        static const int sig[] = { 29, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 4;
        static const int sig[] = { 29, 15, 15, 15, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_float_float_float);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 29, 30, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_ptr);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 2;
        static const int sig[] = { 29, 4, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_PMC);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 4;
        static const int sig[] = { 29, 30, 7, 7, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_ptr_int_int);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }

    {
        const int n = 3;
        static const int sig[] = { 29, 30, 4, };
        PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n);
        int i;
        for (i = 0; i < n; i++)
            VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]);
        temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
        VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_ptr_PMC);
        VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc);
    }


}
示例#24
0
文件: ops.c 项目: mpeters/parrot
void
runops(PARROT_INTERP, size_t offs)
{
    ASSERT_ARGS(runops)
    volatile size_t offset            = offs;
    const    int    old_runloop_id    = interp->current_runloop_id;
    int             our_runloop_level = interp->current_runloop_level;
    int             our_runloop_id    = old_runloop_id;

    /* It is OK if the runloop ID overflows; we only ever test it for equality,
       so the chance of collision is slight. */
    interp->current_runloop_id = our_runloop_id;

#if RUNLOOP_TRACE
    fprintf(stderr, "[entering loop %d, level %d]\n",
            interp->current_runloop_id, our_runloop_level);
#endif

    /*
     * STACKED_EXCEPTIONS are necessary to catch exceptions in reentered
     * run loops, e.g. if a delegate method throws an exception
     */
#if ! STACKED_EXCEPTIONS
    if (!interp->current_runloop)
#endif
    {
        new_runloop_jump_point(interp);
        our_runloop_id = interp->current_runloop_id;
        our_runloop_level = interp->current_runloop_level;
  reenter:
        interp->current_runloop->handler_start = NULL;
        switch (setjmp(interp->current_runloop->resume)) {
          case 1:
            /* an exception was handled */
            if (STACKED_EXCEPTIONS)
                free_runloop_jump_point(interp);

            interp->current_runloop_level = our_runloop_level - 1;
            interp->current_runloop_id    = old_runloop_id;

#if RUNLOOP_TRACE
            fprintf(stderr, "[handled exception; back to loop %d, level %d]\n",
                        interp->current_runloop_id, interp->current_runloop_level);
#endif
            return;
          case 2:
            /* Reenter the runloop from a exception thrown from C
             * with a pir handler */
            free_runloops_until(interp, our_runloop_id);
            PARROT_ASSERT(interp->current_runloop->handler_start);
            offset = interp->current_runloop->handler_start - interp->code->base.data;
            /* Prevent incorrect reuse */
            goto reenter;
          case 3:
            /* Reenter the runloop when finished the handling of a
             * exception */
            free_runloops_until(interp, our_runloop_id);
            offset = interp->current_runloop->handler_start - interp->code->base.data;
            goto reenter;
          default:
            break;
        }
    }

    runops_int(interp, offset);

    interp->current_runloop->handler_start = NULL;
    /* Remove the current runloop marker (put it on the free list). */
    if (STACKED_EXCEPTIONS || interp->current_runloop)
        free_runloop_jump_point(interp);

#if RUNLOOP_TRACE
    fprintf(stderr, "[exiting loop %d, level %d]\n",
            our_runloop_id, our_runloop_level);
#endif
}