Пример #1
0
    
    if(pv.major != major)
        return PACKAGE_INAPPROPRIATE_MAJOR;

    if(pv.minor < minor)
        return PACKAGE_INAPPROPRIATE_MINOR;
    
    return PACKAGE_LOADED;
}

char* packageError(){
    return dlerror();
}

void readQualifiedTypeName(EmojicodeChar *name, EmojicodeChar *namespace, FILE *in){
    *name = readEmojicodeChar(in);
    *namespace = readEmojicodeChar(in);
}

uint32_t readBlock(EmojicodeCoin **destination, uint8_t *variableCount, FILE *in){
    *variableCount = fgetc(in);
    uint32_t coinCount = readEmojicodeChar(in);

    *destination = malloc(sizeof(EmojicodeCoin) * coinCount);
    for (uint32_t i = 0; i < coinCount; i++) {
        (*destination)[i] = readCoin(in);
    }
    
    return coinCount;
}
Пример #2
0
Function* readBytecode(FILE *in) {
    uint8_t version = fgetc(in);
    if (version != kByteCodeVersion) {
        error("The bytecode file (bcsv %d) is not compatible with this interpreter (bcsv %d).\n",
              version, kByteCodeVersion);
    }

    DEBUG_LOG("Bytecode version %d", version);

    const int classCount = readUInt16(in);
    classTable = new Class*[classCount];

    DEBUG_LOG("%d class(es) on the whole", classCount);

    const int functionCount = readUInt16(in);
    functionTable = new Function*[functionCount];

    DEBUG_LOG("%d function(s) on the whole", functionCount);

    for (int i = 0, l = fgetc(in); i < l; i++) {
        DEBUG_LOG("📦 Reading package %d of %d", i + 1, l);
        readPackage(in);
    }

    CL_STRING = classTable[0];
    CL_LIST = classTable[1];
    CL_DATA = classTable[2];
    CL_DICTIONARY = classTable[3];
    CL_CLOSURE = classTable[4];

    DEBUG_LOG("✅ Read all packages");

    uint16_t tableSize = readUInt16(in);
    protocolDispatchTableTable = new ProtocolDispatchTable[tableSize];
    protocolDTTOffset = readUInt16(in);
    for (uint16_t count = readUInt16(in); count > 0; count--) {
        DEBUG_LOG("➡️ Still %d value type protocol tables to load", count);
        auto index = readUInt16(in);
        readProtocolTable(protocolDispatchTableTable[index - protocolDTTOffset], functionTable, in);
    }

    size_t n = readInstruction(in);
    boxObjectVariableRecordTable = new BoxObjectVariableRecords[n];
    for (size_t i = 0; i < n; i++) {
        boxObjectVariableRecordTable[i].count = readUInt16(in);
        boxObjectVariableRecordTable[i].records = new ObjectVariableRecord[boxObjectVariableRecordTable[i].count];
        for (size_t j = 0; j < boxObjectVariableRecordTable[i].count; j++) {
            boxObjectVariableRecordTable[i].records[j].variableIndex = readUInt16(in);
            boxObjectVariableRecordTable[i].records[j].condition = readUInt16(in);
            boxObjectVariableRecordTable[i].records[j].type = static_cast<ObjectVariableType>(readUInt16(in));
        }
    }

    stringPoolCount = readUInt16(in);
    DEBUG_LOG("Reading string pool with %d strings", stringPoolCount);
    stringPool = new Object*[stringPoolCount];
    for (int i = 0; i < stringPoolCount; i++) {
        Object *o = newObject(CL_STRING);
        auto *string = o->val<String>();

        string->length = readUInt16(in);
        string->charactersObject = newArray(string->length * sizeof(EmojicodeChar));

        for (int j = 0; j < string->length; j++) {
            string->characters()[j] = readEmojicodeChar(in);
        }

        stringPool[i] = o;
    }

    DEBUG_LOG("✅ Program ready for execution");
    return functionTable[0];
}
Пример #3
0
void readFunction(Function **table, FILE *in, FunctionFunctionPointer *linkingTable) {
    uint16_t vti = readUInt16(in);

    auto *function = static_cast<Function *>(malloc(sizeof(Function)));
    function->argumentCount = fgetc(in);

    DEBUG_LOG("*️⃣ Reading function with vti %d and takes %d argument(s)", vti, function->argumentCount);

    function->objectVariableRecordsCount = readUInt16(in);
    function->objectVariableRecords = new FunctionObjectVariableRecord[function->objectVariableRecordsCount];
    for (unsigned int i = 0; i < function->objectVariableRecordsCount; i++) {
        function->objectVariableRecords[i].variableIndex = readUInt16(in);
        function->objectVariableRecords[i].condition = readUInt16(in);
        function->objectVariableRecords[i].type = static_cast<ObjectVariableType>(readUInt16(in));
        function->objectVariableRecords[i].from = readInstruction(in);
        function->objectVariableRecords[i].to = readInstruction(in);
    }

    function->context = static_cast<ContextType>(fgetc(in));

    DEBUG_LOG("Read %d object variable records", function->objectVariableRecordsCount);

    function->frameSize = readUInt16(in);
    uint16_t native = readUInt16(in);
    if (native != 0) {
        DEBUG_LOG("Function has native function");
        function->handler = linkingTable[native];
    }

    function->block.instructionCount = readEmojicodeChar(in);

    function->block.instructions = new EmojicodeInstruction[function->block.instructionCount];
#ifdef DEBUG
    int numberPrint = 0;
#endif
    for (unsigned int i = 0; i < function->block.instructionCount; i++) {
        function->block.instructions[i] = readInstruction(in);
#ifdef DEBUG
        if (numberPrint == 0) {
            printf("%4d: ", i);
            auto ins = static_cast<Instructions>(function->block.instructions[i]);
            pinsname(ins);
            printf(" ");
            numberPrint = inscount(ins);
            if (numberPrint == 0) {
                puts("");
            }
        }
        else {
            printf("%d ", function->block.instructions[i]);
            if (--numberPrint == 0) {
                puts("");
            }
        }
#endif
    }

    DEBUG_LOG("Read block with %d coins and %d local variable(s)", function->block.instructionCount,
              function->frameSize);

    table[vti] = function;
}
Пример #4
0
void readPackage(FILE *in) {
    static uint16_t classNextIndex = 0;

    FunctionFunctionPointer *linkingTable;
    PrepareClassFunction prepareClass;

    uint_fast8_t packageNameLength = fgetc(in);
    if (packageNameLength == 0) {
        DEBUG_LOG("Package does not have native binary");
        linkingTable = sLinkingTable;
        prepareClass = sPrepareClass;
    }
    else {
        DEBUG_LOG("Package has native binary");
        auto name = new char[packageNameLength];
        fread(name, sizeof(char), packageNameLength, in);

        uint16_t major = readUInt16(in);
        uint16_t minor = readUInt16(in);

        DEBUG_LOG("Package is named %s and has version %d.%d.x", name, major, minor);

        PackageLoadingState s = packageLoad(name, major, minor, &linkingTable, &prepareClass);

        if (s == PACKAGE_INAPPROPRIATE_MAJOR) {
            error("Installed version of package \"%s\" is incompatible with required version %d.%d. (How did you made Emojicode load this version of the package?!)", name, major, minor);
        }
        else if (s == PACKAGE_INAPPROPRIATE_MINOR) {
            error("Installed version of package \"%s\" is incompatible with required version %d.%d. Please update to the latest minor version.", name, major, minor);
        }
        else if (s == PACKAGE_LOADING_FAILED) {
            error("Could not load package \"%s\" %s.", name, packageError());
        }

        delete [] name;
    }

    for (int classCount = readUInt16(in); classCount > 0; classCount--) {
        DEBUG_LOG("➡️ Still %d class(es) to load", classCount);
        EmojicodeChar name = readEmojicodeChar(in);

        auto *klass = new Class;
        classTable[classNextIndex++] = klass;

        DEBUG_LOG("Loading class %X into %p", name, klass);

        klass->superclass = classTable[readUInt16(in)];
        int instanceVariableCount = readUInt16(in);

        int methodCount = readUInt16(in);
        klass->methodsVtable = new Function*[methodCount];

        bool inheritsInitializers = fgetc(in);
        int initializerCount = readUInt16(in);
        klass->initializersVtable = new Function*[initializerCount];

        DEBUG_LOG("Inherting intializers: %s", inheritsInitializers ? "true" : "false");

        DEBUG_LOG("%d instance variable(s); %d methods; %d initializer(s)",
                  instanceVariableCount, initializerCount, methodCount);

        uint_fast16_t localMethodCount = readUInt16(in);
        uint_fast16_t localInitializerCount = readUInt16(in);

        DEBUG_LOG("Reading %d method(s) and %d initializer(s) that are not inherited or overriden",
                  localMethodCount, localInitializerCount);

        if (klass != klass->superclass) {
            memcpy(klass->methodsVtable, klass->superclass->methodsVtable, methodCount * sizeof(Function*));
            if (inheritsInitializers) {
                memcpy(klass->initializersVtable, klass->superclass->initializersVtable,
                       initializerCount * sizeof(Function*));
            }
        }
        else {
            klass->superclass = nullptr;
        }

        for (uint_fast16_t i = 0; i < localMethodCount; i++) {
            DEBUG_LOG("Reading method %d", i);
            readFunction(klass->methodsVtable, in, linkingTable);
        }

        for (uint_fast16_t i = 0; i < localInitializerCount; i++) {
            DEBUG_LOG("Reading initializer %d", i);
            readFunction(klass->initializersVtable, in, linkingTable);
        }

        readProtocolTable(klass->protocolTable, klass->methodsVtable, in);

        // Allow inheritance from class with value, e.g. list
        klass->valueSize = klass->superclass && klass->superclass->valueSize ? klass->superclass->valueSize : 0;
        prepareClass(klass, name);
        klass->size = alignSize(sizeof(Object) + klass->valueSize + instanceVariableCount * sizeof(Value));

        klass->instanceVariableRecordsCount = readUInt16(in);
        klass->instanceVariableRecords = new FunctionObjectVariableRecord[klass->instanceVariableRecordsCount];
        for (size_t i = 0; i < klass->instanceVariableRecordsCount; i++) {
            klass->instanceVariableRecords[i].variableIndex = readUInt16(in);
            klass->instanceVariableRecords[i].condition = readUInt16(in);
            klass->instanceVariableRecords[i].type = static_cast<ObjectVariableType>(readUInt16(in));
        }

        DEBUG_LOG("Read %d object variable records", klass->instanceVariableRecordsCount);
    }

    for (int functionCount = readUInt16(in); functionCount > 0; functionCount--) {
        DEBUG_LOG("➡️ Still %d functions to come", functionCount);
        readFunction(functionTable, in, linkingTable);
    }
}