52
52
#include < cstring>
53
53
#include < typeinfo>
54
54
55
+ #if defined(__arm64__)
56
+ #include < exception>
57
+ #include < setjmp.h>
58
+ #define CLING_CATCH_UNCAUGHT_ \
59
+ ARMUncaughtException guard; \
60
+ if (setjmp(gExcJumBuf ) == 0 ) {
61
+ #define _CLING_CATCH_UNCAUGHT \
62
+ } else { \
63
+ if (!std::getenv (" CPPYY_UNCAUGHT_QUIET" )) \
64
+ std::cerr << " Warning: uncaught exception in JIT is rethrown; resources may leak" \
65
+ << " (suppress with \" CPPYY_UNCAUGHT_QUIET=1\" )" << std::endl;\
66
+ std::rethrow_exception (std::current_exception ()); \
67
+ }
68
+ #else
69
+ #define CLING_CATCH_UNCAUGHT_
70
+ #define _CLING_CATCH_UNCAUGHT
71
+ #endif
72
+
55
73
// temp
56
74
#include < iostream>
57
75
typedef CPyCppyy::Parameter Parameter;
@@ -75,6 +93,7 @@ static const ClassRefs_t::size_type STD_HANDLE = GLOBAL_HANDLE + 1;
75
93
76
94
typedef std::map<std::string, ClassRefs_t::size_type> Name2ClassRefIndex_t;
77
95
static Name2ClassRefIndex_t g_name2classrefidx;
96
+
78
97
static std::map<std::string, std::string> resolved_enum_types;
79
98
80
99
namespace {
@@ -245,7 +264,7 @@ class ApplicationStarter {
245
264
public:
246
265
ApplicationStarter () {
247
266
// initialize ROOT early to guarantee proper order of shutdown later on (gROOT is a
248
- // macro that resolves to the ROOT ::GetROOT() function call)
267
+ // macro that resolves to the ::CppyyLegacy ::GetROOT() function call)
249
268
(void )gROOT ;
250
269
251
270
// setup dummy holders for global and std namespaces
@@ -262,6 +281,13 @@ class ApplicationStarter {
262
281
g_globalvars.push_back (nullptr );
263
282
g_globalidx[nullptr ] = 0 ;
264
283
284
+ // fill out the builtins
285
+ std::set<std::string> bi{g_builtins};
286
+ for (const auto & name : bi) {
287
+ for (const char * a : {" *" , " &" , " *&" , " []" , " *[]" })
288
+ g_builtins.insert (name+a);
289
+ }
290
+
265
291
// disable fast path if requested
266
292
if (std::getenv (" CPPYY_DISABLE_FASTPATH" )) gEnableFastPath = false ;
267
293
@@ -324,25 +350,23 @@ class ApplicationStarter {
324
350
gInterpreter ->Declare (" namespace __cppyy_internal { struct Sep; }" );
325
351
326
352
// retrieve all initial (ROOT) C++ names in the global scope to allow filtering later
327
- if (!std::getenv (" CPPYY_NO_ROOT_FILTER" )) {
328
- gROOT ->GetListOfGlobals (true ); // force initialize
329
- gROOT ->GetListOfGlobalFunctions (true ); // id.
330
- std::set<std::string> initial;
331
- Cppyy::GetAllCppNames (GLOBAL_HANDLE, initial);
332
- gInitialNames = initial;
353
+ gROOT ->GetListOfGlobals (true ); // force initialize
354
+ gROOT ->GetListOfGlobalFunctions (true ); // id.
355
+ std::set<std::string> initial;
356
+ Cppyy::GetAllCppNames (GLOBAL_HANDLE, initial);
357
+ gInitialNames = initial;
333
358
334
359
#ifndef WIN32
335
- gRootSOs .insert (" libCore.so " );
336
- gRootSOs .insert (" libRIO.so " );
337
- gRootSOs .insert (" libThread.so " );
338
- gRootSOs .insert (" libMathCore.so " );
360
+ gRootSOs .insert (" libCore.so " );
361
+ gRootSOs .insert (" libRIO.so " );
362
+ gRootSOs .insert (" libThread.so " );
363
+ gRootSOs .insert (" libMathCore.so " );
339
364
#else
340
- gRootSOs .insert (" libCore.dll " );
341
- gRootSOs .insert (" libRIO.dll " );
342
- gRootSOs .insert (" libThread.dll " );
343
- gRootSOs .insert (" libMathCore.dll " );
365
+ gRootSOs .insert (" libCore.dll " );
366
+ gRootSOs .insert (" libRIO.dll " );
367
+ gRootSOs .insert (" libThread.dll " );
368
+ gRootSOs .insert (" libMathCore.dll " );
344
369
#endif
345
- }
346
370
347
371
// start off with a reasonable size placeholder for wrappers
348
372
gWrapperHolder .reserve (1024 );
@@ -467,10 +491,10 @@ std::string Cppyy::ResolveName(const std::string& cppitem_name)
467
491
if (tclean.compare (0 , 9 , " std::byte" ) == 0 )
468
492
return tclean;
469
493
470
-
471
494
// check data types list (accept only builtins as typedefs will
472
495
// otherwise not be resolved)
473
496
if (IsBuiltin (tclean)) return tclean;
497
+
474
498
// special case for enums
475
499
if (IsEnum (cppitem_name))
476
500
return ResolveEnum (cppitem_name);
@@ -699,15 +723,17 @@ Cppyy::TCppType_t Cppyy::GetActualClass(TCppType_t klass, TCppObject_t obj)
699
723
// if the raw name is the empty string (no guarantees that this is so as truly, the
700
724
// address is corrupt, but it is common to be empty), then there is no accessible RTTI
701
725
// and getting the unmangled name will crash ...
702
- if (!raw)
726
+
727
+ // a common case are the i/o stream objects b/c these are pulled in from libCling
728
+ if (!raw || (strstr (cr->GetName (), " std::basic_" ) && strstr (cr->GetName (), " stream" )) || raw[0 ] == ' \0 ' )
703
729
return klass;
704
730
} catch (std::bad_typeid) {
705
731
return klass; // can't risk passing to ROOT/meta as it may do RTTI
706
732
}
707
733
#endif
708
734
709
735
TClass* clActual = cr->GetActualClass ((void *)obj);
710
- // The additional check using TClass::GetClassInfo is to prevent returning classes of which the Interpreter has no info
736
+ // The additional check using TClass::GetClassInfo is to prevent returning classes of which the Interpreter has no info (see https://github.com/root-project/root/pull/16177)
711
737
if (clActual && clActual != cr.GetClass () && clActual->GetClassInfo ()) {
712
738
auto itt = g_name2classrefidx.find (clActual->GetName ());
713
739
if (itt != g_name2classrefidx.end ())
@@ -733,7 +759,6 @@ size_t Cppyy::SizeOf(const std::string& type_name)
733
759
return SizeOf (GetScope (type_name));
734
760
}
735
761
736
-
737
762
bool Cppyy::IsBuiltin (const std::string& type_name)
738
763
{
739
764
if (g_builtins.find (type_name) != g_builtins.end ())
@@ -756,7 +781,7 @@ bool Cppyy::IsComplete(const std::string& type_name)
756
781
757
782
int oldEIL = gErrorIgnoreLevel ;
758
783
gErrorIgnoreLevel = 3000 ;
759
- TClass* klass = TClass::GetClass (TClassEdit::ShortType ( type_name. c_str (), 1 ) .c_str ());
784
+ TClass* klass = TClass::GetClass (type_name.c_str ());
760
785
if (klass && klass->GetClassInfo ()) // works for normal case w/ dict
761
786
b = gInterpreter ->ClassInfo_IsLoaded (klass->GetClassInfo ());
762
787
else { // special case for forward declared classes
@@ -802,11 +827,11 @@ void Cppyy::Destruct(TCppType_t type, TCppObject_t instance)
802
827
else {
803
828
auto ib = sHasOperatorDelete .find (type);
804
829
if (ib == sHasOperatorDelete .end ()) {
805
- TFunction *f = (TFunction *)cr->GetMethodAllAny (" operator delete" );
806
- sHasOperatorDelete [type] = (bool )(f && (f->Property () & kIsPublic ));
807
- ib = sHasOperatorDelete .find (type);
830
+ TFunction *f = (TFunction *)cr->GetMethodAllAny (" operator delete" );
831
+ sHasOperatorDelete [type] = (bool )(f && (f->Property () & kIsPublic ));
832
+ ib = sHasOperatorDelete .find (type);
808
833
}
809
- ib->second ? cr->Destructor ((void *)instance) : ::operator delete ((void *)instance);
834
+ ib->second ? cr->Destructor ((void *)instance) : ::operator delete ((void *)instance);
810
835
}
811
836
}
812
837
}
@@ -869,7 +894,8 @@ bool copy_args(Parameter* args, size_t nargs, void** vargs)
869
894
}
870
895
871
896
static inline
872
- void release_args (Parameter* args, size_t nargs) {
897
+ void release_args (Parameter* args, size_t nargs)
898
+ {
873
899
for (size_t i = 0 ; i < nargs; ++i) {
874
900
if (args[i].fTypeCode == ' X' )
875
901
free (args[i].fValue .fVoidp );
@@ -1106,15 +1132,19 @@ bool Cppyy::IsAbstract(TCppType_t klass)
1106
1132
bool Cppyy::IsEnum (const std::string& type_name)
1107
1133
{
1108
1134
if (type_name.empty ()) return false ;
1135
+
1136
+ if (type_name.rfind (" enum " , 0 ) == 0 )
1137
+ return true ; // by definition (C-style)
1138
+
1109
1139
std::string tn_short = TClassEdit::ShortType (type_name.c_str (), 1 );
1110
1140
if (tn_short.empty ()) return false ;
1111
1141
return gInterpreter ->ClassInfo_IsEnum (tn_short.c_str ());
1112
1142
}
1113
1143
1114
- bool Cppyy::IsAggregate (TCppType_t klass )
1144
+ bool Cppyy::IsAggregate (TCppType_t type )
1115
1145
{
1116
- // Test if this type is an aggregate type
1117
- TClassRef& cr = type_from_handle (klass );
1146
+ // Test if this type is a "plain old data" type
1147
+ TClassRef& cr = type_from_handle (type );
1118
1148
if (cr.GetClass ())
1119
1149
return cr->ClassProperty () & kClassIsAggregate ;
1120
1150
return false ;
@@ -1183,7 +1213,7 @@ static inline
1183
1213
void cond_add (Cppyy::TCppScope_t scope, const std::string& ns_scope,
1184
1214
std::set<std::string>& cppnames, const char * name, bool nofilter = false )
1185
1215
{
1186
- if (!name || name[ 0 ] == ' _ ' || strstr (name, " .h" ) != 0 || strncmp (name, " operator " , 8 ) = = 0 )
1216
+ if (!name || strstr (name, " .h" ) != 0 )
1187
1217
return ;
1188
1218
1189
1219
if (scope == GLOBAL_HANDLE) {
@@ -1252,23 +1282,21 @@ void Cppyy::GetAllCppNames(TCppScope_t scope, std::set<std::string>& cppnames)
1252
1282
1253
1283
// add functions
1254
1284
coll = (scope == GLOBAL_HANDLE) ?
1255
- gROOT ->GetListOfGlobalFunctions () : cr->GetListOfMethods ();
1285
+ gROOT ->GetListOfGlobalFunctions (true ) : cr->GetListOfMethods (true );
1256
1286
{
1257
1287
TIter itr{coll};
1258
1288
TFunction* obj = nullptr ;
1259
1289
while ((obj = (TFunction*)itr.Next ())) {
1260
1290
const char * nm = obj->GetName ();
1261
1291
// skip templated functions, adding only the un-instantiated ones
1262
- if (nm && nm[0 ] != ' _' && strstr (nm, " <" ) == 0 && strncmp (nm, " operator" , 8 ) != 0 ) {
1263
- if (gInitialNames .find (nm) == gInitialNames .end ())
1264
- cppnames.insert (nm);
1265
- }
1292
+ if (nm && gInitialNames .find (nm) == gInitialNames .end ())
1293
+ cppnames.insert (nm);
1266
1294
}
1267
1295
}
1268
1296
1269
1297
// add uninstantiated templates
1270
1298
coll = (scope == GLOBAL_HANDLE) ?
1271
- gROOT ->GetListOfFunctionTemplates () : cr->GetListOfFunctionTemplates ();
1299
+ gROOT ->GetListOfFunctionTemplates () : cr->GetListOfFunctionTemplates (true );
1272
1300
FILL_COLL (TFunctionTemplate, kIsPrivate | kIsProtected )
1273
1301
1274
1302
// add (global) data members
@@ -1350,7 +1378,7 @@ std::string Cppyy::GetScopedFinalName(TCppType_t klass)
1350
1378
return std::string (" std::" )+cr->GetName ();
1351
1379
return cr->GetName ();
1352
1380
}
1353
- return " " ;
1381
+ return " <unknown> " ;
1354
1382
}
1355
1383
1356
1384
bool Cppyy::HasVirtualDestructor (TCppType_t klass)
@@ -1512,10 +1540,8 @@ bool Cppyy::GetSmartPtrInfo(
1512
1540
TClassRef& cr = type_from_handle (GetScope (tname));
1513
1541
if (cr.GetClass ()) {
1514
1542
TFunction* func = cr->GetMethod (" operator->" , " " );
1515
- if (!func) {
1516
- gInterpreter ->UpdateListOfMethods (cr.GetClass ());
1543
+ if (!func)
1517
1544
func = cr->GetMethod (" operator->" , " " );
1518
- }
1519
1545
if (func) {
1520
1546
if (deref) *deref = (TCppMethod_t)new_CallWrapper (func);
1521
1547
if (raw) *raw = GetScope (TClassEdit::ShortType (
@@ -2483,3 +2509,5 @@ long long Cppyy::GetEnumDataValue(TCppEnum_t etype, TCppIndex_t idata)
2483
2509
TEnumConstant* ecst = (TEnumConstant*)((TEnum*)etype)->GetConstants ()->At ((int )idata);
2484
2510
return (long long )ecst->GetValue ();
2485
2511
}
2512
+
2513
+
0 commit comments