Changeset 14607 for trunk/FACT++
- Timestamp:
- 11/13/12 13:38:22 (12 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/InterpreterV8.cc
r14603 r14607 63 63 // be checked in all placed to avoid that V8 will core dump. 64 64 // 65 // HandleScope: 66 // ------------ 67 // A handle scope is a garbage collector and collects all handles created 68 // until it goes out of scope. Handles which are not needed anymore are 69 // then deleted. To return a handle from a HandleScope you need to use 70 // Close(). E.g., String::Utf8Value does not create a new handle and 71 // hence does not need a HandleScope. Any ::New will need a handle scope. 72 // Forgetting the HandleScope could in principle fill your memory, 73 // but everything is properly deleted by the global HandleScope at 74 // script termination. 75 // 65 76 66 77 // ========================================================================== … … 110 121 // Using a Javascript function has the advantage that it is fully 111 122 // interruptable without the need of C++ code 112 113 123 const string code = 114 124 "(function(){" … … 117 127 "})();"; 118 128 119 HandleScope handle_scope; 120 121 const Handle<Script> script = Script::Compile(String::New(code.c_str()), String::New("internal")); 122 if (script.IsEmpty()) 123 return Undefined(); 124 125 return handle_scope.Close(script->Run()); 129 return ExecuteInternal(code); 126 130 } 127 131 … … 142 146 TryCatch exception; 143 147 144 const Handle<Script> sleep = Script::Compile(String::New(("dim.sleep("+to_string(ms)+");").c_str()), String::New("internal"));145 if ( ms==0 || (!sleep.IsEmpty() && !sleep->Run().IsEmpty()))148 const bool rc = ms==0 || !ExecuteInternal("dim.sleep("+to_string(ms)+");").IsEmpty(); 149 if (rc) 146 150 { 147 151 Handle<Value> args[] = { }; … … 173 177 return ThrowException(String::New("Argument 0 not an uint32.")); 174 178 179 const HandleScope handle_scope; 180 175 181 Handle<Function> handle = Handle<Function>::Cast(args[1]); 176 182 … … 190 196 if (!args[0]->IsString()) 191 197 return ThrowException(String::New("Argument 1 must be a string.")); 192 193 HandleScope handle_scope;194 198 195 199 const String::Utf8Value str(args[0]); … … 207 211 } 208 212 209 return handle_scope.Close(Boolean::New(JsSend(command)));213 return Boolean::New(JsSend(command)); 210 214 } 211 215 … … 263 267 code += ");"; 264 268 265 HandleScope handle_scope; 266 267 // It is not strictly necessary to catch the exception, instead 268 // script->Run() could just be returned, but catching the 269 // exception allow to print the position in the file in 270 // the exception handler instead of just the posiiton in the script. 271 TryCatch exception; 272 273 const Handle<Script> script = Script::Compile(String::New(code.c_str()), String::New("internal")); 274 if (script.IsEmpty()) 275 return Undefined(); 276 277 const Handle<Value> result = script->Run(); 278 279 return exception.HasCaught() ? exception.ReThrow() : handle_scope.Close(result); 280 281 /* 282 const string server = *String::Utf8Value(args[0]); 283 const int32_t state = args[1]->Int32Value(); 284 const uint32_t millisec = args.Length()==3 ? args[2]->Int32Value() : 0; 285 286 const int rc = JsWait(server, state, millisec); 287 288 if (rc==0 || rc==1) 289 return Boolean::New(rc); 290 291 return ThrowException(String::New(("Waitig for state "+to_string(state)+" of server '"+server+"' failed.").c_str())); 292 */ 269 return ExecuteInternal(code); 293 270 } 294 271 … … 337 314 return ThrowException(String::New("Argument 3 must be a string.")); 338 315 339 HandleScope handle_scope;340 341 316 const uint32_t index = args[0]->Int32Value(); 342 317 const string name = *String::Utf8Value(args[1]); … … 360 335 } 361 336 362 return handle_scope.Close(Boolean::New(JsNewState(index, name, comment)));337 return Boolean::New(JsNewState(index, name, comment)); 363 338 } 364 339 … … 370 345 if (!args[0]->IsUint32() && !args[0]->IsString()) 371 346 return ThrowException(String::New("Argument must be an unint32 or a string.")); 372 373 HandleScope handle_scope;374 347 375 348 int index = -2; … … 389 362 return ThrowException(String::New("State must be in the range [10, 255].")); 390 363 391 return handle_scope.Close(Boolean::New(JsSetState(index)));364 return Boolean::New(JsSetState(index)); 392 365 } 393 366 … … 404 377 for (int i=0; i<args.Length(); i++) 405 378 { 406 const HandleScope handle_scope;407 408 379 const String::Utf8Value str(args[i]); 409 380 if (*str) … … 417 388 for (int i=0; i<args.Length(); i++) 418 389 { 419 const HandleScope handle_scope;420 421 390 const String::Utf8Value str(args[i]); 422 391 if (*str) … … 434 403 for (int i=0; i<args.Length(); i++) 435 404 { 436 const HandleScope handle_scope;437 438 405 const String::Utf8Value str(args[i]); 439 406 if (*str) … … 450 417 for (int i=0; i<args.Length(); i++) 451 418 { 452 const HandleScope handle_scope;453 454 419 const String::Utf8Value file(args[i]); 455 420 if (*file == NULL) 456 return ThrowException(String::New( ("Error loading file '"+string(*file)+"'").c_str()));421 return ThrowException(String::New("File name missing")); 457 422 458 423 if (!ExecuteFile(*file)) 459 return ThrowException(String::New(("Execution of '"+string(*file)+"' failed").c_str()));460 } 461 return Undefined();424 return Boolean::New(false); 425 } 426 return Boolean::New(true); 462 427 } 463 428 … … 473 438 Handle<Value> InterpreterV8::FuncDbClose(const Arguments &args) 474 439 { 475 HandleScope handle_scope;476 477 440 void *ptr = External::Unwrap(args.This()->GetInternalField(0)); 478 441 if (!ptr) 479 return handle_scope.Close(Boolean::New(false));442 return Boolean::New(false); 480 443 481 444 #ifdef HAVE_SQL … … 486 449 #endif 487 450 451 HandleScope handle_scope; 452 488 453 args.This()->SetInternalField(0, External::New(0)); 489 454 … … 494 459 if (args.Length()==0) 495 460 return ThrowException(String::New("Arguments expected.")); 496 497 HandleScope handle_scope;498 461 499 462 void *ptr = External::Unwrap(args.This()->GetInternalField(0)); … … 509 472 try 510 473 { 474 HandleScope handle_scope; 475 511 476 Database *db = reinterpret_cast<Database*>(ptr); 512 477 … … 651 616 return ThrowException(String::New("Argument 1 not a string.")); 652 617 653 HandleScope handle_scope;654 655 618 #ifdef HAVE_SQL 656 619 try 657 620 { 621 HandleScope handle_scope; 622 658 623 Database *db = new Database(*String::Utf8Value(args[0])); 659 624 fDatabases.push_back(db); … … 989 954 Handle<Value> InterpreterV8::OnChangeSet(Local<String> prop, Local< Value > value, const AccessorInfo &) 990 955 { 991 const HandleScope handle_scope;992 993 956 // Returns the value if the setter intercepts the request. Otherwise, returns an empty handle. 994 957 const string server = *String::Utf8Value(prop); … … 1023 986 } 1024 987 1025 const HandleScope handle_scope;1026 1027 988 if (it->second.IsEmpty() || !it->second->IsFunction()) 1028 989 return; 990 991 const HandleScope handle_scope; 1029 992 1030 993 fGlobalContext->Enter(); … … 1079 1042 // return ThrowException(String::New("Must be used as constructor.")); 1080 1043 1081 HandleScope handle_scope;1082 1083 1044 const String::Utf8Value str(args[0]); 1084 1045 1085 1046 const auto it = fReverseMap.find(*str); 1086 1047 if (it!=fReverseMap.end()) 1087 return handle_scope.Close(it->second);1048 return it->second; 1088 1049 1089 1050 void *ptr = JsSubscribe(*str); 1090 1051 if (ptr==0) 1091 1052 return ThrowException(String::New(("Subscription to '"+string(*str)+"' already exists.").c_str())); 1053 1054 HandleScope handle_scope; 1092 1055 1093 1056 Handle<ObjectTemplate> tem = ObjectTemplate::New(); … … 1153 1116 Handle<ObjectTemplate> loc = ObjectTemplate::New(); 1154 1117 1155 loc->Set(String::New("zd"), Number::New(zd), ReadOnly);1156 loc->Set(String::New("az"), Number::New(az), ReadOnly);1118 loc->Set(String::New("zd"), Number::New(zd), ReadOnly); 1119 loc->Set(String::New("az"), Number::New(az), ReadOnly); 1157 1120 loc->Set(String::New("toSky"), FunctionTemplate::New(LocalToSky), ReadOnly); 1158 1121 loc->Set(String::New("toString"), FunctionTemplate::New(LocalToString), ReadOnly); … … 1167 1130 Handle<ObjectTemplate> sky = ObjectTemplate::New(); 1168 1131 1169 sky->Set(String::New("ra"), Number::New(ra), ReadOnly);1170 sky->Set(String::New("dec"), Number::New(dec), ReadOnly);1132 sky->Set(String::New("ra"), Number::New(ra), ReadOnly); 1133 sky->Set(String::New("dec"), Number::New(dec), ReadOnly); 1171 1134 sky->Set(String::New("toLocal"), FunctionTemplate::New(ismoon?MoonToLocal :SkyToLocal), ReadOnly); 1172 1135 sky->Set(String::New("toString"), FunctionTemplate::New(ismoon?MoonToString:SkyToString), ReadOnly); … … 1179 1142 Handle<Value> InterpreterV8::LocalDist(const Arguments &args) 1180 1143 { 1181 HandleScope handle_scope;1182 1183 1144 if (args.Length()!=2) 1184 1145 return ThrowException(String::New("dist must not be called with two arguments.")); … … 1186 1147 if (!args[0]->IsObject() || !args[1]->IsObject()) 1187 1148 return ThrowException(String::New("at least one argument not an object.")); 1149 1150 HandleScope handle_scope; 1188 1151 1189 1152 Handle<Object> obj[2] = … … 1228 1191 Handle<Value> InterpreterV8::MoonDisk(const Arguments &args) 1229 1192 { 1230 HandleScope handle_scope;1231 1232 1193 if (args.Length()>1) 1233 1194 return ThrowException(String::New("disk must not be called with more than one argument.")); … … 1236 1197 const Time utc = args.Length()==0 ? Time() : Time(v/1000, v%1000); 1237 1198 1238 return handle_scope.Close(Number::New(ln_get_lunar_disk(utc.JD())));1199 return Number::New(ln_get_lunar_disk(utc.JD())); 1239 1200 } 1240 1201 1241 1202 Handle<Value> InterpreterV8::LocalToSky(const Arguments &args) 1242 1203 { 1243 HandleScope handle_scope;1244 1245 1204 if (args.Length()>1) 1246 1205 return ThrowException(String::New("toSky must not be called with more than one argument.")); … … 1252 1211 if (!finite(hrz.alt) || !finite(hrz.az)) 1253 1212 return ThrowException(String::New("zd and az must be finite.")); 1213 1214 HandleScope handle_scope; 1254 1215 1255 1216 const Local<Value> date = … … 1273 1234 Handle<Value> InterpreterV8::SkyToLocal(const Arguments &args) 1274 1235 { 1275 HandleScope handle_scope;1276 1277 1236 if (args.Length()>1) 1278 1237 return ThrowException(String::New("toLocal must not be called with more than one argument.")); … … 1284 1243 if (!finite(equ.ra) || !finite(equ.dec)) 1285 1244 return ThrowException(String::New("Ra and dec must be finite.")); 1245 1246 HandleScope handle_scope; 1286 1247 1287 1248 const Local<Value> date = … … 1305 1266 Handle<Value> InterpreterV8::MoonToLocal(const Arguments &args) 1306 1267 { 1307 HandleScope handle_scope;1308 1309 1268 if (args.Length()>0) 1310 1269 return ThrowException(String::New("toLocal must not be called with arguments.")); … … 1316 1275 if (!finite(equ.ra) || !finite(equ.dec)) 1317 1276 return ThrowException(String::New("ra and dec must be finite.")); 1277 1278 HandleScope handle_scope; 1318 1279 1319 1280 const Local<Value> date = … … 1337 1298 Handle<Value> InterpreterV8::ConstructorMoon(const Arguments &args) 1338 1299 { 1339 HandleScope handle_scope;1340 1341 1300 if (args.Length()>1) 1342 1301 return ThrowException(String::New("Moon constructor must not be called with more than one argument.")); 1302 1303 HandleScope handle_scope; 1343 1304 1344 1305 const Local<Value> date = … … 1358 1319 Handle<Value> InterpreterV8::ConstructorSky(const Arguments &args) 1359 1320 { 1360 HandleScope handle_scope;1361 1362 1321 if (args.Length()!=2) 1363 1322 return ThrowException(String::New("Sky constructor takes two arguments.")); … … 1369 1328 return ThrowException(String::New("Both arguments to Sky must be valid numbers.")); 1370 1329 1371 return handle_scope.Close(ConstructSky(ra, dec));1330 return ConstructSky(ra, dec); 1372 1331 } 1373 1332 1374 1333 Handle<Value> InterpreterV8::ConstructorLocal(const Arguments &args) 1375 1334 { 1376 HandleScope handle_scope;1377 1378 1335 if (args.Length()!=2) 1379 1336 return ThrowException(String::New("Local constructor takes two arguments.")); … … 1385 1342 return ThrowException(String::New("Both arguments to Local must be valid numbers.")); 1386 1343 1387 return handle_scope.Close(ConstructLocal(zd, az));1344 return ConstructLocal(zd, az); 1388 1345 } 1389 1346 #endif … … 1425 1382 } 1426 1383 1384 // -------------- SKIP if 'internal' and 'Error' --------------- 1427 1385 if (*exception) 1428 1386 out << *exception; … … 1434 1392 if (*sourceline) 1435 1393 JsException(*sourceline); 1394 // -------------- SKIP if 'internal' and 'Error: ' --------------- 1436 1395 1437 1396 // Print wavy underline (GetUnderline is deprecated). … … 1458 1417 const boost::tokenizer<separator> tokenizer(trace, separator("\n")); 1459 1418 1419 // maybe skip: " at internal:" 1420 1460 1421 auto it = tokenizer.begin(); 1461 1422 JsException(""); … … 1466 1427 } 1467 1428 1468 // Executes a string within the current v8 context. 1469 bool InterpreterV8::ExecuteStringNT(const Handle<String> &code, const Handle<Value> &file) 1470 { 1471 if (code.IsEmpty()) 1472 return true; 1473 1474 const HandleScope handle_scope; 1475 1476 const Handle<Script> script = Script::Compile(code, file); 1429 Handle<Value> InterpreterV8::ExecuteInternal(const string &code) 1430 { 1431 TryCatch exception; 1432 const Handle<Value> result = ExecuteCode(code); 1433 return exception.HasCaught() ? exception.ReThrow() : result; 1434 } 1435 1436 Handle<Value> InterpreterV8::ExecuteCode(const string &code, const string &file, bool main) 1437 { 1438 HandleScope handle_scope; 1439 1440 const Handle<String> source = String::New(code.c_str(), code.size()); 1441 const Handle<String> origin = String::New(file.c_str()); 1442 if (source.IsEmpty()) 1443 return Handle<Value>(); 1444 1445 const Handle<Script> script = Script::Compile(source, origin); 1477 1446 if (script.IsEmpty()) 1478 return false; 1479 1480 JsSetState(3); 1447 return Handle<Value>(); 1448 1449 if (main) 1450 JsSetState(3); 1481 1451 1482 1452 const Handle<Value> result = script->Run(); 1483 1453 if (result.IsEmpty()) 1484 return false;1454 return result; 1485 1455 1486 1456 // If all went well and the result wasn't undefined then print … … 1489 1459 JsResult(*String::Utf8Value(result)); 1490 1460 1491 return true; 1492 } 1493 1494 bool InterpreterV8::ExecuteCode(const Handle<String> &code, const Handle<Value> &file) 1495 { 1496 TryCatch exception; 1497 1498 const bool rc = ExecuteStringNT(code, file); 1499 1500 // Check if this is a termination exception 1501 //if (!exception.CanContinue()) 1502 // return false; 1503 1504 if (exception.HasCaught()) 1505 return ReportException(&exception); 1506 1507 return rc; 1508 } 1509 1510 bool InterpreterV8::ExecuteCode(const string &code, const string &file) 1511 { 1512 return ExecuteCode(String::New(code.c_str(), code.size()), 1513 String::New(file.c_str())); 1514 } 1515 1516 bool InterpreterV8::ExecuteFile(const string &name) 1461 return handle_scope.Close(result); 1462 } 1463 1464 bool InterpreterV8::ExecuteFile(const string &name, bool main) 1517 1465 { 1518 1466 ifstream fin(name.c_str()); … … 1533 1481 } 1534 1482 1535 return ExecuteCode(buffer, name);1483 return !ExecuteCode(buffer, name, main).IsEmpty(); 1536 1484 } 1537 1485 … … 1567 1515 "case 'x': val = parseInt(arr[i]).toString(base?base:16); break;" 1568 1516 "case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;" 1569 "default:\n"1570 " throw new SyntaxError('Conversion specifier '+p4+' unknown.');\n"1517 //"default:\n" 1518 //" throw new SyntaxError('Conversion specifier '+p4+' unknown.');\n" 1571 1519 "}" 1572 1520 "" … … 1581 1529 "}" 1582 1530 "" 1583 "var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?( .)/g;"1531 "var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd])/g;" 1584 1532 "return str.replace(regex, callback);" 1585 1533 "}" 1586 1534 "\n" 1587 "String.prototype. format= function()"1535 "String.prototype.$ = function()" 1588 1536 "{" 1589 1537 "return dim.format(this, Array.prototype.slice.call(arguments));" 1590 "}" 1538 "}"/* 1591 1539 "\n" 1592 1540 "var format = function()" 1593 1541 "{" 1594 1542 "return dim.format(arguments[0], Array.prototype.slice.call(arguments,1));" 1595 "}" ;1543 "}"*/; 1596 1544 1597 1545 Script::New(String::New(code.c_str()), String::New("internal"))->Run(); … … 1607 1555 JsLoad(filename); 1608 1556 1609 HandleScope handle_scope;1557 const HandleScope handle_scope; 1610 1558 1611 1559 // Create a template for the global object. … … 1668 1616 1669 1617 //context->Enter(); 1618 1619 TryCatch exception; 1620 1670 1621 Locker::StartPreemption(10); 1671 const bool rc = ExecuteFile(filename); 1622 bool rc = ExecuteFile(filename, true); 1623 Locker::StopPreemption(); 1624 1672 1625 Terminate(); 1626 1627 if (exception.HasCaught()) 1628 rc = ReportException(&exception); 1673 1629 1674 1630 // ----- … … 1684 1640 // } 1685 1641 1686 Locker::StopPreemption();1687 1642 //context->Exit(); 1688 1643 -
trunk/FACT++/src/InterpreterV8.h
r14603 r14607 49 49 50 50 bool ReportException(v8::TryCatch* try_catch); 51 bool ExecuteStringNT(const v8::Handle<v8::String> &code, const v8::Handle<v8::Value> &file); 52 bool ExecuteCode(const v8::Handle<v8::String> &code, const v8::Handle<v8::Value> &file); 53 bool ExecuteCode(const std::string &code, const std::string &file=""); 54 bool ExecuteFile(const std::string &name); 51 bool ExecuteFile(const std::string &name, bool main=false); 52 v8::Handle<v8::Value> ExecuteCode(const std::string &code, const std::string &file="internal", bool main=false); 53 v8::Handle<v8::Value> ExecuteInternal(const std::string &code); 55 54 56 55 void ThreadTimeout(v8::Persistent<v8::Function> func, uint32_t ms);
Note:
See TracChangeset
for help on using the changeset viewer.