int registerSymbol(ParserTable& table, ident_t symbol, int new_id) { if (symbol.compare("||")) { return _registerSymbol(table, "|", new_id); } else if (symbol.compare("&|")) { return _registerSymbol(table, "||", new_id); } else if (symbol.compare("-->")) { return _registerSymbol(table, "->", new_id); } else return _registerSymbol(table, symbol, new_id); }
bool VMTapeParser :: parseMessage(ident_t message, IdentifierString& reference) { int paramCounter = 0; size_t length = getlength(message); length = message.find('['); if (length != NOTFOUND_POS) { reference.copy(message + length + 1); if (reference[reference.Length() - 1] == ']') { reference.truncate(reference.Length() - 1); //if (emptystr(reference)) { // paramCounter = OPEN_ARG_COUNT; //} /*else */paramCounter = reference.ident().toInt(); } else return false; } else return false; reference.clear(); reference.append('0' + (char)paramCounter); reference.append(message, length); return true; }
bool VMTapeParser :: writeObject(TapeWriter& writer, int state, ident_t token) { if (token.compare(".")) { writer.writeCommand(POP_TAPE_MESSAGE_ID); } else { switch (state) { case dfaInteger: writer.writeCommand(PUSHN_TAPE_MESSAGE_ID, token); break; case dfaReal: writer.writeCommand(PUSHR_TAPE_MESSAGE_ID, token); break; case dfaLong: writer.writeCommand(PUSHL_TAPE_MESSAGE_ID, token); break; case dfaQuote: writer.writeCommand(PUSHS_TAPE_MESSAGE_ID, token); break; case dfaFullIdentifier: writer.writeCallCommand(token); break; case dfaIdentifier: writeSubject(writer, token); break; default: return false; } } return true; }
bool VMTapeParser :: writeArray(TapeWriter& writer, int state, ident_t token) { if (state == dfaInteger) { int value = token.toInt(); writer.writeCommand(NEW_TAPE_MESSAGE_ID, value); return true; } else return false; }
void ECodesAssembler :: fixJump(ident_t label, MemoryWriter& writer, LabelInfo& info) { _Memory* code = writer.Memory(); Map<ident_t, int>::Iterator it = info.fwdJumps.start(); while (!it.Eof()) { if (label.compare(it.key())) { (*code)[*it] = writer.Position() - *it - 4; } it++; } }
bool VMTapeParser :: writeExtension(TapeWriter& writer, ident_t message, int command) { IdentifierString reference; size_t dotPos = message.find('.'); if (parseMessage(message + dotPos + 1, reference)) { reference.insert(message, 0, dotPos + 1); writer.writeCommand(command, reference); return true; } else return false; }
bool ModuleScope :: includeNamespace(IdentifierList& importedNs, ident_t name, bool& duplicateInclusion) { // check if the namespace exists ReferenceNs virtualRef(name, NAMESPACE_REF); ref_t dummyRef = 0; _Module* extModule = project->resolveModule(virtualRef, dummyRef, true); if (extModule && dummyRef) { ident_t value = retrieve(importedNs.start(), name, NULL); if (value == NULL) { importedNs.add(name.clone()); saveIncludedModule(extModule); return true; } else duplicateInclusion = true; } return false; }
void ModuleScope :: saveListMember(ident_t name, ident_t memberName) { // HOTFIX : do not include itself IdentifierString sectionName("'", name); _Memory* section = module->mapSection(module->mapReference(sectionName, false) | mskMetaRDataRef, false); // check if the module alread included MemoryReader metaReader(section); while (!metaReader.Eof()) { ident_t s = metaReader.getLiteral(DEFAULT_STR); if (s.compare(memberName)) return; } // otherwise add it to the list MemoryWriter metaWriter(section); metaWriter.writeLiteral(memberName.c_str()); }
void parseMessageConstant(IdentifierString& message, ident_t reference) { // message constant: nverb&signature int verbId = 0; int signatureId = 0; // read the param counter int count = reference[0] - '0'; // skip the param counter reference+=1; int index = reference.find('&'); //HOTFIX: for generic GET message we have to ignore ampresand if (reference[index + 1] == 0) index = -1; if (index != -1) { //HOTFIX: for GET message we have &&, so the second ampersand should be used if (reference[index + 1] == 0 || reference[index + 1] == '&') index++; IdentifierString verb(reference, index); ident_t signature = reference + index + 1; // if it is a predefined verb if (verb[0] == '#') { verbId = verb[1] - 0x20; } message.append(signature); } else { message.append(reference); } }
ident_t ExecutableImage :: resolveTemplateWeakReference(ident_t referenceName) { ident_t resolvedName = _project->resolveForward(referenceName + TEMPLATE_PREFIX_NS_LEN); if (emptystr(resolvedName)) { if (referenceName.endsWith(CLASSCLASS_POSTFIX)) { // HOTFIX : class class reference should be resolved simultaneously with class one IdentifierString classReferenceName(referenceName, getlength(referenceName) - getlength(CLASSCLASS_POSTFIX)); classReferenceName.copy(resolveTemplateWeakReference(classReferenceName.c_str())); classReferenceName.append(CLASSCLASS_POSTFIX); _project->addForward(referenceName + TEMPLATE_PREFIX_NS_LEN, classReferenceName.c_str()); return _project->resolveForward(referenceName + TEMPLATE_PREFIX_NS_LEN); } // COMPILER MAGIC : try to find a template implementation ref_t resolvedRef = 0; _Module* refModule = _project->resolveWeakModule(referenceName + TEMPLATE_PREFIX_NS_LEN, resolvedRef, true); if (refModule != nullptr) { ident_t resolvedReferenceName = refModule->resolveReference(resolvedRef); if (isWeakReference(resolvedReferenceName)) { IdentifierString fullName(refModule->Name(), resolvedReferenceName); _project->addForward(referenceName + TEMPLATE_PREFIX_NS_LEN, fullName); } else _project->addForward(referenceName + TEMPLATE_PREFIX_NS_LEN, resolvedReferenceName); referenceName = _project->resolveForward(referenceName + TEMPLATE_PREFIX_NS_LEN); } else throw JITUnresolvedException(referenceName); } else referenceName = resolvedName; return referenceName; }
void printMethod(_Module* module, ident_t methodReference, int pageSize) { methodReference = trim(methodReference); int separator = methodReference.find('.'); if (separator == -1) { printf("Invalid command"); return; } IdentifierString className(methodReference, separator); ident_t methodName = methodReference + separator + 1; ref_t message = 0; // resolve method if (methodName[0] >= '0' && methodName[0] <= '9') { message = resolveMessageByIndex(module, className.ident(), methodName.toInt()); } else message = resolveMessage(module, methodName); if (message == 0) return; // find class VMT _Memory* vmt = findClassVMT(module, className); _Memory* code = findClassCode(module, className); if (vmt == NULL || code == NULL) { printLine("Class not found: ", className); return; } // find method entry MemoryReader vmtReader(vmt); // read tape record size size_t size = vmtReader.getDWord(); // read VMT header ClassHeader header; vmtReader.read((void*)&header, sizeof(ClassHeader)); VMTEntry entry; // read VMT while the entry not found size -= sizeof(ClassHeader); bool found = false; while (size > 0) { vmtReader.read((void*)&entry, sizeof(VMTEntry)); if (entry.message == message) { found = true; IdentifierString temp; temp.copy(className); temp.append('.'); printMessage(temp, module, entry.message); printLine("@method ", temp); printByteCodes(module, code, entry.address, 4, pageSize); print("@end\n"); break; } size -= sizeof(VMTEntry); } if (!found) { printLine("Method not found:", methodName); } }
ref_t resolveMessage(_Module* module, ident_t method) { int paramCount = 0; ref_t actionRef = 0; ref_t flags = 0; if (method.startsWith("params#")) { flags |= VARIADIC_MESSAGE; method = method.c_str() + getlength("params#"); } if (method.startsWith("prop#")) { flags |= PROPERTY_MESSAGE; method = method.c_str() + getlength("prop#"); } if (method.startsWith("#invoke")) { flags |= SPECIAL_MESSAGE; } if (method.startsWith("#private&")) { flags |= STATIC_MESSAGE; method = method.c_str() + getlength("#private&"); } if (method.compare("#init")) { flags |= SPECIAL_MESSAGE; } IdentifierString actionName; int paramIndex = method.find('[', -1); if (paramIndex != -1) { actionName.copy(method, paramIndex); IdentifierString countStr(method + paramIndex + 1, getlength(method) - paramIndex - 2); paramCount = countStr.ident().toInt(); } else actionName.copy(method); //if (actionName.compare("dispatch")) { // actionRef = DISPATCH_MESSAGE_ID; //} //else if (actionName.compare("#new")) { // actionRef = NEWOBJECT_MESSAGE_ID; //} ///*else */if (actionName.compare("#init")) { // actionRef = INIT_MESSAGE_ID; //} //else { // if (method.find("set&") != NOTFOUND_POS) { // actionName.cut(0, 4); // flags = PROPSET_MESSAGE; // } // else if (method.startsWith("#cast<") && paramCount > 0) { // flags = SPECIAL_MESSAGE; // } //// else if (actionName.compare("set")) { //// flags = PROPSET_MESSAGE; //// } ref_t signature = 0; size_t index = actionName.ident().find('<'); if (index != NOTFOUND_POS) { ref_t references[ARG_COUNT]; size_t end = actionName.ident().find('>'); size_t len = 0; size_t i = index + 1; while (i < end) { size_t j = actionName.ident().find(i, ',', end); IdentifierString temp(actionName.c_str() + i, j-i); references[len++] = module->mapReference(temp, true); i = j + 1; } signature = module->mapSignature(references, len, true); actionName.truncate(index); } actionRef = module->mapAction(actionName, signature, true); if (actionRef == 0) { printLine("Unknown subject ", actionName); return 0; } //} return encodeMessage(actionRef, paramCount, flags); }