[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/harold-b/daScript/master/src/simulate/runtime_array.cpp [Back]  [Original]

#include "daScript/misc/platform.h"

#include "daScript/simulate/runtime_array.h"

namespace das
{
    void array_clear ( Context & context, Array & arr ) {
        if ( arr.isLocked() ) context.throw_error("can't clear locked array");
        arr.size = 0;
    }

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

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

    void array_reserve(Context & context, Array & arr, uint32_t newCapacity, uint32_t stride) {
        if ( arr.isLocked() ) context.throw_error("can't change capacity of a locked array");
        if ( arr.capacity >= newCapacity ) return;
        auto newData = (char *)context.heap->reallocate(arr.data, arr.capacity*stride, newCapacity*stride);
        if ( !newData ) context.throw_error("out of linear allocator memory");
        context.heap->mark_comment(newData, "array");
        if ( newData != arr.data ) {
            // memcpy(newData, arr.data, arr.capacity);
            arr.data = newData;
        }
        arr.capacity = newCapacity;
    }

    void array_resize ( Context & context, Array & arr, uint32_t newSize, uint32_t stride, bool zero ) {
        if ( arr.isLocked() ) context.throw_error("can't resize locked array");
        if ( newSize > arr.capacity ) {
            uint32_t newCapacity = 1 arr.size ) {
            memset ( arr.data + arr.size*stride, 0, (newSize-arr.size)*stride );
        }
        arr.size = newSize;
    }

    // GoodArrayIterator

    bool GoodArrayIterator::first ( Context & context, char * _value )  {
        char ** value = (char **) _value;
        array_lock(context, *array);
        data = array->data;
        *value = data;
        array_end  = data + array->size * stride;
        return (bool) array->size;
    }

    bool GoodArrayIterator::next  ( Context &, char * _value )  {
        char ** value = (char **) _value;
        data += stride;
        *value = data;
        return data != array_end;
    }

    void GoodArrayIterator::close ( Context & context, char * _value )  {
        if ( _value ) {
            char ** value = (char **) _value;
            *value = nullptr;
        }
        array_unlock(context, *array);
        context.heap->free((char *)this, sizeof(GoodArrayIterator));
    }

    vec4f SimNode_GoodArrayIterator::eval ( Context & context ) {
        DAS_PROFILE_NODE
        vec4f ll = source->eval(context);
        Array * arr = cast::to(ll);
        char * iter = context.heap->allocate(sizeof(GoodArrayIterator));
        context.heap->mark_comment(iter,"array iterator");
        context.heap->mark_location(iter,&debugInfo);
        new (iter) GoodArrayIterator(arr, stride);
        return cast::from(iter);
    }

    // FixedArrayIterator

    bool FixedArrayIterator::first ( Context &, char * _value )  {
        char ** value = (char **) _value;
        *value = data;
        fixed_array_end = data + size*stride;
        return (bool) size;
    }

    bool FixedArrayIterator::next  ( Context & , char * _value )  {
        char ** value = (char **) _value;
        data += stride;
        *value = data;
        return data != fixed_array_end;
    }

    void FixedArrayIterator::close ( Context & context, char * _value )  {
        if ( _value ) {
            char ** value = (char **) _value;
            *value = nullptr;
        }
        context.heap->free((char *)this, sizeof(FixedArrayIterator));
    }

    vec4f SimNode_FixedArrayIterator::eval ( Context & context ) {
        DAS_PROFILE_NODE
        vec4f ll = source->eval(context);
        char * data = cast::to(ll);
        char * iter = context.heap->allocate(sizeof(FixedArrayIterator));
        context.heap->mark_comment(iter,"fixed array iterator");
        context.heap->mark_location(iter,&debugInfo);
        new (iter) FixedArrayIterator(data, size, stride);
        return cast::from(iter);
    }

    // delete

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

Web Proxy Viewer  |  New URL  |  Original Page