bool Shell::compileAndSendCode(const wstring& source, unsigned nodeId, const string& nodeName) { // compile code std::wistringstream is(source); Error error; BytecodeVector bytecode; unsigned allocatedVariablesCount; Compiler compiler; compiler.setTargetDescription(getDescription(nodeId)); compiler.setCommonDefinitions(&commonDefinitions); bool result = compiler.compile(is, bytecode, allocatedVariablesCount, error); if (result) { // send bytecode sendBytecode(targetStream, nodeId, std::vector<uint16_t>(bytecode.begin(), bytecode.end())); // run node Run msg(nodeId); msg.serialize(targetStream); targetStream->flush(); // retrieve user-defined variables for use in get/set allVariables[nodeName] = *compiler.getVariablesMap(); return true; } else { wcerr << "compilation for node " << UTF8ToWString(nodeName) << " failed: " << error.toWString() << endl; return false; } }
bool HttpDashelTarget::compileAndRunCode(unsigned globalNodeId, const std::string& code, std::string& errorString) { map<unsigned, Node>::iterator query = nodes.find(globalNodeId); if(query == nodes.end()) { if(interface->isVerbose()) { cerr << "Target " << address << " failed to compile and run code for node " << globalNodeId << ": No such node" << endl; } return false; } Node& node = query->second; assert(globalNodeId == node.globalId); // compile code std::wistringstream is(UTF8ToWString(code)); Error error; BytecodeVector bytecode; unsigned allocatedVariablesCount; Compiler compiler; compiler.setTargetDescription(getDescription(node.localId)); compiler.setCommonDefinitions(&interface->getProgram().getCommonDefinitions()); if(compiler.compile(is, bytecode, allocatedVariablesCount, error)) { try { // send bytecode sendBytecode(stream, node.localId, std::vector<uint16>(bytecode.begin(), bytecode.end())); // run node Run msg(node.localId); msg.serialize(stream); stream->flush(); } catch(Dashel::DashelException e) { errorString = e.what(); if(interface->isVerbose()) { cerr << "Target " << address << " failed to send bytecode and run message for node " << node.globalId << " (" << node.name << ") to stream: " << e.what() << endl; } return false; } // retrieve user-defined variables for use in get/set node.variablesMap = *compiler.getVariablesMap(); return true; } else { errorString = WStringToUTF8(error.toWString()); if(interface->isVerbose()) { cerr << "Target " << address << " failed to compile program for node " << globalNodeId << " (" << node.name << "): " << errorString << endl; } return false; } }
bool loadBytecode(const BytecodeVector& bytecode) { size_t i = 0; for (BytecodeVector::const_iterator it(bytecode.begin()); it != bytecode.end(); ++it) { if (i == vm.bytecodeSize) return false; const BytecodeElement& be(*it); vm.bytecode[i++] = be.bytecode; } return true; }
void AsebaNetworkInterface::LoadScripts(const QString& fileName, const QDBusMessage &message) { QFile file(fileName); if (!file.open(QFile::ReadOnly)) { DBusConnectionBus().send(message.createErrorReply(QDBusError::InvalidArgs, QString("file %0 does not exists").arg(fileName))); return; } QDomDocument document("aesl-source"); QString errorMsg; int errorLine; int errorColumn; if (!document.setContent(&file, false, &errorMsg, &errorLine, &errorColumn)) { DBusConnectionBus().send(message.createErrorReply(QDBusError::Other, QString("Error in XML source file: %0 at line %1, column %2").arg(errorMsg).arg(errorLine).arg(errorColumn))); return; } commonDefinitions.events.clear(); commonDefinitions.constants.clear(); userDefinedVariablesMap.clear(); int noNodeCount = 0; QDomNode domNode = document.documentElement().firstChild(); // FIXME: this code depends on event and contants being before any code bool wasError = false; while (!domNode.isNull()) { if (domNode.isElement()) { QDomElement element = domNode.toElement(); if (element.tagName() == "node") { bool ok; const unsigned nodeId(getNodeId(element.attribute("name").toStdWString(), element.attribute("nodeId", 0).toUInt(), &ok)); if (ok) { std::wistringstream is(element.firstChild().toText().data().toStdWString()); Error error; BytecodeVector bytecode; unsigned allocatedVariablesCount; Compiler compiler; compiler.setTargetDescription(getDescription(nodeId)); compiler.setCommonDefinitions(&commonDefinitions); bool result = compiler.compile(is, bytecode, allocatedVariablesCount, error); if (result) { typedef std::vector<Message*> MessageVector; MessageVector messages; sendBytecode(messages, nodeId, std::vector<uint16>(bytecode.begin(), bytecode.end())); for (MessageVector::const_iterator it = messages.begin(); it != messages.end(); ++it) { hub->sendMessage(*it); delete *it; } Run msg(nodeId); hub->sendMessage(msg); } else { DBusConnectionBus().send(message.createErrorReply(QDBusError::Failed, QString::fromStdWString(error.toWString()))); wasError = true; break; } // retrieve user-defined variables for use in get/set userDefinedVariablesMap[element.attribute("name")] = *compiler.getVariablesMap(); } else noNodeCount++; } else if (element.tagName() == "event") { const QString eventName(element.attribute("name")); const unsigned eventSize(element.attribute("size").toUInt()); if (eventSize > ASEBA_MAX_EVENT_ARG_SIZE) { DBusConnectionBus().send(message.createErrorReply(QDBusError::Failed, QString("Event %1 has a length %2 larger than maximum %3").arg(eventName).arg(eventSize).arg(ASEBA_MAX_EVENT_ARG_SIZE))); wasError = true; break; } else { commonDefinitions.events.push_back(NamedValue(eventName.toStdWString(), eventSize)); } } else if (element.tagName() == "constant") { commonDefinitions.constants.push_back(NamedValue(element.attribute("name").toStdWString(), element.attribute("value").toInt())); } } domNode = domNode.nextSibling(); } // check if there was an error if (wasError) { std::wcerr << QString("There was an error while loading script %1").arg(fileName).toStdWString() << std::endl; commonDefinitions.events.clear(); commonDefinitions.constants.clear(); userDefinedVariablesMap.clear(); } // check if there was some matching problem if (noNodeCount) { std::wcerr << QString("%0 scripts have no corresponding nodes in the current network and have not been loaded.").arg(noNodeCount).toStdWString() << std::endl; } }