예제 #1
0
파일: string_type.cpp 프로젝트: arn-e/circa
void string_resize(StringData** data, int newLength)
{
    if (*data == NULL) {
        *data = string_create(newLength);
        return;
    }

    // Perform the same check as touch()
    if ((*data)->refCount == 1) {
        INCREMENT_STAT(StringResizeInPlace);

        // Modify in-place
        *data = (StringData*) realloc(*data, sizeof(StringData) + newLength + 1);
        (*data)->length = newLength;
        return;
    }

    INCREMENT_STAT(StringResizeCreate);

    StringData* oldData = *data;
    StringData* newData = string_create(newLength);
    memcpy(newData->str, oldData->str, oldData->length + 1);
    decref(oldData);
    *data = newData;
}
예제 #2
0
파일: kernel.cpp 프로젝트: whunmr/circa
void dynamic_method_call(caStack* stack)
{
    INCREMENT_STAT(DynamicMethodCall);

    caValue* args = circa_input(stack, 0);
    caValue* object = circa_index(args, 0);

    // Lookup method
    Term* term = (Term*) circa_caller_term(stack);
    std::string functionName = term->stringProp("syntax:functionName", "");

    // Find and dispatch method
    Term* method = find_method((Block*) circa_caller_block(stack),
        (Type*) circa_type_of(object), functionName.c_str());

    // copy(object, circa_output(stack, 1));

    if (method != NULL) {
        // Grab inputs before pop
        Value inputs;
        swap(args, &inputs);

        pop_frame(stack);
        push_frame_with_inputs(stack, function_contents(method), &inputs);
        return;
    }

    // Method not found. Raise error.
    std::string msg;
    msg += "Method ";
    msg += functionName;
    msg += " not found on type ";
    msg += as_cstring(&circa_type_of(object)->name);
    circa_output_error(stack, msg.c_str());
}
예제 #3
0
http_connection* create_http_connection()
{
    http_connection* connection = malloc(sizeof(http_connection));
    connection->request = NULL;
    INCREMENT_STAT(stat_connections_created_total);
    return connection;
}
예제 #4
0
http_connection* create_http_connection()
{
    http_connection* connection = calloc(1, sizeof(http_connection));
    connection->buffer = http_request_buffer_init(config->max_request_size);
    INCREMENT_STAT(stat_connections_created_total);
    return connection;
}
예제 #5
0
http_request_context* create_http_context()
{
    http_request_context* context = (http_request_context *)malloc(sizeof(http_request_context));
    context->request = NULL;
    INCREMENT_STAT(stat_connections_created_total);
    return context;
}
예제 #6
0
파일: string_type.cpp 프로젝트: arn-e/circa
// Creates a hard duplicate of a string. Starts off with 1 ref.
StringData* string_duplicate(StringData* original)
{
    INCREMENT_STAT(StringDuplicate);

    StringData* dup = string_create(original->length);
    memcpy(dup->str, original->str, original->length + 1);
    return dup;
}
예제 #7
0
void free_http_connection(http_connection* connection)
{
    if (connection->request != NULL)
    {
        free_http_request(connection->request);
    }
    free(connection);
    INCREMENT_STAT(stat_connections_destroyed_total);
}
예제 #8
0
파일: string_type.cpp 프로젝트: arn-e/circa
// Create a new blank string with the given length. Starts off with 1 ref.
StringData* string_create(int length)
{
    INCREMENT_STAT(StringCreate);

    StringData* result = (StringData*) malloc(sizeof(StringData) + length + 1);
    result->refCount = 1;
    result->length = length;
    result->str[0] = 0;
    return result;
}
예제 #9
0
http_connection* create_http_connection()
{
    http_connection* connection = malloc(sizeof(http_connection));
    connection->request = NULL;
    connection->current_header_key.length = 0;
    connection->current_header_value.length = 0;
    connection->last_was_value = 0;
    INCREMENT_STAT(stat_connections_created_total);
    return connection;
}
예제 #10
0
void touch(caValue* value)
{
    INCREMENT_STAT(ValueTouch);

    Type::Touch touch = value->value_type->touch;
    if (touch != NULL)
        touch(value);

    // Default behavior: no-op.
}
예제 #11
0
void free_http_connection(http_connection* connection)
{
    if (connection->request)
    {
        free_http_request(connection->request);
    }
    http_request_buffer_destroy(connection->buffer);
    free(connection);
    INCREMENT_STAT(stat_connections_destroyed_total);
}
예제 #12
0
파일: list.cpp 프로젝트: RickMoynihan/circa
    void tv_cast(CastResult* result, caValue* value, Type* type, bool checkOnly)
    {
        if (!is_list(value)) {
            result->success = false;
            return;
        }

        int sourceLength = list_length(value);

        // If the requested type doesn't have a specific size restriction, then
        // the input data is fine as-is.
        if (!list_type_has_specific_size(&type->parameter)) {
            if (!checkOnly)
                value->value_type = type;
            return;
        }

        List& destTypes = *List::checkCast(list_get_type_list_from_type(type));

        // Check for correct number of elements.
        if (sourceLength != destTypes.length()) {
            result->success = false;
            return;
        }

        if (!checkOnly) {
            INCREMENT_STAT(Touch_ListCast);
            list_touch(value);
            value->value_type = type;
        }

        for (int i=0; i < sourceLength; i++) {
            caValue* sourceElement = list_get(value, i);
            Type* expectedType = as_type(destTypes[i]);

            INCREMENT_STAT(Cast_ListCastElement);
            cast(result, sourceElement, expectedType, checkOnly);

            if (!result->success)
                return;
        }
    }
