Beispiel #1
0
bool _corto_delegate_compatible(
    corto_delegate _this,
    corto_type type)

{
    static corto_uint32 _methodId;
    corto_method _method;
    bool _result;
    corto_interface _abstract;

    _abstract = corto_interface(corto_typeof(_this));

    /* Determine methodId once, then cache it for subsequent calls. */
    if (!_methodId) {
        _methodId = corto_interface_resolveMethodId(_abstract, "compatible(type type)");
    }
    corto_assert(_methodId, "virtual 'compatible(type type)' not found in '%s'%s%s", corto_fullpath(NULL, _abstract), corto_lasterr() ? ": " : "", corto_lasterr() ? corto_lasterr() : "");

    /* Lookup method-object. */
    _method = corto_interface_resolveMethodById(_abstract, _methodId);
    corto_assert(_method != NULL, "unresolved method '%s::compatible(type type)@%d'", corto_idof(_this), _methodId);

    if (corto_function(_method)->kind == CORTO_PROCEDURE_CDECL) {
        _result = ((bool ___ (*)(corto_object, corto_type))((corto_function)_method)->fptr)(_this, type);
    } else {
        corto_call(corto_function(_method), &_result, _this, type);
    }
    
    return _result;
}
Beispiel #2
0
corto_int16 cpp_fluentTemplDecl(corto_type type, char *base, cpp_classWalk_t *data) {
    corto_id id;
    g_oid(data->g, type, id);

    g_fileWrite(data->header, "// Helper class that sets members and enables inheritance for factories\n");
    g_fileWrite(data->header, "template <class T>\n");
    g_fileWrite(data->header, "class %s_v : public %s_v<T>\n", id, base);
    g_fileWrite(data->header, "{\n");
    g_fileWrite(data->header, "public:\n");
    g_fileIndent(data->header);
    g_fileWrite(data->header, "%s_v(T& _this, void *ptr) : %s_v<T>(_this, ptr) { }\n", id, base);

    if (corto_instanceof(corto_interface_o, type) && corto_interface(type)->base) {
        g_fileWrite(data->header, "%s_v<T> super() ", base);
        g_fileWrite(data->header, "{ return %s_v<T>(this->m_this, this->ptr); }\n", base);
    }

    if (cpp_fluent_walkMembers(type, data)) {
        goto error;
    }

    g_fileDedent(data->header);
    g_fileWrite(data->header, "};\n");
    g_fileWrite(data->header, "\n");

    return 0;
error:
    return -1;
}
Beispiel #3
0
/* Create a class that mounts fibonacci numbers in corto */
corto_class createFiboClass(void) {
    corto_class FiboClass = corto_declareChild(root_o, "FiboConnector", corto_class_o);
    if (!FiboClass) {
        goto error;
    }

    /* Inherit from the corto mount class */
    corto_setref(&corto_interface(FiboClass)->base, corto_mount_o);

    /* Create onNotify method (called when the mount receives an update) */
    corto_method onRequestMethod = corto_declareChild(
        FiboClass,
        "onRequest(core/request request)",
        corto_method_o);
    if (!onRequestMethod) {
        goto error;
    }

    corto_function(onRequestMethod)->kind = CORTO_PROCEDURE_CDECL;
    corto_function(onRequestMethod)->fptr = (corto_word)onRequest;

    if (corto_define(onRequestMethod)) {
        goto error;
    }

    /* Finalize class */
    if (corto_define(FiboClass)) {
        goto error;
    }

    return FiboClass;
error:
    return NULL;
}
Beispiel #4
0
corto_int16 corto_value_memberExpr(corto_value *val, corto_string member, corto_value *out) {
    corto_type t = corto_value_typeof(val);
    corto_object o = corto_value_objectof(val);
    void *ptr = corto_value_ptrof(val);

    corto_id tokens;
    strncpy(tokens, member, sizeof(corto_id));

    char *cur = tokens, *prev = tokens;
    do {
        if (cur && (cur = strchr(cur + 1, '.'))) *cur = '\0';

        if (!corto_instanceof(corto_interface_o, t)) {
            corto_seterr(
                "cannot get member from a non-composite value (type is '%s')",
                corto_fullpath(NULL, t));
            goto error;
        }

        if (!strcmp(prev, "super")) {
            if (!(t = (corto_type)corto_interface(t)->base)) {
                corto_seterr("super unpexpected: interface '%s' does not have a base",
                    corto_fullpath(NULL, t));
                goto error;
            } else {
                *out = corto_value_base(ptr, t);
            }
        } else {
            corto_member m = corto_interface_resolveMember(t, prev);
            if (!m) {
                corto_seterr(
                    "unresolved member '%s' in type '%s'",
                    prev,
                    corto_fullpath(NULL, t));
                goto error;
            }

            ptr = CORTO_OFFSET(ptr, m->offset);
            t = m->type;

            *out = corto_value_member(o, m, ptr);
        }

        prev = cur + 1;
    } while (cur);

    return 0;
error:
    return -1;
}
Beispiel #5
0
corto_int16 _corto_delegate_bind(corto_function object) {
/* $begin(::corto::lang::delegate::bind) */
    corto_object parent = corto_parentof(object);

    if (corto_class_instanceof(corto_interface_o, corto_typeof(parent))) {
        corto_interface type = corto_interface(corto_typeof(parent));
        corto_id functionName;
        corto_member m = NULL;

        /* Get function name, lookup delegate, assign function */
        corto_signatureName(corto_nameof(object), functionName);
        if (corto_checkState(corto_type_o, CORTO_DEFINED) && (m = corto_interface_resolveMember(type, functionName)) &&
            (m->type->kind == CORTO_COMPOSITE) && (corto_interface(m->type)->kind == CORTO_DELEGATE)) {
            if (corto_delegate_instanceof(corto_delegate(m->type), object)) {
                /* Bind instance of function is a method */
                if (corto_procedure(corto_typeof(object))->kind == CORTO_METHOD) {
                    corto_setref(&((corto_delegatedata *) CORTO_OFFSET(parent, m->offset))->instance, parent);
                }
                /* Bind procedure */
                corto_setref(&((corto_delegatedata *) CORTO_OFFSET(parent, m->offset))->procedure, object);    
            } else {
                /* If there is a member that corresponds to a delegate but has a non matching
                 * signature, always report error */
                corto_id id1, id2;
                corto_error("member '%s' of delegate type '%s' does not match signature of '%s'",
                    corto_nameof(m), corto_fullname(m->type, id1), corto_fullname(object, id2));
                goto error;
            }
        }
    }

    return 0;
error:
    return -1;
/* $end */
}
Beispiel #6
0
/* Compare composites */
static corto_int16 corto_ser_composite(corto_walk_opt* s, corto_value *info, void* userData) {
    corto_compare_ser_t *data = userData;
    corto_type t = corto_value_typeof(info);
    void *this = corto_value_ptrof(info);
    void *value = (void*)((corto_word)corto_value_ptrof(&data->value) + ((corto_word)this - (corto_word)data->base));

    if (corto_interface(t)->kind == CORTO_UNION) {
        corto_int32 d1 = *(corto_int32*)this;
        corto_int32 d2 = *(corto_int32*)value;

        if (d1 != d2) {
            corto_member m1 = safe_corto_union_findCase(t, d1);
            corto_member m2 = safe_corto_union_findCase(t, d2);
            if (m1 != m2) {
                goto nomatch;
            }
        }
    }

    return corto_walk_members(s, info, userData);
nomatch:
    data->result = CORTO_NEQ;
    return 1;
}
Beispiel #7
0
/* Parse scope */
static corto_string corto_string_deserParseScope(corto_string str, struct corto_string_deserIndexInfo* info, corto_string_deser_t* data) {
    struct corto_string_deserIndexInfo rootInfo;
    corto_typeKind kind;
    void *ptr = data->ptr;

    if (data->allocValue) {
        ptr = data->allocValue(ptr, data);
    }

    /* Prepare privateData */
    corto_string_deser_t privateData = {
        .out = data->out,
        .scope = data->scope,
        .anonymousObjects = data->anonymousObjects,
        .type = data->type,
        .isObject = data->isObject,
        .members = {0, NULL}
    };

    /* Offset the scope-members with the current offset */
    if (info && info->m) {
        ptr = corto_getMemberPtr(data->isObject ? data->out : NULL, ptr, info->m);
    }
    privateData.ptr = ptr;

    /* Open scope of type */
    if (!info) {
        if (!data->type) {
            rootInfo.type = corto_typeof(data->out);
        } else {
            rootInfo.type = data->type;
        }
        rootInfo.m = NULL;
        rootInfo.parsed = FALSE;
        info = &rootInfo;
    }

    /* Check if type is any, composite or collection */
    kind = info->type->kind;

    if ((kind != CORTO_COMPOSITE) && (kind != CORTO_COLLECTION) && (kind != CORTO_ANY)) {
        corto_seterr("'{' unexpected for type '%s'",
            corto_fullpath(NULL, info->type));
        goto error;
    }

    /* Build index for type */
    if (info->type->kind == CORTO_COMPOSITE) {
        if (corto_interface(info->type)->kind == CORTO_UNION) {
            /* Parse discriminator */
            struct corto_string_deserIndexInfo dInfo;
            dInfo.type = (corto_type)corto_int32_o;
            dInfo.parsed = FALSE;
            dInfo.m = NULL;
            str = corto_string_deserParse(str + 1, &dInfo, &privateData);
            if (!str) {
                goto error;
            }

            /* Find corresponding union case */
            corto_int32 d = *(corto_int32*)ptr;
            corto_member m = safe_corto_union_findCase(info->type, d);
            if (!m) {
                corto_seterr("discriminator '%d' invalid for union '%s'",
                    d, corto_fullpath(NULL, info->type));
                goto error;
            }

            /* Build index for one member */
            struct corto_string_deserIndexInfo *caseInfo =
                corto_alloc(sizeof(struct corto_string_deserIndexInfo));
            caseInfo->type = m->type;
            caseInfo->parsed = FALSE;
            caseInfo->m = m;
            corto_string_deserIndexInsert(&privateData, caseInfo);
        } else {
            corto_walk_opt s = corto_string_deserBuildIndex();
            s.members = data->members;
            if (s.members.length) {
                s.access = 0;
            }
            if (corto_metawalk(&s, info->type, &privateData)) {
                goto error;
            }
        }

        /* Create iterator for index */
        if (privateData.index) {
            privateData.currentIter = _corto_ll_iter(privateData.index, &privateData.iterData);
        }
    /* If type is a collection, build index with one node for element */
    } else if (info->type->kind == CORTO_COLLECTION) {
        struct corto_string_deserIndexInfo *elementNode;
        elementNode = corto_alloc(sizeof(struct corto_string_deserIndexInfo));
        elementNode->m = NULL;
        elementNode->parsed = FALSE;
        elementNode->type = corto_collection(info->type)->elementType;
        corto_string_deserIndexInsert(&privateData, elementNode);

        /* Create iterator for index */
        privateData.currentIter = _corto_ll_iter(privateData.index, &privateData.iterData);
        privateData.allocValue = corto_string_deserAllocElem;
        privateData.allocUdata = info->type;

        if (ptr) {
            switch(corto_collection(info->type)->kind) {
            case CORTO_ARRAY:
            case CORTO_SEQUENCE:
                break;
            case CORTO_LIST:
                if (!*(corto_ll*)ptr) {
                    *(corto_ll*)ptr = corto_ll_new();
                } else {
                    corto_ll_clear(*(corto_ll*)ptr);
                }
                privateData.ptr = ptr;
                break;
            default:
                break;
            }
        }
    } else if (info->type->kind == CORTO_ANY) {
          struct corto_string_deserIndexInfo *anyNode;
          anyNode = corto_alloc(sizeof(struct corto_string_deserIndexInfo));
          anyNode->m = NULL;
          anyNode->parsed = FALSE;
          anyNode->type = corto_type(corto_type_o);
          corto_string_deserIndexInsert(&privateData, anyNode);
          privateData.currentIter = _corto_ll_iter(privateData.index, &privateData.iterData);
          privateData.allocValue = corto_string_deserAllocAny;
          privateData.allocUdata = anyNode;
    }

    /* Parse scope */
    if (!(str = corto_string_deserParse(str+1, info, &privateData))) {
        goto error;
    }

    corto_string_deserFreeIndex(&privateData);

    data->anonymousObjects = privateData.anonymousObjects;

    return str;
error:
    return NULL;
}

