Skip to content

Commit 3580f96

Browse files
authored
Merge branch 'main' into cppinterop-out
2 parents 1d307ff + 1f43b4e commit 3580f96

File tree

12 files changed

+189
-772
lines changed

12 files changed

+189
-772
lines changed

docs/DevelopersDocumentation.rst

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -464,54 +464,12 @@ library files and run pytest:
464464
python -m pip install pytest
465465
python -m pytest -sv
466466
467-
###################################
467+
***********************************
468468
CppInterOp Internal Documentation
469-
###################################
469+
***********************************
470470

471471
CppInterOp maintains an internal Doxygen documentation of its components.
472472
Internal documentation aims to capture intrinsic details and overall usage of
473473
code components. The goal of internal documentation is to make the codebase
474474
easier to understand for the new developers. Internal documentation can be
475475
visited : `here <build/html/index.html>`_
476-
477-
**************************************
478-
Multiple Interpreter & Thread-Safety
479-
**************************************
480-
481-
CppInterOp allows the user to create multiple interpreters at a time and
482-
use those interpreters. The interpreters that are created are stored in a
483-
stack and a map. The stack is used to enable the model where the user
484-
wants to create a temporary interpreter and destroy it after performing a
485-
few operations. In such a use case, the top of the stack is the only
486-
interpreter in use at any given point in time.
487-
488-
The map is used to store the mapping from :code:`clang::ASTContext` to
489-
:code:`Cpp::InterpreterInfo`. This is required to figure out which
490-
interpreter an object belongs to. Say the library user performs the
491-
following operations:
492-
493-
1. Create an Interpreter
494-
2. Compile some code with variable :code:`a`
495-
3. Create another Interpreter
496-
4. Performs :code:`Cpp::GetVariableOffset(a)`
497-
498-
In step 4, the top of the stack is an interpreter without the definition of
499-
:code:`a`. And we cannot use it to figure out the address of :code:`a`.
500-
The :code:`clang::Decl` passed to :code:`Cpp::GetVariableOffset` is used to
501-
retrieve the :code:`clang::ASTContext`, using
502-
:code:`clang::Decl::getASTContext`. We then use the map to figure out the
503-
exact Interpreter Instance this :code:`clang::Decl` belongs to and perform
504-
the operation.
505-
506-
A shortcoming of this is that if the CppInterOp accepts a
507-
:code:`clang::QualType` instead of :code:`clang::Decl`, then it is not
508-
possible to get the :code:`clang::ASTContext` from the :code:`clang::QualType`.
509-
In such cases, we iterate over the Allocator of all the Interpreters in our
510-
stack and figure out which :code:`clang::ASTContext` allocated this
511-
:code:`clang::QualType`. This is a very expensive operation. But there is no
512-
alternative to this.
513-
514-
For **thread-safety**, we introduce a lock for each of the interpreters we
515-
create. And lock only that one specific interpreter when required. We also
516-
have 2 global locks, one for LLVM, and another is used to lock operations
517-
performed on the interpreter stack and the map itself.

include/CppInterOp/CppInterOp.h

Lines changed: 23 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ CPPINTEROP_API std::string GetQualifiedCompleteName(TCppScope_t klass);
390390
CPPINTEROP_API std::vector<TCppScope_t> GetUsingNamespaces(TCppScope_t scope);
391391

392392
/// Gets the global scope of the whole C++ instance.
393-
CPPINTEROP_API TCppScope_t GetGlobalScope(TInterp_t interp = nullptr);
393+
CPPINTEROP_API TCppScope_t GetGlobalScope();
394394

395395
/// Strips the typedef and returns the underlying class, and if the
396396
/// underlying decl is not a class it returns the input unchanged.
@@ -399,28 +399,18 @@ CPPINTEROP_API TCppScope_t GetUnderlyingScope(TCppScope_t scope);
399399
/// Gets the namespace or class (by stripping typedefs) for the name
400400
/// passed as a parameter, and if the parent is not passed,
401401
/// then global scope will be assumed.
402-
/// Looks up the name in parent, if parent is nullptr,
403-
/// interp is used to select the interpreter if multiple in-use.
404-
/// interp is ignored if parent is non-null.
405402
CPPINTEROP_API TCppScope_t GetScope(const std::string& name,
406-
TCppScope_t parent = nullptr,
407-
TInterp_t interp = nullptr);
403+
TCppScope_t parent = nullptr);
408404

409405
/// When the namespace is known, then the parent doesn't need
410406
/// to be specified. This will probably be phased-out in
411407
/// future versions of the interop library.
412-
/// interp is used to select the interpreter if multiple in-use.
413-
CPPINTEROP_API TCppScope_t GetScopeFromCompleteName(const std::string& name,
414-
TInterp_t interp = nullptr);
408+
CPPINTEROP_API TCppScope_t GetScopeFromCompleteName(const std::string& name);
415409