예제 #13
0
파일: string_type.cpp 프로젝트: arn-e/circa
void string_copy(Type* type, caValue* source, caValue* dest)
{
    set_null(dest);
    StringData* data = (StringData*) source->value_data.ptr;
    if (data != NULL)
        incref(data);
    dest->value_type = source->value_type;
    dest->value_data.ptr = data;

    INCREMENT_STAT(StringSoftCopy);
}
예제 #14
0
파일: list.cpp 프로젝트: RickMoynihan/circa
ListData* list_duplicate(ListData* source)
{
    if (source == NULL)
        return NULL;

    INCREMENT_STAT(ListHardCopy);

    assert_valid_list(source);

    ListData* result = allocate_empty_list(source->capacity);

    result->count = source->count;

    for (int i=0; i < source->count; i++) {
        INCREMENT_STAT(Copy_ListDuplicate);
        copy(&source->items[i], &result->items[i]);
    }

    return result;
}
예제 #15
0
void make(Type* type, caValue* value)
{
    INCREMENT_STAT(ValueCreates);

    set_null(value);

    value->value_type = type;

    if (type->initialize != NULL)
        type->initialize(type, value);

    type->inUse = true;
}
예제 #16
0
void cast(CastResult* result, caValue* value, Type* type, bool checkOnly)
{
    INCREMENT_STAT(ValueCast);

    result->success = true;

    // Finish early if value already has this exact type.
    if (value->value_type == type) {
        result->success = true;
        return;
    }

    if (type->cast != NULL) {
        INCREMENT_STAT(ValueCastDispatched);

        type->cast(result, value, type, checkOnly);
        return;
    }

    // Type has no 'cast' handler, and the type is not exactly the same, so fail.
    result->success = false;
}
예제 #17
0
파일: list.cpp 프로젝트: RickMoynihan/circa
void list_copy(caValue* source, caValue* dest)
{
    INCREMENT_STAT(ListSoftCopy);

    ca_assert(source->value_type->storageType == name_StorageTypeList);

    // prepare 'dest'
    change_type(dest, source->value_type);

    ListData* sourceData = (ListData*) source->value_data.ptr;

    if (sourceData == NULL)
        return;

    list_make_immutable(sourceData);
    list_incref(sourceData);

    dest->value_data.ptr = sourceData;
}
예제 #18
0
void copy(caValue* source, caValue* dest)
{
    INCREMENT_STAT(ValueCopies);

    ca_assert(source);
    ca_assert(dest);

    if (source == dest)
        return;

    Type::Copy copyFunc = source->value_type->copy;

    if (copyFunc != NULL) {
        copyFunc(source->value_type, source, dest);
        ca_assert(dest->value_type == source->value_type);
        return;
    }

    // Default behavior, shallow assign.
    set_null(dest);
    dest->value_type = source->value_type;
    dest->value_data = source->value_data;
}
예제 #19
0
파일: loops.cpp 프로젝트: mokerjoke/circa
void for_loop_finish_iteration(Stack* stack, bool enableLoopOutput)
{
    INCREMENT_STAT(LoopFinishIteration);

    Frame* frame = top_frame(stack);
    Branch* contents = frame->branch;

    // Find list length
    caValue* listInput = get_frame_register(frame, 0);

    // Increment the loop index
    caValue* index = get_top_register(stack, for_loop_find_index(contents));
    set_int(index, as_int(index) + 1);

    // Preserve list output
    if (enableLoopOutput && frame->exitType != name_Discard) {
        caValue* outputIndex = get_frame_register(frame, for_loop_find_output_index(contents));

        Term* outputPlaceholder = get_output_placeholder(contents, 0);
        caValue* outputList = get_frame_register(frame, outputPlaceholder);
        caValue* outputValue = find_stack_value_for_term(stack, outputPlaceholder->input(0), 0);

        if (!is_list(outputList))
            set_list(outputList);
        list_touch(outputList);
        copy(outputValue, list_get(outputList, as_int(outputIndex)));

        INCREMENT_STAT(LoopWriteOutput);

        // Advance output index
        set_int(outputIndex, as_int(outputIndex) + 1);
    }

    // Check if we are finished
    if (as_int(index) >= list_length(listInput)
            || frame->exitType == name_Break
            || frame->exitType == name_Return) {

        // Possibly truncate output list, in case any elements were discarded.
        if (enableLoopOutput) {
            caValue* outputIndex = get_frame_register(frame, for_loop_find_output_index(contents));
            Term* outputPlaceholder = get_output_placeholder(contents, 0);
            caValue* outputList = get_frame_register(frame, outputPlaceholder);
            list_resize(outputList, as_int(outputIndex));
        } else {
            Term* outputPlaceholder = get_output_placeholder(contents, 0);
            caValue* outputList = get_frame_register(frame, outputPlaceholder);
            set_list(outputList, 0);
        }
        
        finish_frame(stack);
        return;
    }

    // If we're not finished yet, copy rebound outputs back to inputs.
    for (int i=1;; i++) {
        Term* input = get_input_placeholder(contents, i);
        if (input == NULL)
            break;
        Term* output = get_output_placeholder(contents, i);
        copy(get_frame_register(frame, output),
            get_frame_register(frame, input));

        INCREMENT_STAT(Copy_LoopCopyRebound);
    }

    // Return to start of loop body
    frame->pc = 0;
    frame->nextPc = 0;
    frame->exitType = name_None;
}
예제 #20
0
파일: string_type.cpp 프로젝트: arn-e/circa
std::string as_string(caValue* value)
{
    INCREMENT_STAT(StringToStd);
    return std::string(as_cstring(value));
}