cx_int16 Fast_Member_resolveMember(Fast_Member _this, cx_type type, cx_string member) { cx_object o = NULL; if (cx_instanceof(cx_type(cx_interface_o), type) && !strcmp(member, "super")) { if (cx_interface(type)->base) { _this->member = NULL; cx_set(&Fast_Expression(_this)->type, cx_interface(type)->base); } else { cx_id id; Fast_Parser_error(yparser(), "type '%s' has no base", Fast_Parser_id(type, id)); goto error; } } else { if (cx_instanceof(cx_type(cx_interface_o), type)) { o = cx_interface_resolveMember(cx_interface(type), member); } if (!o) { /* If no members are found for name, look for methods */ o = cx_type_resolveProcedure(type, member); if (!o) { cx_id id; Fast_Parser_error(yparser(), "unresolved member '%s' for type '%s'", member, Fast_Parser_id(type, id)); goto error; } cx_set(&Fast_Expression(_this)->type, cx_function(o)->returnType); } else { cx_set(&Fast_Expression(_this)->type, cx_member(o)->type); } _this->member = o; cx_keep_ext(_this, o, "Keep object for member-expression"); } return 0; error: return -1; }
/* ::cortex::lang::type::copy(any value) */ cx_int16 cx_type_copy(cx_any _this, cx_any value) { /* $begin(::cortex::lang::type::copy) */ cx_copy_ser_t data; struct cx_serializer_s s; cx_value v1; cx_int16 result; if (_this.type->reference || value.type->reference) { cx_valueObjectInit(&data.value, _this.value); cx_valueObjectInit(&v1, value.value); } else { cx_valueValueInit(&data.value, NULL, cx_type(_this.type), _this.value); cx_valueValueInit(&v1, NULL, cx_type(value.type), value.value); } s = cx_copy_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_ON_FAIL); result = cx_serializeValue(&s, &v1, &data); if (result) { cx_id id, id2; cx_error("type::copy: failed to copy value of type '%s' to value of type '%s'", cx_fullname(_this.type, id), cx_fullname(value.type, id2)); } return result; /* $end */ }
/* Obtain inttype from value */ cx_type Fast_Expression_getIntTypeFromValue(cx_int64 v, cx_primitive t) { cx_type result = NULL; if (v < 0) { if(t->kind == CX_UINTEGER) { /* Overflow */ if (((cx_uint64)v) <= 4294967295) { result = cx_type(cx_uint32_o); } else { result = cx_type(cx_uint64_o); } } else if (v >= -128) { result = cx_type(cx_int8_o); } else if (v >= -32768) { result = cx_type(cx_int16_o); } else if (v >= -2147483648) { result = cx_type(cx_int32_o); } else { result = cx_type(cx_int64_o); } } else { if (v <= 255) { result = cx_type(cx_uint8_o); } else if (v <= 65535) { result = cx_type(cx_uint16_o); } else { result = cx_type(cx_uint32_o); } } return result; }
/* ::cortex::lang::list::construct() */ cx_int16 cx_list_construct(cx_list _this) { /* $begin(::cortex::lang::list::construct) */ cx_type(_this)->hasResources = TRUE; cx_type(_this)->size = sizeof(cx_ll); cx_type(_this)->alignment = CX_ALIGNMENT(cx_ll); if (!cx_collection(_this)->elementType) { cx_error("no elementtype provided for list"); goto error; } return cx_type_construct(cx_type(_this)); error: return -1; /* $end */ }
/* ::cortex::lang::function::bind() */ cx_int16 cx_function_bind(cx_function _this) { /* $begin(::cortex::lang::function::bind) */ /* Count the size based on the parameters and store parameters in slots */ if (!_this->size) { cx_uint32 i; for(i=0; i<_this->parameters.length; i++) { if (_this->parameters.buffer[i].passByReference) { _this->size += sizeof(cx_word); } else { cx_type paramType = _this->parameters.buffer[i].type; switch(paramType->kind) { case CX_ANY: _this->size += sizeof(cx_any); break; case CX_PRIMITIVE: _this->size += cx_type_sizeof(paramType); break; default: _this->size += sizeof(void*); break; } } } /* Add size of this-pointer - this must be moved to impl of methods, delegates and callbacks. */ if (!(cx_typeof(_this) == cx_type(cx_function_o))) { if (cx_typeof(_this) == cx_type(cx_metaprocedure_o)) { _this->size += sizeof(cx_any); } else { _this->size += sizeof(cx_object); } } } /* If no returntype is set, make it void */ if (!_this->returnType) { cx_set(&_this->returnType, cx_void_o); } /* Bind with interface if possible */ if (cx_delegate_bind(_this)) { goto error; } return 0; error: return -1; /* $end */ }
/* ::cortex::lang::struct::compatible(type type) */ cx_bool cx_struct_compatible_v(cx_struct _this, cx_type type) { /* $begin(::cortex::lang::struct::compatible) */ cx_bool result; cx_assert(cx_class_instanceof(cx_struct_o, _this), "struct::compatible called on non-struct object."); result = FALSE; /* Call overloaded type::compatible function first to check for generic compatibility. */ if (!cx_type_compatible_v(cx_type(_this), type)) { /* Type must be at least struct for it to be compatible. */ if (cx_class_instanceof(cx_struct_o, type)) { cx_interface e; /* Check if '_this' is superclass of 'type' */ e = cx_interface(type); do { e = cx_interface(e)->base; }while(e && (e != cx_interface(_this))); result = (e == (cx_interface)_this); } } else { result = TRUE; } return result; /* $end */ }
/* $header(::cortex::Fast::Expression::getType_expr) */ cx_type Fast_Expression_getType_intern(Fast_Expression _this, cx_type target, Fast_Expression targetExpr) { cx_type result = Fast_Expression_getType(_this); if (!result) { if ((Fast_Node(_this)->kind == Fast_LiteralExpr) && (Fast_Literal(_this)->kind == Fast_Nothing)) { if (target) { if (target->reference) { result = target; } else if ((target->kind == CX_PRIMITIVE) && (cx_primitive(target)->kind == CX_TEXT)) { result = cx_type(cx_string_o); } else { if (targetExpr && targetExpr->isReference) { result = target; } else { goto error; } } } else { goto error; } } else if (Fast_Node(_this)->kind == Fast_InitializerExpr) { result = target; } else { goto error; } } else if ((target && (target->kind == CX_VOID) && target->reference)) { result = cx_object_o; } return result; error: Fast_Parser_error(yparser(), "inconsistent usage of references"); return NULL; }
/* ::cortex::lang::type::compare(any value) */ cx_equalityKind cx_type_compare(cx_any _this, cx_any value) { /* $begin(::cortex::lang::type::compare) */ cx_compare_ser_t data; struct cx_serializer_s s; cx_value v1; cx_valueValueInit(&v1, NULL, cx_type(_this.type), _this.value); cx_valueValueInit(&data.value, NULL, cx_type(value.type), value.value); s = cx_compare_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_NEVER); cx_serializeValue(&s, &v1, &data); return data.result; /* $end */ }
/* ::cortex::lang::type::resolveProcedure(string name) */ cx_function cx_type_resolveProcedure(cx_type _this, cx_string name) { /* $begin(::cortex::lang::type::resolveProcedure) */ cx_function result = NULL; /* If type is an interface, try first to resolve a method on the interface */ if (cx_instanceof((cx_type)cx_interface_o, _this)) { result = (cx_function)cx_interface_resolveMethod(cx_interface(_this), name); } /* If no method is found or type is not an interface, resolve metaprocedure */ if (!result) { cx_function *f; cx_int32 d = 0, prevD = 9999; cx_class metaclass = cx_class(cx_typeof(_this)); /* Walk inheritance of metaclass to find metaprocedure */ do { if ((f = cx_vtableLookup(&cx_type(metaclass)->metaprocedures, name, NULL, &d))) { if (d < prevD) { result = *f; prevD = d; } } metaclass = cx_class(cx_interface(metaclass)->base); }while(metaclass && !result); } return result; /* $end */ }
/* ::cortex::lang::text::init() */ cx_int16 cx_text_init(cx_text _this) { /* $begin(::cortex::lang::text::init) */ cx_type(_this)->hasResources = TRUE; cx_primitive(_this)->kind = CX_TEXT; cx_primitive(_this)->width = CX_WIDTH_WORD; return cx_primitive_init((cx_primitive)_this); /* $end */ }
/* ::cortex::lang::bitmask::init() */ cx_int16 cx_bitmask_init(cx_bitmask _this) { /* $begin(::cortex::lang::bitmask::init) */ cx_primitive(_this)->kind = CX_BITMASK; cx_primitive(_this)->width = CX_WIDTH_32; cx_set(&cx_type(_this)->defaultType, cx_constant_o); return cx_primitive_init((cx_primitive)_this); /* $end */ }
/* Define type */ static void cx_defineType(cx_object o, cx_uint32 size) { cx_defineObject(o); /* Size validation */ if (cx_type(o)->size != size) { cx_id id; cx_error("bootstrap: size validation failed for type '%s' - metatype = %d, c-type = %d.", cx_fullname(o, id), cx_type(o)->size, size); } }
/* ::cortex::lang::constant::init() */ cx_int16 cx_constant_init(cx_constant *_this) { /* $begin(::cortex::lang::constant::init) */ cx_object parent; parent = cx_parentof(_this); /* Parent must be an enum */ if (cx_typeof(parent) == cx_type(cx_enum_o)) { cx__enum_bindConstant(parent, _this); } else if (cx_typeof(parent) == cx_type(cx_bitmask_o)) { cx__bitmask_bindConstant(parent, _this); } else { cx_id id; cx_error("::constant::init: parent of constant '%s' is not an enum.", cx_fullname(_this, id)); goto error; } return 0; error: return -1;/* $end */ }
/* ::cortex::Fast::StaticInitializer::define() */ cx_int16 Fast_StaticInitializer_define(Fast_StaticInitializer _this) { /* $begin(::cortex::Fast::StaticInitializer::define) */ cx_uint32 variable; cx_object o; /* Types are defined during 1st pass. All other objects are defined when a program starts. Defining types * at compile-time is required to do validity checking while parsing. On the other hand, objects cannot be * defined at compile-time because class constructors\destructors are not yet defined at that point. This * would cause object creation\destruction without calling the appropriate constructors\destructors. */ for(variable=0; variable<Fast_Initializer(_this)->variableCount; variable++) { o = (cx_object)Fast_Object(Fast_Initializer(_this)->variables[variable].object)->value; if (cx_instanceof(cx_type(cx_type_o), o) || (cx_checkAttr(o, CX_ATTR_SCOPED) && cx_instanceof(cx_type(cx_type_o), cx_parentof(o)))) { if (cx_define(o)) { cx_id id1, id2; Fast_Parser_error(yparser(), "define of variable '%s' of type '%s' failed", Fast_Parser_id(o, id1), Fast_Parser_id(cx_typeof(o), id2)); goto error; } } else { Fast_Expression refVar = Fast_Expression(Fast_Object__create(o)); refVar->isReference = TRUE; /* Always treat object as reference */ Fast_Define defineStmt = Fast_Define__create(refVar); Fast_Parser_addStatement(yparser(), Fast_Node(defineStmt)); Fast_Parser_collect(yparser(), defineStmt); Fast_Parser_collect(yparser(), refVar); } } Fast_Initializer_define_v(Fast_Initializer(_this)); return 0; error: return -1; /* $end */ }
/* Do metawalk on type */ cx_int16 cx_metaWalk(cx_serializer s, cx_type type, void* userData) { cx__object* o; cx_int16 result; /* Instantiate dummy-object */ o = cx_malloc(sizeof(cx__object) + type->size); /* alloca is dangerous here because objects can get large, causing stack overflows. */ memset(o, 0, sizeof(cx__object) + type->size); o->type = cx_type(type); o->refcount = 1; result = cx_serialize(s, CX_OFFSET(o, sizeof(cx__object)), userData); cx_dealloc(o); return result; }
/* ::cortex::ic::program::add(node n) */ cx_void ic_program_add(ic_program _this, ic_node n) { /* $begin(::cortex::ic::program::add) */ if (n->kind == IC_OP) { if (!ic_op_validate(ic_op(n))) { _this->errors++; } } if (cx_instanceof(cx_type(ic_storage_o), n)) { ic_node_list__append(_this->scope->storages, n); } else { ic_node_list__append(_this->scope->program, n); } /* $end */ }
/* ::cortex::Fast::Element::construct() */ cx_int16 Fast_Element_construct(Fast_Element _this) { /* $begin(::cortex::Fast::Element::construct) */ cx_type lvalueType, rvalueType; Fast_Storage(_this)->kind = Fast_ElementStorage; lvalueType = Fast_Expression_getType(_this->lvalue); if (lvalueType) { if (lvalueType->kind == CX_COLLECTION) { rvalueType = Fast_Expression_getType(_this->rvalue); if (rvalueType) { if (cx_collection(lvalueType)->kind != CX_MAP) { if (!cx_type_castable(cx_type(cx_uint32_o), rvalueType)) { cx_id id; Fast_Parser_error(yparser(), "expected integer expression for index, got '%s'", Fast_Parser_id(rvalueType, id)); goto error; } } else { if (!cx_type_castable(cx_map(lvalueType)->keyType, rvalueType)) { cx_id id, id2; Fast_Parser_error(yparser(), "expected expression of type '%s' for key, got '%s'", Fast_Parser_id(cx_map(lvalueType)->keyType, id), Fast_Parser_id(rvalueType, id2)); goto error; } } } /* Set type of expression */ cx_set(&Fast_Expression(_this)->type, cx_collection(lvalueType)->elementType); } else { cx_id id; Fast_Parser_error(yparser(), "cannot obtain element from _this of non-collection type '%s'", Fast_Parser_id(lvalueType, id)); goto error; } } else { Fast_Parser_error(yparser(), "dynamic expressions are not yet supported"); goto error; } Fast_Expression(_this)->isReference = cx_collection(lvalueType)->elementType->reference; return Fast_Storage_construct(Fast_Storage(_this)); error: return -1; /* $end */ }
cx_type Fast_Expression_narrowType(Fast_Expression expr) { cx_int64 v; cx_type t = Fast_Expression_getType(expr); if (Fast_Node(expr)->kind == Fast_LiteralExpr) { if (t && (t->kind == CX_PRIMITIVE)) { switch(cx_primitive(t)->kind) { case CX_INTEGER: case CX_UINTEGER: Fast_Expression_serialize(expr, cx_type(cx_int64_o), (cx_word)&v); t = Fast_Expression_getIntTypeFromValue(v, cx_primitive(t)); break; default: break; } } } return t; }
/* ::cortex::lang::struct::init() */ cx_int16 cx_struct_init(cx_struct _this) { /* $begin(::cortex::lang::struct::init) */ /* If not bootstrapping, set baseAccess to GLOBAL | PUBLIC */ if (cx_checkState(cx_type_o, CX_DEFINED)) { _this->baseAccess = CX_GLOBAL; } if (cx_interface_init(cx_interface(_this))) { goto error; } cx_interface(_this)->kind = CX_STRUCT; cx_type(_this)->reference = FALSE; return 0; error: return -1; /* $end */ }
/* ::cortex::Fast::Member::toIc(ic::program program,ic::storage storage,bool stored) */ ic_node Fast_Member_toIc_v(Fast_Member _this, ic_program program, ic_storage storage, cx_bool stored) { /* $begin(::cortex::Fast::Member::toIc) */ ic_member result = NULL; cx_member member; ic_node lvalue; CX_UNUSED(stored); CX_UNUSED(storage); /* Get lvalue & rvalue */ lvalue = Fast_Node_toIc(Fast_Node(_this->lvalue), program, NULL, FALSE); if (Fast_Node(_this->rvalue)->kind == Fast_LiteralExpr) { if (Fast_Literal(_this->rvalue)->kind == Fast_Text) { cx_type t = Fast_Expression_getType(_this->lvalue); if (cx_instanceof(cx_type(cx_interface_o), t)) { cx_interface baseType = cx_interface(t); member = cx_interface_resolveMember(baseType, Fast_String(_this->rvalue)->value); } else { cx_id id; Fast_Parser_error(yparser(), "cannot resolve members on non-interface type '%s'", Fast_Parser_id(t, id)); goto error; } } else { Fast_Parser_error(yparser(), "dynamic resolving of members not yet supported."); goto error; } } else { Fast_Parser_error(yparser(), "dynamic resolving of members not yet supported."); goto error; } if (member) { result = ic_program_getMember(program, ic_storage(lvalue), member); } return (ic_node)result; error: return NULL; /* $end */ }
/* ::cortex::web::SockJsServer::poll() */ cx_void web_SockJsServer_poll(web_SockJsServer _this) { /* $begin(::cortex::web::SockJsServer::poll) */ struct mg_server *server = (struct mg_server *)_this->server; mg_poll_server(server, _this->pollTimemoutMillis); _this->timeElapsed += _this->pollTimemoutMillis; /* Send heartbeats for all live connections every n seconds */ if (_this->timeElapsed >= (WEB_SOCKJSSERVER_DEFAULT_HEARTBEAT_TIMEOUT * 1000)) { cx_ll scope = cx_scopeClaim(_this); cx_iter iter = cx_llIter(scope); while (cx_iterHasNext(&iter)) { cx_object o = cx_iterNext(&iter); if (cx_instanceof(cx_type(web_SockJsServer_Connection_o), o)) { web_SockJsServer_Connection c = web_SockJsServer_Connection(o); mg_websocket_printf((struct mg_connection *)c->conn, WEBSOCKET_OPCODE_TEXT, "h"); } } cx_scopeRelease(scope); _this->timeElapsed = 0; } /* $end */ }
cx_type cx_rbtreeKeyType(cx_rbtree tree) { return cx_type(jsw_rbtype((jsw_rbtree_t*)tree)); }
/* ::cortex::Fast::Expression::cast(type type,bool isReference) */ Fast_Expression Fast_Expression_cast(Fast_Expression _this, cx_type type, cx_bool isReference) { /* $begin(::cortex::Fast::Expression::cast) */ cx_type exprType, refType; Fast_Expression result = NULL; cx_bool castRequired = TRUE; cx_assert(type != NULL, "cannot cast to unknown type NULL"); exprType = Fast_Expression_getType(_this); if((_this->deref == Fast_ByReference) && !isReference && !exprType->reference) { refType = cx_object_o; } else { refType = exprType; } /* If types are different, cast */ if (refType != type) { if (!exprType) { /* If expression is an untyped initializer, create an anonymous variable of the destination type * and assign it to the initializer. */ if(Fast_Node(_this)->kind == Fast_InitializerExpr) { Fast_Expression local = Fast_Expression(Fast_Temporary__create(type, FALSE)); Fast_InitializerExpression_insert(Fast_InitializerExpression(_this), local); result = local; castRequired = TRUE; }else { castRequired = FALSE; } } else if (cx_type_castable(type, refType)) { void *value = NULL; /* If expression is a literal or constant create new literal of right type */ value = (void*)Fast_Expression_getValue(_this); if (value) { if (type->reference && (Fast_Node(_this)->kind == Fast_LiteralExpr)) { /* If destination type is a reference and the literal is a string this results * in a resolve at run-time. */ switch(Fast_Literal(_this)->kind) { case Fast_Text: break; case Fast_Nothing: /* No cast required */ break; default: { cx_id id1, id2; /* Invalid cast */ Fast_Parser_error(yparser(), "cannot cast from '%s' to '%s'", Fast_Parser_id(exprType, id1), Fast_Parser_id(type, id2)); break; } } } /* Create literal expressions based on destination type */ switch(cx_primitive(type)->kind) { case CX_BOOLEAN: { cx_bool dstValue = FALSE; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_bool_o), &dstValue); result = Fast_Expression(Fast_Boolean__create(dstValue)); break; } case CX_CHARACTER: { cx_char dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_char_o), &dstValue); result = Fast_Expression(Fast_Character__create(dstValue)); break; } case CX_BINARY: case CX_UINTEGER: { cx_uint64 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_uint64_o), &dstValue); result = Fast_Expression(Fast_Integer__create(dstValue)); break; } case CX_INTEGER: { cx_int64 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_int64_o), &dstValue); result = Fast_Expression(Fast_SignedInteger__create(dstValue)); break; } case CX_FLOAT: { cx_float64 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_float64_o), &dstValue); result = Fast_Expression(Fast_FloatingPoint__create(dstValue)); break; } case CX_TEXT: { cx_string dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_string_o), &dstValue); result = Fast_Expression(Fast_String__create(dstValue)); break; } case CX_ENUM: case CX_BITMASK: { cx_int32 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_int32_o), &dstValue); result = Fast_Expression(Fast_SignedInteger__create(dstValue)); break; } case CX_ALIAS: { cx_int32 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_word_o), &dstValue); result = Fast_Expression(Fast_SignedInteger__create(dstValue)); break; } } if (result){ cx_set_ext(result, &Fast_Expression(result)->type, type, "Set correct type after cast"); } } else { /* TODO: This functionality must be pushed down to the assembler. For all this function is concerned a cast should only be required when a type is a) castable and b) not compatible. */ /* If both types are primitive make sure that no cast is inserted for primitives * of the same kind or 'score' to the same width */ if ((refType->kind == CX_PRIMITIVE) && (type->kind == CX_PRIMITIVE) && (Fast_Expression_getCastScore(cx_primitive(refType)) == Fast_Expression_getCastScore(cx_primitive(type)))) { if (cx_primitive(exprType)->width != cx_primitive(type)->width) { result = Fast_Expression(Fast_Cast__create(type, _this, isReference)); } else { /* Types have the same width, so no cast required */ castRequired = FALSE; } /* Interface-downcasting doesn't require an explicit cast */ } else if (!cx_instanceof(cx_type(cx_interface_o), type)) { result = Fast_Expression(Fast_Cast__create(type, _this, isReference)); } else { castRequired = FALSE; } } /* If object is a reference and targetType is string, insert toString operation */ } else /*if (_this->isReference || Fast_Expression_getType(_this)->reference)*/ { if ((type->kind == CX_PRIMITIVE) && (cx_primitive(type)->kind == CX_TEXT)) { /* Create call-expression */ result = Fast_Expression(Fast_createCallWithArguments(_this, "toString", NULL)); if (!result) { goto error; } cx_keep(result); /* If type is of a generic reference type, accept any reference without cast */ } else if (type->kind == CX_VOID && type->reference) { castRequired = FALSE; /* If assigning to a generic reference, insert cast */ } else if (exprType->kind == CX_VOID && exprType->reference && isReference) { result = Fast_Expression(Fast_Cast__create(type, _this, isReference)); } } } else { castRequired = FALSE; } if (result && castRequired) { Fast_Parser_collect(yparser(), result); } else { if (castRequired) { cx_id id1, id2; Fast_Parser_error(yparser(), "no conversion from '%s' to '%s'", Fast_Parser_id(exprType, id1), Fast_Parser_id(type, id2)); } } return result; error: return NULL; /* $end */ }
/* ::cortex::Fast::String::toIc(ic::program program,ic::storage storage,bool stored) */ ic_node Fast_String_toIc_v(Fast_String _this, ic_program program, ic_storage storage, cx_bool stored) { /* $begin(::cortex::Fast::String::toIc) */ ic_node result = NULL; CX_UNUSED(storage); CX_UNUSED(stored); /* Parse string after parsing script and thus not interfere with parser */ if (Fast_String_parse(_this)) { goto error; } if (!cx_llSize(_this->elements)) { result = (ic_node)ic_literal__create((cx_any){cx_type(cx_string_o), &_this->value, FALSE}); } else { if (stored) { cx_iter elementIter; Fast_Expression element; ic_node icElement1, icElement2; cx_uint32 elementCount = cx_llSize(_this->elements); cx_bool stored = FALSE; ic_node dummy; cx_uint32 accPushCount = 0; cx_type elementType; if (storage && (storage->type != cx_type(cx_string_o))) { Fast_Parser_error(yparser(), "storage for string-expression '%s' has invalid type (%s)", _this->value, cx_nameof(storage->type)); goto error; } dummy = (ic_node)ic_literal__create((cx_any){cx_type(cx_string_o), NULL, FALSE}); result = (ic_node)storage; elementIter = cx_llIter(_this->elements); while(cx_iterHasNext(&elementIter)) { ic_accumulator acc = ic_program_pushAccumulator(program, (cx_type)cx_string_o, FALSE, FALSE); accPushCount++; element = cx_iterNext(&elementIter); elementType = Fast_Expression_getType(element); if (!elementType) { element = Fast_Expression(Fast_String__create(CX_NULL_STRING)); } else if (elementType != cx_type(cx_string_o)) { element = Fast_Expression_cast(element, cx_type(cx_string_o), FALSE); if(!element) { goto error; } } icElement1 = Fast_Node_toIc(Fast_Node(element), program, (ic_storage)acc, TRUE); if (!icElement1) { goto error; } if (elementCount == 1) { if (storage) { IC_2(program, Fast_Node(_this)->line, ic_strcpy, storage, icElement1, IC_DEREF_VALUE, IC_DEREF_VALUE); } else { result = (ic_node)icElement1; } stored = TRUE; } else { if (elementCount) { if (cx_iterHasNext(&elementIter)) { ic_accumulator acc = ic_program_pushAccumulator(program, (cx_type)cx_string_o, FALSE, FALSE); accPushCount++; element = cx_iterNext(&elementIter); elementType = Fast_Expression_getType(element); if (!elementType) { element = Fast_Expression(Fast_String__create(CX_NULL_STRING)); } else if (elementType && (Fast_Expression_getType(element) != cx_type(cx_string_o))) { element = Fast_Expression_cast(element, cx_type(cx_string_o), FALSE); if (!element) { goto error; } } icElement2 = Fast_Node_toIc(Fast_Node(element), program, (ic_storage)acc, TRUE); if (!icElement2) { goto error; } IC_2(program, Fast_Node(_this)->line, ic_strcat, icElement1, icElement2, IC_DEREF_VALUE, IC_DEREF_VALUE); elementCount--; } } else { IC_2(program, Fast_Node(_this)->line, ic_strcat, icElement1, dummy, IC_DEREF_VALUE, IC_DEREF_VALUE); } } elementCount--; } /* If string is not yet copied, insert copy instruction */ if (!stored) { IC_2(program, Fast_Node(_this)->line, ic_strcpy, storage, dummy, IC_DEREF_VALUE, IC_DEREF_VALUE); stored = TRUE; } while(accPushCount) { ic_program_popAccumulator(program); accPushCount--; } } } return result; error: return NULL; /* $end */ }
/* Build dependency-administration for object */ int cx_genDepBuildAction(cx_object o, void* userData) { g_itemWalk_t data; struct g_depWalk_t walkData; struct cx_serializer_s s; int result; cx_object parent = NULL; if (cx_checkAttr(o, CX_ATTR_SCOPED)) { parent = cx_parentof(o); } data = userData; /* If object is cortex_lang_o, signal that a bootstrap is found, indicating * that dependencies should be disregarded. */ if (o == cortex_lang_o) { data->bootstrap = TRUE; result = 0; } else { /* Insert type-dependency: object can be declared only after it's type is defined. */ if (g_mustParse(data->g, cx_typeof(o))) { cx_depresolver_depend(data->resolver, o, CX_DECLARED, cx_typeof(o), CX_DEFINED); } /* TODO: this is not nice */ if (cx_class_instanceof(cx_procedure_o, cx_typeof(o))) { /* Insert base-dependency: methods may only be declared after the base of a class has been defined. */ if (cx_typeof(o) != cx_type(cx_function_o)) { if (cx_class_instanceof(cx_class_o, parent) && cx_interface(parent)->base) { if (g_mustParse(data->g, cx_interface(parent)->base)) { cx_depresolver_depend(data->resolver, o, CX_DECLARED, cx_interface(parent)->base, CX_DEFINED); } } } /* Add dependencies on function parameters - types must be declared before function is declared. */ if (cx_genDepBuildProc(cx_function(o), data)) { goto error; } } /* Insert dependency on parent */ if (cx_checkAttr(o, CX_ATTR_SCOPED)) { if (parent != root_o) { /* Root is always available */ cx_int8 parentState = cx_type(cx_typeof(o))->parentState; cx_depresolver_depend(data->resolver, o, CX_DECLARED, parent, parentState); if (parentState == CX_DECLARED) { cx_depresolver_depend(data->resolver, parent, CX_DEFINED, o, CX_DEFINED); } } } /* Insert dependencies on references in the object-value */ walkData.o = o; walkData.data = data; s = cx_genDepSerializer(); if (cx_serialize(&s, o, &walkData)) { goto error; } result = 1; } return result; error: return 0; }
/* ::cortex::lang::struct::construct() */ cx_int16 cx_struct_construct(cx_struct _this) { /* $begin(::cortex::lang::struct::construct) */ cx_struct base; cx_uint16 alignment; cx_uint32 size; size = 0; alignment = 0; /* Insert members */ if (cx__interface_insertMembers(cx_interface(_this))) { goto error; } /* Calculate alignment of self */ if (cx_interface(_this)->members.length) { alignment = cx__interface_calculateAlignment(cx_interface(_this)); if (!alignment) { cx_id id; cx_error("error in definition of '%s'", cx_fullname(_this, id)); goto error; } } /* Check if struct inherits from another struct */ base = (cx_struct)cx_interface(_this)->base; /* Get maximum alignment from self and base-class and copy template parameters */ if (base) { if (!cx_instanceof(cx_type(cx_struct_o), base)) { cx_id id, id2; cx_error("struct '%s' inherits from non-struct type '%s'", cx_fullname(_this, id), cx_fullname(base, id2)); goto error; } if (cx_type(base)->alignment) { if (alignment < cx_type(base)->alignment) { alignment = cx_type(base)->alignment; } } } /* Set alignment of self */ cx_type(_this)->alignment = alignment; /* Get size of base-class */ if (base) { size = cx_type(base)->size; if (cx_type(base)->hasResources) { cx_type(_this)->hasResources = TRUE; } } /* Calculate size of self */ if (cx_interface(_this)->members.length) { size = cx__interface_calculateSize(cx_interface(_this), size); if (!size) { cx_id id; cx_error("error in definition of '%s'", cx_fullname(_this, id)); goto error; } } /* Set size of self */ cx_type(_this)->size = size; return cx_interface_construct(cx_interface(_this)); error: return -1; /* $end */ }
int cx_start(void) { /* Initialize threadkeys */ cx_threadTlsKey(&CX_KEY_OBSERVER_ADMIN, NULL); cx_threadTlsKey(&CX_KEY_WAIT_ADMIN, NULL); /* Init admin-lock */ cx_mutexNew(&cx_adminLock); /* Bootstrap sizes of types used in parameters, these are used to determine * argument-stack sizes for functions during function::bind. */ cx_type(cx_string_o)->size = sizeof(cx_string); cx_type(cx_int32_o)->size = sizeof(cx_int32); cx_type(cx_uint32_o)->size = sizeof(cx_uint32); cx_type(cx_any_o)->size = sizeof(cx_any); cx_type(cx_state_o)->size = sizeof(cx_state); cx_type(cx_attr_o)->size = sizeof(cx_attr); /* Initialize builtin scopes */ cx_initObject(root_o); cx_initObject(cortex_o); cx_initObject(cortex_lang_o); /* Define builtin scopes */ cx_defineObject(root_o); cx_defineObject(cortex_o); cx_defineObject(cortex_lang_o); /* Init objects */ SSO_OP_TYPE(cx_initType); SSO_OP_OBJECT(cx_initObject); SSO_OP_OBJECT_2ND(cx_initObject); /* Construct objects */ SSO_OP_OBJECT_2ND(cx_defineObject); SSO_OP_OBJECT(cx_defineObject); SSO_OP_TYPE(cx_defineType); /* Update refcounts of public members */ SSO_OP_TYPE(cx_updateRefType); SSO_OP_OBJECT(cx_updateRef); SSO_OP_OBJECT_2ND(cx_updateRef); /* Initialize conversions and operators */ cx_convertInit(); cx_operatorInit(); /* Register C-binding and vm-binding */ { cx_uint32 id; id = cx_callRegisterBinding(NULL, NULL, NULL, NULL); cx_assert(id == 1, "C-binding did not receive binding-id 1."); id = cx_callRegisterBinding(cx_call_vm, NULL, NULL, (cx_callDestructHandler)cx_callDestruct_vm); cx_assert(id == 2, "Vm-binding did not receive binding-id 2."); } /* Always randomize seed */ srand (time(NULL)); /* Init CRC table */ cx_crcInit(); return 0; }