Changeset 14637
- Timestamp:
- 11/17/12 14:36:27 (12 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/InterpreterV8.cc
r14634 r14637 84 84 // ========================================================================== 85 85 86 void InterpreterV8::Terminate()87 {88 if (!Locker::IsLocked())89 JsException("***** InterprterV8::Terminate call not locked *****");90 91 for (auto it=fThreadIds.begin(); it!=fThreadIds.end(); it++)92 V8::TerminateExecution(*it);93 fThreadIds.clear();94 95 if (fThreadId>=0)96 {97 V8::TerminateExecution(fThreadId);98 fThreadId = -1;99 }100 }101 102 86 Handle<Value> InterpreterV8::FuncExit(const Arguments &) 103 87 { 104 Terminate();105 return ThrowException(String::New("exit"));88 V8::TerminateExecution(fThreadId); 89 return Undefined(); 106 90 } 107 91 … … 135 119 } 136 120 137 void InterpreterV8::ThreadTimeout( Persistent<Function> func, uint32_t ms)121 void InterpreterV8::ThreadTimeout(int &id, Persistent<Function> func, uint32_t ms) 138 122 { 139 123 const Locker lock; 140 124 141 125 if (fThreadId<0) 126 { 127 id = -1; 142 128 return; 143 144 const int id = V8::GetCurrentThreadId(); 129 } 130 131 id = V8::GetCurrentThreadId(); 145 132 fThreadIds.insert(id); 146 133 … … 161 148 fThreadIds.erase(id); 162 149 163 if (!exception.HasCaught()) 164 return; 165 166 ReportException(&exception); 167 Terminate(); 150 if (!HandleException(exception, "dim.timeout")) 151 V8::TerminateExecution(fThreadId); 168 152 } 169 153 … … 190 174 const uint32_t ms = args[0]->Uint32Value(); 191 175 192 fTimeout.push_back(thread(bind(&InterpreterV8::ThreadTimeout, this, func, ms))); 193 return Undefined(); 176 int id=-2; 177 fTimeout.push_back(thread(bind(&InterpreterV8::ThreadTimeout, this, ref(id), func, ms))); 178 { 179 const Unlocker unlock; 180 while (id==-2) 181 usleep(1); 182 } 183 184 return Integer::New(id); 185 } 186 187 Handle<Value> InterpreterV8::FuncKill(const Arguments& args) 188 { 189 for (int i=0; i<args.Length(); i++) 190 if (!args[i]->IsInt32()) 191 return ThrowException(String::New("All arguments must be int32.")); 192 193 uint32_t cnt = 0; 194 195 for (int i=0; i<args.Length(); i++) 196 { 197 V8::TerminateExecution(args[i]->Int32Value()); 198 cnt += fThreadIds.erase(args[i]->Int32Value()); 199 } 200 201 return Integer::New(cnt); 194 202 } 195 203 … … 995 1003 const HandleScope handle_scope; 996 1004 997 Persistent<Object> obj = it->second;1005 Handle<Object> obj = it->second; 998 1006 999 1007 obj->CreationContext()->Enter(); … … 1024 1032 fThreadIds.erase(id); 1025 1033 1026 if (exception.HasCaught()) 1027 ReportException(&exception); 1034 if (!HandleException(exception, "Service.onchange")) 1035 V8::TerminateExecution(fThreadId); 1036 //Terminate(); 1028 1037 1029 1038 if (ret->IsNativeError()) 1039 { 1030 1040 JsException(service+".onchange callback - "+*String::Utf8Value(ret)); 1031 1032 if (ret->IsUndefined() || ret->IsNativeError() || exception.HasCaught()) 1033 Terminate(); 1041 V8::TerminateExecution(fThreadId); 1042 //Terminate(); 1043 } 1044 1045 //if (ret->IsUndefined() || ret->IsNativeError()/* || exception.HasCaught()*/) 1034 1046 } 1035 1047 … … 1097 1109 fThreadIds.erase(id); 1098 1110 1099 if (!exception.HasCaught()) 1100 return; 1101 1102 ReportException(&exception); 1103 Terminate(); 1111 if (!HandleException(exception, "dim.onchange")) 1112 V8::TerminateExecution(fThreadId); 1113 //Terminate(); 1104 1114 } 1105 1115 … … 1440 1450 // ========================================================================== 1441 1451 1442 bool InterpreterV8:: ReportException(TryCatch* try_catch)1443 { 1444 if (!try_catch ->CanContinue())1445 return false;1452 bool InterpreterV8::HandleException(TryCatch& try_catch, const char *where) 1453 { 1454 if (!try_catch.HasCaught() || !try_catch.CanContinue()) 1455 return true; 1446 1456 1447 1457 const HandleScope handle_scope; 1448 1458 1449 const String::Utf8Value exception(try_catch->Exception()); 1450 1451 if (*exception && string(*exception)=="exit") 1459 Handle<Value> except = try_catch.Exception(); 1460 if (except.IsEmpty() || except->IsNull()) 1452 1461 return true; 1453 if (*exception && string(*exception)=="null") 1454 return false;1455 1456 const Handle<Message> message = try_catch ->Message();1462 1463 const String::Utf8Value exception(except); 1464 1465 const Handle<Message> message = try_catch.Message(); 1457 1466 if (message.IsEmpty()) 1458 1467 return false; … … 1465 1474 const String::Utf8Value filename(message->GetScriptResourceName()); 1466 1475 1467 if (*filename)1468 out << *filename << ": ";1469 out << "l." << message->GetLineNumber();1476 out << *filename; 1477 if (message->GetLineNumber()>0) 1478 out << ": l." << message->GetLineNumber(); 1470 1479 if (*exception) 1471 1480 out << ": "; 1472 1481 } 1473 1482 1474 // -------------- SKIP if 'internal' and 'Error' ---------------1475 1483 if (*exception) 1476 1484 out << *exception; 1485 1486 out << " [" << where << "]"; 1477 1487 1478 1488 JsException(out.str()); … … 1482 1492 if (*sourceline) 1483 1493 JsException(*sourceline); 1484 // -------------- SKIP if 'internal' and 'Error: ' ---------------1485 1494 1486 1495 // Print wavy underline (GetUnderline is deprecated). … … 1495 1504 JsException(out.str()); 1496 1505 1497 const String::Utf8Value stack_trace(try_catch ->StackTrace());1506 const String::Utf8Value stack_trace(try_catch.StackTrace()); 1498 1507 if (stack_trace.length()<=0) 1499 1508 return false; … … 1547 1556 JsSetState(3); 1548 1557 1558 TryCatch exception; 1559 1549 1560 const Handle<Value> result = script->Run(); 1550 if (result.IsEmpty()) 1551 return Handle<Value>(); 1561 1562 if (exception.HasCaught()) 1563 { 1564 if (file=="internal") 1565 return exception.ReThrow(); 1566 1567 HandleException(exception, "code"); 1568 return Undefined(); 1569 } 1552 1570 1553 1571 // If all went well and the result wasn't undefined then print 1554 1572 // the returned value. 1555 if (!result ->IsUndefined())1573 if (!result.IsEmpty() && result->IsUndefined()) 1556 1574 JsResult(*String::Utf8Value(result)); 1557 1575 … … 1596 1614 1597 1615 1598 void InterpreterV8::AddFormatToGlobal() const1616 void InterpreterV8::AddFormatToGlobal()// const 1599 1617 { 1600 1618 const string code = … … 1651 1669 "}"*/; 1652 1670 1671 // ExcuteInternal does not work properly here... 1672 // If suring compilation an exception is thrown, it will not work 1653 1673 Handle<Script> script = Script::New(String::New(code.c_str()), String::New("internal")); 1654 1674 if (!script.IsEmpty()) … … 1683 1703 dim->Set(String::New("sleep"), FunctionTemplate::New(WrapSleep), ReadOnly); 1684 1704 dim->Set(String::New("timeout"), FunctionTemplate::New(WrapTimeout), ReadOnly); 1705 dim->Set(String::New("kill"), FunctionTemplate::New(WrapKill), ReadOnly); 1685 1706 dim->Set(String::New("subscribe"), FunctionTemplate::New(WrapSubscribe), ReadOnly); 1686 1707 dim->Set(String::New("file"), FunctionTemplate::New(WrapFile), ReadOnly); 1708 1709 // timeout -> Thread - class? 1710 // subscribe -> Service - class? 1711 // file -> File - class? 1712 // new class State ? 1713 // newState -> return State? 1714 // setState -> return State? 1715 // getState -> return State? 1687 1716 1688 1717 Handle<ObjectTemplate> onchange = ObjectTemplate::New(); … … 1728 1757 } 1729 1758 1759 // Switch off eval(). It is not possible to track it's exceptions. 1760 context->AllowCodeGenerationFromStrings(false); 1761 1730 1762 Context::Scope scope(context); 1731 1763 … … 1738 1770 //V8::ResumeProfiler(); 1739 1771 1772 bool rc; 1773 1774 TryCatch exception; 1775 1740 1776 AddFormatToGlobal(); 1741 1777 1742 JsStart(filename); 1743 1744 //context->Enter(); 1745 1746 TryCatch exception; 1747 1748 Locker::StartPreemption(10); 1749 bool rc = ExecuteFile(filename, true); 1750 1751 Locker::StopPreemption(); 1752 1753 Terminate(); 1754 1755 if (exception.HasCaught()) 1756 rc = ReportException(&exception); 1778 if (!exception.HasCaught()) 1779 { 1780 JsStart(filename); 1781 1782 Locker::StartPreemption(10); 1783 1784 rc = ExecuteFile(filename, true); 1785 1786 Locker::StopPreemption(); 1787 1788 // Stop all other threads 1789 for (auto it=fThreadIds.begin(); it!=fThreadIds.end(); it++) 1790 V8::TerminateExecution(*it); 1791 fThreadIds.clear(); 1792 } 1793 1794 // Handle an exception 1795 rc = HandleException(exception, "main"); 1757 1796 1758 1797 // IsProfilerPaused() … … 1773 1812 //context->Exit(); 1774 1813 1775 // Thre threads are started already and wait to get the lock 1776 // So we have to unlock (manual preemtion) so they they get 1777 // the signal to terminate. After they are all successfully 1778 // terminated, just to be sure... we lock again 1814 // The threads are started already and wait to get the lock 1815 // So we have to unlock (manual preemtion) so that they get 1816 // the signal to terminate. 1779 1817 { 1780 1818 const Unlocker unlock; … … 1814 1852 { 1815 1853 Locker locker; 1816 This->Terminate(); 1854 V8::TerminateExecution(This->fThreadId); 1855 //This->Terminate(); 1817 1856 } 1818 1857 -
trunk/FACT++/src/InterpreterV8.h
r14636 r14637 50 50 51 51 #ifdef HAVE_V8 52 void Terminate(); 53 54 bool ReportException(v8::TryCatch* try_catch); 52 bool HandleException(v8::TryCatch &try_catch, const char *where); 55 53 bool ExecuteFile(const std::string &name, bool main=false); 56 54 v8::Handle<v8::Value> ExecuteCode(const std::string &code, const std::string &file="internal", bool main=false); 57 55 v8::Handle<v8::Value> ExecuteInternal(const std::string &code); 58 56 59 void ThreadTimeout( v8::Persistent<v8::Function> func, uint32_t ms);57 void ThreadTimeout(int &id, v8::Persistent<v8::Function> func, uint32_t ms); 60 58 61 59 v8::Handle<v8::Value> FuncWait(const v8::Arguments& args); … … 63 61 v8::Handle<v8::Value> FuncSleep(const v8::Arguments& args); 64 62 v8::Handle<v8::Value> FuncTimeout(const v8::Arguments& args); 63 v8::Handle<v8::Value> FuncKill(const v8::Arguments& args); 65 64 v8::Handle<v8::Value> FuncPrint(const v8::Arguments& args); 66 65 v8::Handle<v8::Value> FuncAlarm(const v8::Arguments& args); … … 108 107 static v8::Handle<v8::Value> WrapSleep(const v8::Arguments &args) { if (This) return This->FuncSleep(args); else return v8::Undefined(); } 109 108 static v8::Handle<v8::Value> WrapTimeout(const v8::Arguments &args) { if (This) return This->FuncTimeout(args); else return v8::Undefined(); } 109 static v8::Handle<v8::Value> WrapKill(const v8::Arguments &args) { if (This) return This->FuncKill(args); else return v8::Undefined(); } 110 110 static v8::Handle<v8::Value> WrapExit(const v8::Arguments &args) { if (This) return This->FuncExit(args); else return v8::Undefined(); } 111 111 static v8::Handle<v8::Value> WrapState(const v8::Arguments &args) { if (This) return This->FuncState(args); else return v8::Undefined(); } … … 178 178 void JsHandleState(const std::string &, const State &); 179 179 180 void AddFormatToGlobal() const;180 void AddFormatToGlobal(); 181 181 182 182 bool JsRun(const std::string &, const std::map<std::string,std::string> & = std::map<std::string,std::string>());
Note:
See TracChangeset
for help on using the changeset viewer.