416410
/// This function performs a lookup within the specified parent,
417411
/// a specific named entity (functions, enums, etcetera).
418-
/// Looks up the name in parent, if parent is nullptr,
419-
/// interp is used to select the interpreter if multiple in-use.
420-
/// interp is ignored if parent is non-null.
421412
CPPINTEROP_API TCppScope_t GetNamed(const std::string& name,
422-
TCppScope_t parent = nullptr,
423-
TInterp_t interp = nullptr);
413+
TCppScope_t parent = nullptr);
424414

425415
/// Gets the parent of the scope that is passed as a parameter.
426416
CPPINTEROP_API TCppScope_t GetParentScope(TCppScope_t scope);
@@ -504,12 +494,8 @@ CPPINTEROP_API bool IsTemplatedFunction(TCppFunction_t func);
504494

505495
/// This function performs a lookup to check if there is a
506496
/// templated function of that type.
507-
/// Looks up the name in parent, if parent is nullptr,
508-
/// interp is used to select the interpreter if multiple in-use.
509-
/// interp is ignored if parent is non-null.
510497
CPPINTEROP_API bool ExistsFunctionTemplate(const std::string& name,
511-
TCppScope_t parent = nullptr,
512-
TInterp_t interp = nullptr);
498+
TCppScope_t parent = nullptr);
513499

514500
/// Sets a list of all the constructor for a scope/class that is
515501
/// supplied as a parameter.
@@ -557,8 +543,7 @@ CPPINTEROP_API bool IsDestructor(TCppConstFunction_t method);
557543
CPPINTEROP_API bool IsStaticMethod(TCppConstFunction_t method);
558544

559545
///\returns the address of the function given its potentially mangled name.
560-
CPPINTEROP_API TCppFuncAddr_t GetFunctionAddress(const char* mangled_name,
561-
TInterp_t interp = nullptr);
546+
CPPINTEROP_API TCppFuncAddr_t GetFunctionAddress(const char* mangled_name);
562547

563548
///\returns the address of the function given its function declaration.
564549
CPPINTEROP_API TCppFuncAddr_t GetFunctionAddress(TCppFunction_t method);
@@ -659,9 +644,7 @@ CPPINTEROP_API TCppType_t GetCanonicalType(TCppType_t type);
659644

660645
/// Used to either get the built-in type of the provided string, or
661646
/// use the name to lookup the actual type.
662-
/// interp is used to select the interpreter if multiple in-use.
663-
CPPINTEROP_API TCppType_t GetType(const std::string& type,
664-
TInterp_t interp = nullptr);
647+
CPPINTEROP_API TCppType_t GetType(const std::string& type);
665648

666649
///\returns the complex of the provided type.
667650
CPPINTEROP_API TCppType_t GetComplexType(TCppType_t element_type);
@@ -720,11 +703,6 @@ CreateInterpreter(const std::vector<const char*>& Args = {},
720703
///\returns false on failure or if \c I is not tracked in the stack.
721704
CPPINTEROP_API bool DeleteInterpreter(TInterp_t I = nullptr);
722705

723-
/// Take ownership of an interpreter instance.
724-
///\param[in] I - the interpreter to be taken, if nullptr, returns the last.
725-
///\returns nullptr on failure or if \c I is not tracked in the stack.
726-
CPPINTEROP_API TInterp_t TakeInterpreter(TInterp_t I = nullptr);
727-
728706
/// Activates an instance of an interpreter to handle subsequent API requests
729707
///\param[in] I - the interpreter to be activated.
730708
///\returns false on failure.
@@ -745,10 +723,10 @@ CPPINTEROP_API void UseExternalInterpreter(TInterp_t I);
745723

746724
/// Adds a Search Path for the Interpreter to get the libraries.
747725
CPPINTEROP_API void AddSearchPath(const char* dir, bool isUser = true,
748-
bool prepend = false, TInterp_t I = nullptr);
726+
bool prepend = false);
749727

750728
/// Returns the resource-dir path (for headers).
751-
CPPINTEROP_API const char* GetResourceDir(TInterp_t I = nullptr);
729+
CPPINTEROP_API const char* GetResourceDir();
752730

753731
/// Uses the underlying clang compiler to detect the resource directory.
754732
/// In essence calling clang -print-resource-dir and checks if it ends with
@@ -769,52 +747,46 @@ DetectSystemCompilerIncludePaths(std::vector<std::string>& Paths,
769747

770748
/// Secondary search path for headers, if not found using the
771749
/// GetResourceDir() function.
772-
CPPINTEROP_API void AddIncludePath(const char* dir, TInterp_t I = nullptr);
750+
CPPINTEROP_API void AddIncludePath(const char* dir);
773751

774752
// Gets the currently used include paths
775753
///\param[out] IncludePaths - the list of include paths
776754
///
777755
CPPINTEROP_API void GetIncludePaths(std::vector<std::string>& IncludePaths,
778756
bool withSystem = false,
779-
bool withFlags = false,
780-
TInterp_t I = nullptr);
757+
bool withFlags = false);
781758

