summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/uscxml/plugins/DataModel.h13
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp110
-rw-r--r--src/uscxml/transform/ChartToC.cpp67
3 files changed, 127 insertions, 63 deletions
diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h
index df0143d..f229a94 100644
--- a/src/uscxml/plugins/DataModel.h
+++ b/src/uscxml/plugins/DataModel.h
@@ -91,6 +91,19 @@ public:
virtual bool isDeclared(const std::string& expr) = 0;
+ /**
+ * test147:
+ * <data id="Var1" expr="0"/>
+ *
+ * test150:
+ * <data id="Var3">
+ * [1,2,3]
+ * </data>
+ *
+ * test277:
+ * <data id="Var1" expr="return"/>
+ *
+ */
virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
const Arabica::DOM::Node<std::string>& node,
const std::string& content) = 0;
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
index fd4da3c..86bafd3 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
@@ -625,11 +625,60 @@ JSValueRef JSCDataModel::evalAsValue(const std::string& expr, bool dontThrow) {
return result;
}
+JSValueRef JSCDataModel::getNodeAsValue(const Node<std::string>& node) {
+ switch (node.getNodeType()) {
+ case Node_base::ELEMENT_NODE: {
+ TO_JSC_DOMVALUE(Element);
+ }
+ case Node_base::TEXT_NODE: {
+ TO_JSC_DOMVALUE(Text);
+ }
+ case Node_base::CDATA_SECTION_NODE: {
+ TO_JSC_DOMVALUE(CDATASection);
+ }
+ case Node_base::DOCUMENT_NODE: {
+ TO_JSC_DOMVALUE(Document);
+ }
+ default: {
+ TO_JSC_DOMVALUE(Node);
+ }
+ }
+}
+
+void JSCDataModel::assign(const std::string& location, const Data& data) {
+
+ // flags on attribute are ignored?
+ if (location.compare("_sessionid") == 0) // test 322
+ ERROR_EXECUTION_THROW("Cannot assign to _sessionId");
+ if (location.compare("_name") == 0)
+ ERROR_EXECUTION_THROW("Cannot assign to _name");
+ if (location.compare("_ioprocessors") == 0) // test 326
+ ERROR_EXECUTION_THROW("Cannot assign to _ioprocessors");
+ if (location.compare("_invokers") == 0)
+ ERROR_EXECUTION_THROW("Cannot assign to _invokers");
+ if (location.compare("_event") == 0)
+ ERROR_EXECUTION_THROW("Cannot assign to _event");
+
+ JSValueRef exception = NULL;
+ if (data.node) {
+ JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(location.c_str()), getNodeAsValue(data.node), 0, &exception);
+ } else {
+ evalAsValue(location + " = " + Data::toJSON(data));
+ }
+
+ /**
+ * test157: We need to evluate, as this will not throw for 'continue' = Var[5] in
+ */
+// JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(location.c_str()), getDataAsValue(data), 0, &exception);
+
+ if (exception)
+ handleException(exception);
+}
+
void JSCDataModel::assign(const Element<std::string>& assignElem,
const Node<std::string>& node,
const std::string& content) {
std::string key;
- JSValueRef exception = NULL;
if (HAS_ATTR(assignElem, "id")) {
key = ATTR(assignElem, "id");
} else if (HAS_ATTR(assignElem, "location")) {
@@ -638,63 +687,30 @@ void JSCDataModel::assign(const Element<std::string>& assignElem,
if (key.length() == 0) {
ERROR_EXECUTION_THROW("Assign element has neither id nor location");
}
- // flags on attribute are ignored?
- if (key.compare("_sessionid") == 0) // test 322
- ERROR_EXECUTION_THROW("Cannot assign to _sessionId");
- if (key.compare("_name") == 0)
- ERROR_EXECUTION_THROW("Cannot assign to _name");
- if (key.compare("_ioprocessors") == 0) // test 326
- ERROR_EXECUTION_THROW("Cannot assign to _ioprocessors");
- if (key.compare("_invokers") == 0)
- ERROR_EXECUTION_THROW("Cannot assign to _invokers");
- if (key.compare("_event") == 0)
- ERROR_EXECUTION_THROW("Cannot assign to _event");
if (HAS_ATTR(assignElem, "expr")) {
- evalAsValue(key + " = " + ATTR(assignElem, "expr"));
+ assign(key, Data(ATTR(assignElem, "expr"), Data::INTERPRETED));
} else if (node) {
- JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(key.c_str()), getNodeAsValue(node), 0, &exception);
- if (exception)
- handleException(exception);
+ Data d;
+ d.node = node;
+ assign(key, d);
} else if (content.size() > 0) {
try {
- evalAsValue(key + " = " + content);
- } catch (...) {
- evalAsValue(key + " = " + "\"" + InterpreterImpl::spaceNormalize(content) + "\"");
+ Data d = Data::fromJSON(content);
+ if (d.empty())
+ throw Event();
+ assign(key, Data(d, Data::INTERPRETED));
+ } catch (Event e) {
+ assign(key, Data("\"" + InterpreterImpl::spaceNormalize(content) + "\"", Data::INTERPRETED));
}
} else {
+ JSValueRef exception = NULL;
JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(key.c_str()), JSValueMakeUndefined(_ctx), 0, &exception);
if (exception)
handleException(exception);
}
}
-JSValueRef JSCDataModel::getNodeAsValue(const Node<std::string>& node) {
- switch (node.getNodeType()) {
- case Node_base::ELEMENT_NODE: {
- TO_JSC_DOMVALUE(Element);
- }
- case Node_base::TEXT_NODE: {
- TO_JSC_DOMVALUE(Text);
- }
- case Node_base::CDATA_SECTION_NODE: {
- TO_JSC_DOMVALUE(CDATASection);
- }
- case Node_base::DOCUMENT_NODE: {
- TO_JSC_DOMVALUE(Document);
- }
- default: {
- TO_JSC_DOMVALUE(Node);
- }
- }
-}
-
-void JSCDataModel::assign(const std::string& location, const Data& data) {
- std::stringstream ssJSON;
- ssJSON << data;
- evalAsValue(location + " = " + ssJSON.str());
-}
-
void JSCDataModel::init(const Element<std::string>& dataElem,
const Node<std::string>& node,
const std::string& content) {
@@ -708,7 +724,9 @@ void JSCDataModel::init(const Element<std::string>& dataElem,
} else if (HAS_ATTR(dataElem, "location")) {
key = ATTR(dataElem, "location");
}
- evalAsValue(key + " = undefined", true);
+ if (key.size() > 0) {
+ evalAsValue(key + " = undefined", true);
+ }
throw e;
}
}
diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp
index c6be393..7cc50fc 100644
--- a/src/uscxml/transform/ChartToC.cpp
+++ b/src/uscxml/transform/ChartToC.cpp
@@ -690,13 +690,15 @@ void ChartToC::writeTypes(std::ostream& stream) {
stream << "typedef struct uscxml_elem_send uscxml_elem_send;" << std::endl;
stream << "typedef struct uscxml_elem_param uscxml_elem_param;" << std::endl;
stream << "typedef struct uscxml_elem_data uscxml_elem_data;" << std::endl;
+ stream << "typedef struct uscxml_elem_assign uscxml_elem_assign;" << std::endl;
stream << "typedef struct uscxml_elem_donedata uscxml_elem_donedata;" << std::endl;
stream << "typedef struct uscxml_elem_foreach uscxml_elem_foreach;" << std::endl;
stream << std::endl;
stream << "typedef void* (*dequeue_internal_t)(const uscxml_ctx* ctx);" << std::endl;
stream << "typedef void* (*dequeue_external_t)(const uscxml_ctx* ctx);" << std::endl;
- stream << "typedef int (*is_enabled_t)(const uscxml_ctx* ctx, const uscxml_transition* transition, const void* event);" << std::endl;
+ stream << "typedef int (*is_enabled_t)(const uscxml_ctx* ctx, const uscxml_transition* transition);" << std::endl;
+ stream << "typedef int (*is_matched_t)(const uscxml_ctx* ctx, const uscxml_transition* transition, const void* event);" << std::endl;
stream << "typedef int (*is_true_t)(const uscxml_ctx* ctx, const char* expr);" << std::endl;
stream << "typedef int (*exec_content_t)(const uscxml_ctx* ctx, const uscxml_state* state, const void* event);" << std::endl;
stream << "typedef int (*raise_done_event_t)(const uscxml_ctx* ctx, const uscxml_state* state, const uscxml_elem_donedata* donedata);" << std::endl;
@@ -709,7 +711,7 @@ void ChartToC::writeTypes(std::ostream& stream) {
stream << "typedef int (*exec_content_foreach_init_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach);" << std::endl;
stream << "typedef int (*exec_content_foreach_next_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach);" << std::endl;
stream << "typedef int (*exec_content_foreach_done_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach);" << std::endl;
- stream << "typedef int (*exec_content_assign_t)(const uscxml_ctx* ctx, const char* location, const char* expr);" << std::endl;
+ stream << "typedef int (*exec_content_assign_t)(const uscxml_ctx* ctx, const uscxml_elem_assign* assign);" << std::endl;
stream << "typedef int (*exec_content_init_t)(const uscxml_ctx* ctx, const uscxml_elem_data* data);" << std::endl;
stream << "typedef int (*exec_content_cancel_t)(const uscxml_ctx* ctx, const char* sendid, const char* sendidexpr);" << std::endl;
stream << "typedef int (*exec_content_finalize_t)(const uscxml_ctx* ctx, const uscxml_elem_invoke* invoker, const void* event);" << std::endl;
@@ -748,6 +750,16 @@ void ChartToC::writeTypes(std::ostream& stream) {
stream << std::endl;
stream << "/**" << std::endl;
+ stream << " * All information pertaining to an <assign> element." << std::endl;
+ stream << " */" << std::endl;
+ stream << "struct uscxml_elem_assign {" << std::endl;
+ stream << " const char* location;" << std::endl;
+ stream << " const char* expr;" << std::endl;
+ stream << " const char* content;" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+
+ stream << "/**" << std::endl;
stream << " * All information pertaining to any state element." << std::endl;
stream << " */" << std::endl;
stream << "struct uscxml_state {" << std::endl;
@@ -872,6 +884,7 @@ void ChartToC::writeTypes(std::ostream& stream) {
stream << " dequeue_internal_t dequeue_internal;" << std::endl;
stream << " dequeue_external_t dequeue_external;" << std::endl;
stream << " is_enabled_t is_enabled;" << std::endl;
+ stream << " is_matched_t is_matched;" << std::endl;
stream << " is_true_t is_true;" << std::endl;
stream << " raise_done_event_t raise_done_event;" << std::endl;
stream << std::endl;
@@ -1264,20 +1277,7 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Node<s
stream << padding;
stream << "if likely(ctx->exec_content_assign != NULL) {" << std::endl;
stream << padding;
- stream << " if ((ctx->exec_content_assign(ctx, ";
- stream << (HAS_ATTR(elem, "location") ? "\"" + escape(ATTR(elem, "location")) + "\"" : "NULL") << ", ";
- if (HAS_ATTR(elem, "expr")) {
- stream << "\"" + escape(ATTR(elem, "expr")) + "\"";
- } else {
- NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, elem);
- if (assignTexts.size() > 0) {
- stream << "\"";
- writeExecContent(stream, assignTexts[0], 0);
- stream << "\"";
- } else {
- stream << "NULL";
- }
- }
+ stream << " if ((ctx->exec_content_assign(ctx, &" << _prefix << "_elem_assigns[" << ATTR(elem, "documentOrder") << "]";
stream << ")) != USCXML_ERR_OK) return err;" << std::endl;
stream << padding << "} else {" << std::endl;
stream << padding << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl;
@@ -1485,6 +1485,38 @@ void ChartToC::writeElementInfo(std::ostream& stream) {
stream << std::endl;
}
+ NodeSet<std::string> assigns = DOMUtils::inDocumentOrder(_nsInfo.xmlNSPrefix + "assign", _scxml);
+ if (assigns.size() > 0) {
+ _hasElement.insert("assign");
+ stream << "static const uscxml_elem_assign " << _prefix << "_elem_assigns[" << assigns.size() << "] = {" << std::endl;
+ stream << " /* location, expr, content */" << std::endl;
+
+ for (size_t i = 0; i < assigns.size(); i++) {
+ Element<std::string> assign(assigns[i]);
+
+ stream << " { ";
+ stream << (HAS_ATTR(assign, "location") ? "\"" + escape(ATTR(assign, "location")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(assign, "expr") ? "\"" + escape(ATTR(assign, "expr")) + "\"" : "NULL") << ", ";
+
+ NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, assign);
+ if (assignTexts.size() > 0) {
+ if (boost::trim_copy(assignTexts[0].getNodeValue()).length() > 0) {
+ std::string escaped = escape(assignTexts[0].getNodeValue());
+ stream << "\"" << escaped << "\"";
+ }
+ } else {
+ stream << "NULL";
+ }
+ stream << " }," << std::endl;
+
+ assign.setAttribute("documentOrder", toStr(i));
+ }
+
+ stream << "};" << std::endl;
+ stream << std::endl;
+
+ }
+
NodeSet<std::string> datas = DOMUtils::inDocumentOrder(_nsInfo.xmlNSPrefix + "data", _scxml);
if (datas.size() > 0) {
_hasElement.insert("data");
@@ -2169,7 +2201,8 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " if ((USCXML_GET_TRANS(i).event == NULL && ctx->event == NULL) || " << std::endl;
stream << " (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) {" << std::endl;
stream << " /* is it enabled? */" << std::endl;
- stream << " if (ctx->is_enabled(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) {" << std::endl;
+ stream << " if ((ctx->event == NULL || ctx->is_matched(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) &&" << std::endl;
+ stream << " (USCXML_GET_TRANS(i).condition == NULL || ctx->is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) {" << std::endl;
stream << " /* remember that we found a transition */" << std::endl;
stream << " ctx->flags |= USCXML_CTX_TRANSITION_FOUND;" << std::endl;
stream << std::endl;