/* Get pointer to current destination value */
corto_int16 corto_string_getDestinationPtr(
    struct corto_string_deserIndexInfo* info,
    corto_string_deser_t* data,
    void **ptr_out)
{
    void *result = data->ptr;

    *ptr_out = NULL;

    if (!info) {
        corto_seterr("excess elements in string");
        goto error;
    }

    if (data->allocValue) {
        result = data->allocValue(result, data);
    }

    if (info->m) {
        result = corto_getMemberPtr(data->isObject ? data->out : NULL, data->ptr, info->m);
    }

    *ptr_out = result;

    return 0;
error:
    return -1;
}
Beispiel #8
0
static corto_int16 json_deserComposite(void* p, corto_type t, JSON_Value *v)
{
    corto_assert(t->kind == CORTO_COMPOSITE, "not deserializing composite");

    if (json_value_get_type(v) != JSONObject) {
        corto_seterr("expected object, got %s", json_valueTypeToString(v));
        goto error;
    }

    JSON_Object* o = json_value_get_object(v);
    size_t count = json_object_get_count(o);
    size_t i;
    corto_bool isUnion = corto_interface(t)->kind == CORTO_UNION;
    corto_int32 discriminator = 0;
    corto_member unionMember = NULL;

    for (i = 0; i < count; i++) {
        const char* memberName = json_object_get_name(o, i);
        corto_member member_o;

        if (!strcmp(memberName, "super")) {
            JSON_Value* value = json_object_get_value(o, memberName);
            if (json_deserItem(p, corto_type(corto_interface(t)->base), value)) {
                goto error;
            }
        } else if (!strcmp(memberName, "_d") && isUnion) {
            JSON_Value* value = json_object_get_value(o, memberName);
            if (json_deserPrimitive(&discriminator, corto_union(t)->discriminator, value)) {
                goto error;
            }
            unionMember = corto_union_findCase(t, discriminator);
            if (!unionMember) {
                corto_seterr("discriminator '%d' invalid for union '%s'",
                    discriminator, corto_fullpath(NULL, t));
            }
        } else {
            member_o = corto_interface_resolveMember(t, (char*)memberName);

            /* Ensure that we're not resolving members from a base type */
            if (!member_o || (corto_parentof(member_o) != t)) {
                corto_seterr(
                    "cannot find member '%s' in type '%s'",
                    memberName,
                    corto_fullpath(NULL, t));
                goto error;
            }

            if (isUnion && (unionMember != member_o)) {
                corto_seterr(
                    "member '%s' does not match discriminator '%d' (expected member '%s')",
                    memberName,
                    discriminator,
                    corto_idof(unionMember));
                goto error;
            } else if (isUnion) {
                corto_int32 prev = *(corto_int32*)p;
                if (prev != discriminator) {
                    corto_member prevMember = corto_union_findCase(t, prev);
                    corto_deinitp(CORTO_OFFSET(p, prevMember->offset), prevMember->type);
                    memset(CORTO_OFFSET(p, member_o->offset), 0, member_o->type->size);
                }
                *(corto_int32*)p = discriminator;
            }

            if (!json_deserMustSkip(member_o, p)) {
                JSON_Value* value = json_object_get_value(o, memberName);
                void *offset = CORTO_OFFSET(p, member_o->offset);
                if (member_o->modifiers & CORTO_OBSERVABLE) {
                    offset = *(void**)offset;
                    if (json_deserType(offset, member_o->type, value)) {
                        goto error;
                    }
                } else {
                    if (member_o->modifiers & CORTO_OPTIONAL) {
                        if (*(void**)offset) {
                            corto_deinitp(*(void**)offset, member_o->type);
                            memset(*(void**)offset, 0, member_o->type->size);
                        } else {
                            *(void**)offset = corto_calloc(member_o->type->size);
                        }
                        offset = *(void**)offset;
                    }
                    if (json_deserItem(offset, member_o->type, value)) {
                        goto error;
                    }
                }
            }
        }
    }

    return 0;
error:
    return -1;
}
Beispiel #9
0
 * This file contains wrapper functions for /corto/lang.
 */

#include <corto/lang/lang.h>
#include <corto/lang/_meta.h>

corto_bool _corto_collection_castable(
    corto_collection this,
    corto_type type)
{
    static corto_uint32 _methodId;
    corto_method _method;
    corto_bool _result;
    corto_interface _abstract;

    _abstract = corto_interface(corto_typeof(this));

    /* Determine methodId once, then cache it for subsequent calls. */
    if (!_methodId) {
        _methodId = corto_interface_resolveMethodId(_abstract, "castable(type type)");
    }
    corto_assert(_methodId, "virtual 'castable(type type)' not found in '%s'%s%s", corto_fullpath(NULL, _abstract), corto_lasterr()?": ":"", corto_lasterr());

    /* Lookup method-object. */
    _method = corto_interface_resolveMethodById(_abstract, _methodId);
    corto_assert(_method != NULL, "unresolved method '%s::castable(type type)@%d'", corto_idof(this), _methodId);

    corto_call(corto_function(_method), &_result, this, type);
    
    return _result;
}