782759
/// Only Declares a code snippet in \c code and does not execute it.
783760
///\returns 0 on success
784-
CPPINTEROP_API int Declare(const char* code, bool silent = false,
785-
TInterp_t I = nullptr);
761+
CPPINTEROP_API int Declare(const char* code, bool silent = false);
786762

787763
/// Declares and executes a code snippet in \c code.
788764
///\returns 0 on success
789-
CPPINTEROP_API int Process(const char* code, TInterp_t I = nullptr);
765+
CPPINTEROP_API int Process(const char* code);
790766

791767
/// Declares, executes and returns the execution result as a intptr_t.
792768
///\returns the expression results as a intptr_t.
793-
CPPINTEROP_API intptr_t Evaluate(const char* code, bool* HadError = nullptr,
794-
TInterp_t I = nullptr);
769+
CPPINTEROP_API intptr_t Evaluate(const char* code, bool* HadError = nullptr);
795770

796771
/// Looks up the library if access is enabled.
797772
///\returns the path to the library.
798-
CPPINTEROP_API std::string LookupLibrary(const char* lib_name,
799-
TInterp_t I = nullptr);
773+
CPPINTEROP_API std::string LookupLibrary(const char* lib_name);
800774

801775
/// Finds \c lib_stem considering the list of search paths and loads it by
802776
/// calling dlopen.
803777
/// \returns true on success.
804-
CPPINTEROP_API bool LoadLibrary(const char* lib_stem, bool lookup = true,
805-
TInterp_t I = nullptr);
778+
CPPINTEROP_API bool LoadLibrary(const char* lib_stem, bool lookup = true);
806779

807780
/// Finds \c lib_stem considering the list of search paths and unloads it by
808781
/// calling dlclose.
809782
/// function.
810-
CPPINTEROP_API void UnloadLibrary(const char* lib_stem, TInterp_t I = nullptr);
783+
CPPINTEROP_API void UnloadLibrary(const char* lib_stem);
811784

812785
/// Scans all libraries on the library search path for a given potentially
813786
/// mangled symbol name.
814787
///\returns the path to the first library that contains the symbol definition.
815-
CPPINTEROP_API std::string SearchLibrariesForSymbol(const char* mangled_name,
816-
bool search_system /*true*/,
817-
TInterp_t I = nullptr);
788+
CPPINTEROP_API std::string
789+
SearchLibrariesForSymbol(const char* mangled_name, bool search_system /*true*/);
818790

819791
/// Inserts or replaces a symbol in the JIT with the one provided. This is
820792
/// useful for providing our own implementations of facilities such as printf.
@@ -825,8 +797,7 @@ CPPINTEROP_API std::string SearchLibrariesForSymbol(const char* mangled_name,
825797
///
826798
///\returns true on failure.
827799
CPPINTEROP_API bool InsertOrReplaceJitSymbol(const char* linker_mangled_name,
828-
uint64_t address,
829-
TInterp_t I = nullptr);
800+
uint64_t address);
830801

831802
/// Tries to load provided objects in a string format (prettyprint).
832803
CPPINTEROP_API std::string ObjToString(const char* type, void* obj);
@@ -863,10 +834,9 @@ GetClassTemplateInstantiationArgs(TCppScope_t templ_instance,
863834

864835
/// Instantiates a function template from a given string representation. This
865836
/// function also does overload resolution.
866-
///\param[in] interp - is used to select the interpreter if multiple in-use.
867837
///\returns the instantiated function template declaration.
868-
CPPINTEROP_API TCppFunction_t InstantiateTemplateFunctionFromString(
869-
const char* function_template, TInterp_t interp = nullptr);
838+
CPPINTEROP_API TCppFunction_t
839+
InstantiateTemplateFunctionFromString(const char* function_template);
870840

871841
/// Finds best overload match based on explicit template parameters (if any)
872842
/// and argument types.
@@ -964,7 +934,7 @@ CPPINTEROP_API void CodeComplete(std::vector<std::string>& Results,
964934
/// Reverts the last N operations performed by the interpreter.
965935
///\param[in] N The number of operations to undo. Defaults to 1.
966936
///\returns 0 on success, non-zero on failure.
967-
CPPINTEROP_API int Undo(unsigned N = 1, TInterp_t interp = nullptr);
937+
CPPINTEROP_API int Undo(unsigned N = 1);
968938

969939
#ifndef _WIN32
970940
/// Returns the process ID of the executor process.

0 commit comments

Comments
 (0)