[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Xsankor/daScript/master/src/simulate/runtime_table.cpp [Back]  [Original]

#include "daScript/misc/platform.h"

#include "daScript/simulate/runtime_table_nodes.h"

namespace das
{
    void table_clear ( Context & context, Table & arr ) {
        if ( arr.isLocked() ) context.throw_error("can't clear locked table");
        if ( arr.data ) {
            memset(arr.hashes, 0, arr.capacity*sizeof(uint64_t));
            memset(arr.data, 0, arr.keys - arr.data);
        }
        arr.size = 0;
    }

    void table_lock ( Context & context, Table & arr ) {
        if ( arr.shared || arr.hopeless ) return;
        arr.lock ++;
        if ( arr.lock==0 ) context.throw_error("table lock overflow");
    }

    void table_unlock ( Context & context, Table & arr ) {
        if ( arr.shared || arr.hopeless ) return;
        if ( arr.lock==0 ) context.throw_error("table lock underflow");
        arr.lock --;
    }

    // TableIterator

    size_t TableIterator::nextValid ( size_t index ) const {
        for (; index < table->capacity; index++) {
            if (table->hashes[index] > HASH_KILLED64) {
                break;
            }
        }
        return index;
    }

    bool TableIterator::first ( Context & context, char * _value ) {
        char ** value = (char **)_value;
        table_lock(context, *(Table *)table);
        data  = getData();
        table_end = data + table->capacity*stride;
        size_t index = nextValid(0);
        data += index * stride;
        *value = data;
        return (bool) table->size;
    }

    bool TableIterator::next  ( Context &, char * _value ) {
        char ** value = (char **) _value;
        char * tableData = getData();
        size_t index = (data-tableData)/stride;
        index = nextValid(index + 1);
        data = tableData + index * stride;
        *value = data;
        return data != table_end;
    }

    void TableIterator::close ( Context & context, char * _value ) {
        if ( _value ) {
            char ** value = (char **) _value;
            *value = nullptr;
        }
        table_unlock(context, *(Table *)table);
    }

    // keys and values

    char * TableKeysIterator::getData ( ) const {
        return table->keys;
    }

    void TableKeysIterator::close ( Context & context, char * value ) {
        TableIterator::close(context,value);
        context.heap->free((char *)this, sizeof(TableKeysIterator));
    }

    char * TableValuesIterator::getData ( ) const {
        return table->data;
    }

    void TableValuesIterator::close ( Context & context, char * value ) {
        TableIterator::close(context,value);
        context.heap->free((char *)this, sizeof(TableValuesIterator));
    }

    void builtin_table_keys ( Sequence & result, const Table & tab, int32_t stride, Context * __context__ ) {
        char * iter = __context__->heap->allocate(sizeof(TableKeysIterator));
        __context__->heap->mark_comment(iter,"table keys iterator");
        new (iter) TableKeysIterator(&tab, stride);
        result = { (Iterator *) iter };
    }

    void builtin_table_values ( Sequence & result, const Table & tab, int32_t stride, Context * __context__ ) {
        char * iter = __context__->heap->allocate(sizeof(TableKeysIterator));
        __context__->heap->mark_comment(iter,"table values iterator");
        new (iter) TableValuesIterator(&tab, stride);
        result = { (Iterator *) iter };
    }

    // delete

    vec4f SimNode_DeleteTable::eval ( Context & context ) {
        DAS_PROFILE_NODE
        auto pTable = (Table *) subexpr->evalPtr(context);
        pTable = pTable + total - 1;
        for ( uint32_t i=0; i!=total; ++i, pTable-- ) {
            if ( pTable->data ) {
                if ( !pTable->isLocked() ) {
                    uint32_t oldSize = pTable->capacity*(vts_add_kts + sizeof(uint64_t));
                    context.heap->free(pTable->data, oldSize);
                } else {
                    context.throw_error("deleting locked table");
                    return v_zero();
                }
            }
            memset ( pTable, 0, sizeof(Table) );
        }
        return v_zero();
    }
}


Web Proxy Viewer  |  New URL  |  Original Page