- Timestamp:
- 03/15/13 12:19:59 (12 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/InterpreterV8.cc
r15046 r15073 34 34 v8::Handle<v8::FunctionTemplate> InterpreterV8::fTemplateSky; 35 35 v8::Handle<v8::FunctionTemplate> InterpreterV8::fTemplateEvent; 36 v8::Handle<v8::FunctionTemplate> InterpreterV8::fTemplateDescription; 36 37 //v8::Handle<v8::FunctionTemplate> InterpreterV8::fTemplateDatabase; 37 38 … … 129 130 } 130 131 132 Handle<Value> InterpreterV8::FuncTimeout(const Arguments &args) 133 { 134 if (args.Length()<2) 135 return ThrowException(String::New("Number of arguments must be at least two.")); 136 137 if (!args[0]->IsNull() && !args[0]->IsInt32()) 138 return ThrowException(String::New("Argument 0 not null and not an int32.")); 139 140 if (!args[1]->IsFunction()) 141 return ThrowException(String::New("Argument 1 not a function.")); 142 143 const int32_t timeout = args[0]->IsNull() ? 0 : args[0]->Int32Value(); 144 const bool null = args[0]->IsNull(); 145 146 HandleScope handle_scope; 147 148 TryCatch exception; 149 150 const Handle<Script> sleep = Script::Compile(String::New("v8.sleep();"), String::New("internal")); 151 if (sleep.IsEmpty()) 152 return Undefined(); 153 154 Handle<Function> func = Handle<Function>::Cast(args[1]); 155 156 Handle<Value> argv[args.Length()-2]; 157 for (int i=0; i<args.Length()-2; i++) 158 argv[i] = args[i+2]; 159 160 Time t; 161 while (!exception.HasCaught()) 162 { 163 const Handle<Value> rc = func->Call(func, args.Length()-2, argv); 164 if (!rc->IsUndefined()) 165 return rc; 166 167 if (!null && Time()-t>=boost::posix_time::milliseconds(abs(timeout))) 168 break; 169 170 // We cannot sleep directly because we have to give control back to 171 // JavaScript ever now and then. This also allows us to catch 172 // exceptions, either from the preemption or ConvertEvent 173 sleep->Run(); 174 } 175 176 if (exception.HasCaught()) 177 return exception.ReThrow(); 178 179 if (timeout<0) 180 return Undefined(); 181 182 const string str = "Waiting for func to return a defined value timed out."; 183 return ThrowException(String::New(str.c_str())); 184 } 185 131 186 void InterpreterV8::Thread(int &id, Persistent<Function> func, uint32_t ms) 132 187 { … … 139 194 } 140 195 141 id = V8::GetCurrentThreadId(); 142 fThreadIds.insert(id); 196 // Warning: As soon as id is set, the parent of this thread might terminate 197 // and hance the reference to id does not exist anymore. So, id 198 // is just a kind of return value and must not be used at all 199 // otherwise. 200 201 const int id_local = V8::GetCurrentThreadId(); 202 id = id_local; 203 fThreadIds.insert(id_local); 143 204 144 205 const HandleScope handle_scope; … … 153 214 154 215 func.Dispose(); 155 fThreadIds.erase(id );216 fThreadIds.erase(id_local); 156 217 157 218 if (!HandleException(exception, "thread")) … … 485 546 break; 486 547 548 if (is==services.end()) 549 return Undefined(); 550 487 551 HandleScope handle_scope; 488 552 489 Handle< Array> arr = Array::New();553 Handle<Object> arr = fTemplateDescription->GetFunction()->NewInstance();//Object::New(); 490 554 if (arr.IsEmpty()) 491 555 return Undefined(); … … 511 575 return Undefined(); 512 576 513 obj->Set(String::New("name"), String::New(it->name.c_str()), ReadOnly); 577 if (!it->name.empty()) 578 obj->Set(String::New("name"), String::New(it->name.c_str()), ReadOnly); 514 579 if (!it->comment.empty()) 515 580 obj->Set(String::New("description"), String::New(it->comment.c_str()), ReadOnly); … … 628 693 return ThrowException(String::New("File name missing")); 629 694 630 if (!ExecuteFile(*file)) 695 TryCatch exception; 696 const bool rc = ExecuteFile(*file); 697 if (exception.HasCaught()) 698 HandleException(exception, "include"); 699 if (!rc) 631 700 { 632 701 V8::TerminateExecution(fThreadId); … … 1145 1214 return Undefined(); 1146 1215 1147 //const Handle<String> data = String::New("data");1216 const Handle<String> data = String::New("data"); 1148 1217 const Handle<String> object = String::New("obj"); 1149 1218 … … 1168 1237 { 1169 1238 if (!named) 1170 return handle_scope.Close(val);1171 1172 const Handle<Object> event = val->ToObject();1173 const Handle<Value> obj = event->Get(object);1174 1175 if (!obj.IsEmpty() && obj->IsObject())1176 1239 { 1177 // Has names and data was received? 1178 if (obj->ToObject()->GetOwnPropertyNames()->Length()>0) 1240 const Handle<Object> event = val->ToObject(); 1241 const Handle<Value> obj = event->Get(data); 1242 1243 // No names (no 'obj'), but 'data' 1244 if (!obj.IsEmpty() && !obj->IsUndefined()) 1179 1245 return handle_scope.Close(val); 1246 } 1247 else 1248 { 1249 const Handle<Object> event = val->ToObject(); 1250 const Handle<Value> obj = event->Get(object); 1251 1252 if (!obj.IsEmpty() && obj->IsObject()) 1253 { 1254 // Has names and data was received? 1255 if (obj->ToObject()->GetOwnPropertyNames()->Length()>0) 1256 return handle_scope.Close(val); 1257 } 1180 1258 } 1181 1259 } … … 1873 1951 1874 1952 // maybe skip: " at internal:" 1953 // maybe skip: " at unknown source:" 1875 1954 1876 1955 auto it = tokenizer.begin(); … … 1915 1994 1916 1995 const Handle<Value> result = script->Run(); 1917 1918 1996 if (exception.HasCaught()) 1919 1997 { … … 1957 2035 bool InterpreterV8::ExecuteConsole() 1958 2036 { 2037 // Just necessray for the Handle<Script> 2038 const HandleScope handle_scope; 2039 2040 // A void script doing nothing than making sure that some JavaScript is executed 2041 const Handle<Script> catcher = Script::Compile(String::New(";"), String::New("")); 2042 2043 // Unlocking is necessary for the preemption to work 2044 const Unlocker global_unlock; 2045 1959 2046 JsSetState(3); 1960 2047 … … 1965 2052 1966 2053 string command; 1967 1968 2054 while (1) 1969 2055 { … … 1990 2076 } 1991 2077 2078 // Locking is necessary to be able to execute java script code 2079 const Locker lock; 2080 2081 // Dump all pending exceptions. This is mainly to catch the 'null' exception 2082 // thrown if a running JavaScript should be terminated from somewhere. 2083 while (1) 2084 { 2085 TryCatch exception; 2086 catcher->Run(); 2087 if (!exception.HasCaught()) 2088 break; 2089 } 2090 1992 2091 // Catch exceptions during code compilation 1993 2092 TryCatch exception; 1994 2093 1995 2094 // Execute code which was entered 1996 bool rc = ExecuteCode(command, " ", false).IsEmpty();2095 bool rc = ExecuteCode(command, "console", false).IsEmpty(); 1997 2096 if (exception.HasCaught()) 1998 2097 { … … 2000 2099 rc = true; 2001 2100 } 2101 2102 // Stop all other threads 2103 for (auto it=fThreadIds.begin(); it!=fThreadIds.end(); it++) 2104 V8::TerminateExecution(*it); 2105 2106 // Allow the java scripts (threads) to run and hence to terminate 2107 const Unlocker unlock; 2108 2109 // Wait until all threads are terminated 2110 while (fThreadIds.size()>0) 2111 usleep(1000); 2002 2112 2003 2113 // In case of an exception add an empty line to the output … … 2145 2255 Handle<ObjectTemplate> v8 = ObjectTemplate::New(); 2146 2256 v8->Set(String::New("sleep"), FunctionTemplate::New(WrapSleep), ReadOnly); 2257 v8->Set(String::New("timeout"), FunctionTemplate::New(WrapTimeout), ReadOnly); 2147 2258 v8->Set(String::New("version"), String::New(V8::GetVersion()), ReadOnly); 2148 2259 … … 2184 2295 global->Set(String::New("Event"), evt, ReadOnly); 2185 2296 2297 Handle<FunctionTemplate> desc = FunctionTemplate::New(); 2298 desc->SetClassName(String::New("Description")); 2299 global->Set(String::New("Description"), desc, ReadOnly); 2300 2186 2301 fTemplateEvent = evt; 2302 fTemplateDescription = desc; 2187 2303 2188 2304 #ifdef HAVE_NOVA -
trunk/FACT++/src/InterpreterV8.h
r15046 r15073 50 50 static v8::Handle<v8::FunctionTemplate> fTemplateSky; 51 51 static v8::Handle<v8::FunctionTemplate> fTemplateEvent; 52 static v8::Handle<v8::FunctionTemplate> fTemplateDescription; 52 53 53 54 #ifdef HAVE_SQL … … 67 68 v8::Handle<v8::Value> FuncSend(const v8::Arguments& args); 68 69 v8::Handle<v8::Value> FuncSleep(const v8::Arguments& args); 70 v8::Handle<v8::Value> FuncTimeout(const v8::Arguments& args); 69 71 v8::Handle<v8::Value> FuncThread(const v8::Arguments& args); 70 72 v8::Handle<v8::Value> FuncKill(const v8::Arguments& args); … … 124 126 static v8::Handle<v8::Value> WrapSend(const v8::Arguments &args) { if (This) return This->FuncSend(args); else return v8::Undefined(); } 125 127 static v8::Handle<v8::Value> WrapSleep(const v8::Arguments &args) { if (This) return This->FuncSleep(args); else return v8::Undefined(); } 128 static v8::Handle<v8::Value> WrapTimeout(const v8::Arguments &args) { if (This) return This->FuncTimeout(args); else return v8::Undefined(); } 126 129 static v8::Handle<v8::Value> WrapThread(const v8::Arguments &args) { if (This) return This->FuncThread(args); else return v8::Undefined(); } 127 130 static v8::Handle<v8::Value> WrapKill(const v8::Arguments &args) { if (This) return This->FuncKill(args); else return v8::Undefined(); }
Note:
See TracChangeset
for help on using the changeset viewer.