<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
I am always in favor of getting JIT improvements into mainline as
soon as possible. Also, simplifying APIs is an important goal.<br>
<br>
On the other hand this raises a few general questions for me:<br>
<br>
IIUC the current patch introduces a dependency from LLVM to
compiler-rt/clang build artifacts, because the llvm-jitlink-executor
executable is fully functional only if it can find the clang_rt.orc
static library in the build tree. Do we have dependencies like that
in mainline so far?<br>
<br>
And how does it affect testing? So far, it seems we have no testing
for out-of-process execution, because the only tool that exercises
this functionality is llvm-jitlink, which itself is mostly used as a
testing helper. If the functionality now moves into the
TargetProcess library, it might be worth thinking through the test
strategy first.<br>
<br>
At the moment, the TargetProcess library is only used by JITLink.
Will it stay like that? If so, RuntimeDyld-based JITs will not be
affected by the patch. Will it be possible to build and run e.g. a
LLJIT instance with a RuntimeDyldLinkingLayer if only LLVM gets
built (omitting LLVM_ENABLE_PROJECTS="clang;compiler-rt")?<br>
<br>
Last but not least, there are examples that use JITLink. Could we
still build and run them if only LLVM gets built? <br>
<br>
Thanks,<br>
Stefan<br>
<br>
<div class="moz-cite-prefix">On 19/01/2021 23:08, Lang Hames wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CALLttgoqvWbA1w3cnuvqAAVnz6vb5qFhFpaEut0vg9sypy7Zwg@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<div dir="ltr">
<div>Big question for JIT clients: Does anyone have any
objection to APIs in ORC *relying* on the runtime being
loaded in the target? If so, now is the time to let me know.
:)</div>
<div><br>
</div>
<div>I think possible objections are JIT'd program startup
time (unlikely to be very high, and likely fixable via
careful runtime design and pre-linking of parts of the
runtime), and difficulties building compiler-rt (which
sounds like something we should fix in compiler-rt).</div>
<div><br>
</div>
<div>If we can assume that the runtime is loadable then we can
significantly simplify the TargetProcess library, and
TargetProcessControl API, and further accelerate feature
development in LLVM 13.</div>
<div><br>
</div>
<div>-- Lang.</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Jan 19, 2021 at 8:45
AM Lang Hames <<a href="mailto:lhames@gmail.com"
moz-do-not-send="true">lhames@gmail.com</a>> wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Hi Stefan,
<div><br>
</div>
<div>
<blockquote class="gmail_quote" style="margin:0px 0px
0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">%
./bin/llvm-jitlink -oop-executor inits.o<br>
JIT session error: Symbols not found: [
__ZTIN4llvm6detail14format_adapterE ]</blockquote>
</div>
<div><br>
</div>
<div>I've been testing with a debug build:</div>
<div><br>
</div>
<div>% xcrun cmake -GNinja -DCMAKE_BUILD_TYPE=Debug
-DLLVM_ENABLE_PROJECTS="llvm;clang;compiler-rt"
../llvm</div>
<div><br>
</div>
<div>
<div>Matching this build might fix the issue, though
building with my config (if it works) is only a
short-term fix. The error that you're seeing implies
that the runtime is dependending on a symbol from
libSupport that is not being linked in to the target
(llvm-jitlink-executor). I'll aim to break these
dependencies on libSupport in the future. Mostly
that means either removing the dependence on
llvm::Error / llvm::Expected (e.g. by creating
stripped down versions for the orc runtime), or
making those types header-only.</div>
</div>
<div><br>
</div>
<div>-- Lang.</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Jan 19, 2021 at
12:50 AM Stefan Gränitz <<a
href="mailto:stefan.graenitz@gmail.com" target="_blank"
moz-do-not-send="true">stefan.graenitz@gmail.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div> Wow, thanks for the update. One more ORC milestone
in a short period of time!<br>
<br>
On macOS I built the C++ example like this:<br>
<br>
% cmake -GNinja -DLLVM_TARGETS_TO_BUILD=host
-DLLVM_ENABLE_PROJECTS="clang;compiler-rt" ../llvm<br>
% ninja llvm-jitlink llvm-jitlink-executor
lib/clang/12.0.0/lib/darwin/libclang_rt.orc_osx.a<br>
% clang++ -c -o inits.o inits.cpp<br>
<br>
The in-process version works perfectly, but with the
out-of-process flag the examples fails:<br>
<br>
% ./bin/llvm-jitlink inits.o<br>
Foo::Foo()<br>
Foo::foo()<br>
Foo::~Foo()<br>
% ./bin/llvm-jitlink -oop-executor inits.o<br>
JIT session error: Symbols not found: [
__ZTIN4llvm6detail14format_adapterE ]<br>
<br>
Any idea what could go wrong here? Otherwise I can try
to debug it later this week. (Full error below.)<br>
<br>
Best<br>
Stefan<br>
<br>
--<br>
<br>
JIT session error: Symbols not found: [
__ZTIN4llvm6detail14format_adapterE ]<br>
/Users/staefsn/Develop/LLVM/monorepo/llvm-orc-runtime/build/bin/llvm-jitlink:
Failed to materialize symbols: { (Main, {
___orc_rt_macho_symbol_lookup_remote,
__ZN4llvm3orc6shared21WrapperFunctionResult22destroyWithArrayDeleteE39LLVMOrcSharedCWrapperFunctionResultDatay,
__ZNSt3__113__vector_baseIN4llvm3orc6shared25MachOJITDylibInitializersENS_9allocatorIS4_EEED2Ev,
__ZNK4llvm8ExpectedINS_3orc6shared21WrapperFunctionResultEE22fatalUncheckedExpectedEv,
__ZN4llvm3orc6shared21toWrapperFunctionBlobIJNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEEENS1_21WrapperFunctionResultEDpRKT_,
__ZN4llvm3orc6shared20VectorRawByteChannelD1Ev,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJNSt3__16vectorINS1_25MachOJITDylibInitializers13SectionExtentENS4_9allocatorIS7_EEEESA_SA_EE11deserializeISA_JSA_SA_EEENS_5ErrorERS3_RT_DpRT0_,
__ZNSt3__16vectorIN4llvm3orc6shared25MachOJITDylibInitializers13SectionExtentENS_9allocatorIS5_EEE8__appendEm,
__ZN4llvm3orc6shared21toWrapperFunctionBlobIJyNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEEENS1_21WrapperFunctionResultEDpRKT_,
__ZN4llvm29VerifyEnableABIBreakingChecksE,
__ZN4llvm15format_providerImvE6formatERKmRNS_11raw_ostreamENS_9StringRefE,
__ZNSt3__114__split_bufferIN4llvm3orc6shared25MachOJITDylibInitializersERNS_9allocatorIS4_EEED2Ev,
__ZTVN4llvm6detail23provider_format_adapterIRmEE,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJyNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEE9serializeIRKyJRKSA_EEENS_5ErrorERS3_OT_DpOT0_,
__ZTVN4llvm6detail23provider_format_adapterImEE,
__ZN4llvm6detail23provider_format_adapterImE6formatERNS_11raw_ostreamENS_9StringRefE,
__ZN4llvm6detail23provider_format_adapterIRmED1Ev,
___orc_rt_macho_get_deinitializers_tag,
__ZN4llvm6detail23provider_format_adapterIRmED0Ev,
__ZTVN4llvm3orc6shared14RawByteChannelE,
__ZN6orc_rt12jit_dispatchEPKvN4llvm8ArrayRefIhEE,
__ZN4llvm3orc6shared20VectorRawByteChannelD0Ev,
__ZTVN4llvm3orc6shared20VectorRawByteChannelE,
__ZN4llvm8cantFailENS_5ErrorEPKc,
__ZN4llvm6detail23provider_format_adapterImED1Ev,
__ZTVN4llvm6detail23provider_format_adapterIRjEE,
__ZN4llvm6detail23provider_format_adapterImED0Ev,
__ZN4llvm15format_providerIjvE6formatERKjRNS_11raw_ostreamENS_9StringRefE,
__ZTSN4llvm3orc6shared14RawByteChannelE,
__ZN4llvm6detail23provider_format_adapterIRjE6formatERNS_11raw_ostreamENS_9StringRefE,
__ZN4llvm6detail23provider_format_adapterIRjED0Ev,
__ZN4llvm3orc6shared19SerializationTraitsINS1_20VectorRawByteChannelENSt3__16vectorINS1_25MachOJITDylibInitializersENS4_9allocatorIS6_EEEES9_vE11deserializeERS3_RS9_,
__ZTIN4llvm6detail23provider_format_adapterImEE,
__ZN4llvm6detail15HelperFunctions15consumeHexStyleERNS_9StringRefERNS_13HexPrintStyleE,
__ZTIN4llvm6detail23provider_format_adapterIRmEE,
___orc_rt_macho_get_initializers_tag,
__ZTSN4llvm6detail23provider_format_adapterImEE,
__ZN4llvm3orc6shared20VectorRawByteChannel4sendEv,
__ZN4llvm6detail23provider_format_adapterIRmE6formatERNS_11raw_ostreamENS_9StringRefE,
___orc_rt_macho_symbol_lookup_tag,
__ZTSN4llvm6detail23provider_format_adapterIRmEE,
__ZN4llvm3orc6shared20VectorRawByteChannel11appendBytesEPKcj,
__ZTSN4llvm6detail23provider_format_adapterIRjEE,
__ZN4llvm3orc6shared20VectorRawByteChannel9readBytesEPcj,
__ZTSN4llvm3orc6shared20VectorRawByteChannelE,
__ZN4llvm6detail23provider_format_adapterIRjED1Ev,
__ZN4llvm3orc6shared14RawByteChannelD1Ev,
__ZN4llvm3orc6shared23fromWrapperFunctionBlobIJNSt3__16vectorINS1_25MachOJITDylibInitializersENS3_9allocatorIS5_EEEEEEENS_5ErrorENS_8ArrayRefIhEEDpRT_,
__ZN4llvm3orc6shared14RawByteChannelD0Ev,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJyyNSt3__16vectorINS1_25MachOJITDylibInitializers13SectionExtentENS4_9allocatorIS7_EEEESA_SA_EE11deserializeIyJySA_SA_SA_EEENS_5ErrorERS3_RT_DpRT0_,
__ZNSt3__16vectorIN4llvm3orc6shared25MachOJITDylibInitializersENS_9allocatorIS4_EEE8__appendEm,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJyyEE11deserializeIyJyEEENS_5ErrorERS3_RT_DpRT0_,
__ZNSt3__16vectorIN4llvm3orc6shared25MachOJITDylibInitializersENS_9allocatorIS4_EEE6resizeEm,
__ZN4llvm3orc6shared19SerializationTraitsINS1_20VectorRawByteChannelENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESA_vE11deserializeERNS1_14RawByteChannelERSA_,
__ZN4llvm3orc6shared23fromWrapperFunctionBlobIJyEEENS_5ErrorENS_8ArrayRefIhEEDpRT_,
__ZTIN4llvm6detail23provider_format_adapterIRjEE,
__ZN4llvm3orc6shared21WrapperFunctionResult20getAnyOutOfBandErrorEv,
__ZTIN4llvm3orc6shared20VectorRawByteChannelE,
___orc_rt_macho_get_initializers_remote,
__ZTIN4llvm3orc6shared14RawByteChannelE,
__ZNSt3__16vectorIhNS_9allocatorIhEEE26__swap_out_circular_bufferERNS_14__split_bufferIhRS2_EE,
__ZN4llvm3orc6shared19SerializationTraitsINS1_20VectorRawByteChannelENSt3__16vectorINS1_25MachOJITDylibInitializers13SectionExtentENS4_9allocatorIS7_EEEESA_vE11deserializeERS3_RSA_
}) }<br>
/Users/staefsn/Develop/LLVM/monorepo/llvm-orc-runtime/build/bin/llvm-jitlink-executor:Response
has unknown sequence number 527162<br>
<br>
<div>On 18/01/2021 08:55, Lang Hames wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Hi
All,</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">Happy
2021!<br>
<div><br>
</div>
<div>I've just
posted a new
Orc Runtime
Preview patch:
<a
href="https://github.com/lhames/llvm-project/commit/8833a7f24693f1c7a3616438718e7927c6624894"
target="_blank" moz-do-not-send="true">https://github.com/lhames/llvm-project/commit/8833a7f24693f1c7a3616438718e7927c6624894</a></div>
<div><br>
</div>
<div>Quick
background:</div>
<div><br>
</div>
<div>To date,
neither ORC
nor MCJIT have
had their own
runtime
libraries.
This has
limited and
complicated
the
implementation
of many
features (e.g.
jit re-entry
functions,
exception
handling,
JID'd
initializers
and
de-initializers),
and
more-or-less
prevented the
implementation
of others
(e.g. native
thread local
storage).</div>
<div><br>
</div>
<div>Late last
year I started
work on a
prototype ORC
runtime
library to
address this,
and with the
above commit
I've finally
got something
worth sharing.</div>
<div><br>
</div>
<div>The
prototype
above is
simultaneously
limited and
complex.
Limited, in
that it only
tackles a
small subset
of the desired
functionality.
Complex in
that it's one
of the most
involved
pieces of
functionality
that I
anticipate
supporting, as
it requires
two-way
communication
between the
executor and
JIT processes.
My aim in
choosing to
tackle the
hard part
first was to
get a sense of
our ultimate
requirements
for the
project,
particularly
in regards to
<i>where it
should live
within the
LLVM Project</i>.
It's not a
perfect fit
for LLVM
proper: there
will be lots
of target
specific code,
including
assembly, and
it should be
easily
buildable for
multiple
targets (that
sounds more
like
compiler-rt).
On the other
hand it's not
a perfect fit
for
compiler-rt:
it shares data
structures
with LLVM, and
it would be
very useful to
be able to
re-use
llvm::Error /
llvm::Expected
(that sounds
like LLVM). At
the moment I
think the best
way to square
things would
be to keep it
in
compiler-rt,
allow
inclusion of
header-only
code from LLVM
in
compiler-rt,
and then make
Error /
Expected
header-only
(or copy /
adapt them for
this library).
This will be a
discussion for
llvm-dev at
some point in
the near
future.</div>
<div><br>
</div>
<div>On to the
actual
functionality
though: The
prototype
makes
significant
changes to the
MachOPlatform
class and
introduces an
ORC runtime
library in
compiler-rt/lib/orc.
Together,
these changes
allow us to
emulate the
dlopen / dlsym
/ dlclose in
the JIT
executor
process. We
can use this
to define what
it means to
run a <i>JIT
program</i>,
rather than
just running a
JIT function
(the way
TargetProcessControl::runAsMain
does):</div>
<div><br>
</div>
<div>
<div
style="color:rgb(0,0,0)"><font
face="monospace">ORC_RT_INTERFACE <font color="#38761d">int64_t</font> <font
color="#0b5394">__orc_rt_macho_run_program</font>(<font color="#38761d">int</font> <font
color="#bf9000">argc</font>, <font color="#38761d">char</font> *<font
color="#bf9000">argv</font>[])
{</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">using</font> <font
color="#38761d">MainTy</font> = <font
color="#38761d">int</font> (*)(<font color="#38761d">int</font>, <font
color="#38761d">char</font> *[]);</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#38761d">void</font> *<font
color="#bf9000">H</font> =
__orc_rt_macho_jit_dlopen(<font color="#6aa84f">"Main"</font>,
ORC_RT_RTLD_LAZY);</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">if</font> (!H) {</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> __orc_rt_log_error(__orc_rt_macho_jit_dlerror());</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">return</font> -1;</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> }</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">auto</font> *<font
color="#bf9000">Main</font> = <font
color="#45818e">reinterpret_cast</font><<font color="#38761d">MainTy</font>>(__orc_rt_macho_jit_dlsym(H, <font
color="#6aa84f">"main"</font>));</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">if</font> (!Main) {<br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> __orc_rt_log_error(__orc_rt_macho_jit_dlerror());</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">return</font> -1;</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> }</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#38761d">int</font> <font
color="#bf9000">Result</font> =
Main(argc,
argv);</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">if</font> (__orc_rt_macho_jit_dlclose(H)
== -1)</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> __orc_rt_log_error(__orc_rt_macho_jit_dlerror());</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">return</font> Result;</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace">}</font></div>
</div>
<div><br>
</div>
<div>The
functions __orc_rt_macho_jit_dlopen, __orc_rt_macho_jit_dlsym,
and __orc_rt_macho_jit_dlclose behave the same as their dlfcn.h
counterparts
(dlopen,
dlsym,
dlclose), but
operate on
JITDylibs
rather than
regular
dylibs. This
includes
running static
initializers
and
registering
with language
runtimes (e.g.
ObjC). </div>
<div><br>
</div>
<div>While we
could run
static
initializers
before (e.g.
via
LLJIT::runConstructors),
we had to
initiate this
from the JIT
process side,
which has two
significant
drawbacks: (1)
Extra RPC
round trips,
and (2) in the
out-of-process
case:
initializers
not running on
the executor
thread that
requested
them, since
that thread
will be
blocked
waiting for
its call to
return. Issue
(1) only
affects
performance,
but (2) can
affect
correctness if
the
initializers
modify thread
local values,
or interact
with locks or
threads.
Interacting
with threads
from
initializers
is generally
best avoided,
but
nonetheless is
done by
real-world
code, so we
want to
support it. By
using the
runtime we can
improve both
performance
and
correctness
(or at least
consistency
with current
behavior). </div>
<div><br>
</div>
<div>The
effect of this
is that we can
now load C++,
Objective-C
and Swift
programs in
the JIT and
expect them to
run correctly,
at least for
simple cases.
This works
regardless of
whether the
JIT'd code
runs
in-process or
out-of-process. To test all this I have integrated support for the
prototype
runtime into
llvm-jitlink.
You can demo
output from
this tool
below for two
simple input
programs: One
swift, one
C++. All of
this is MachO
specific at
the moment,
but provides a
template that
could be
easily re-used
to support
this on ELF
platforms, and
likely on COFF
platforms too.<br>
</div>
<div><br>
</div>
<div>While the
discussion on
where the
runtime should
live plays out
I will
continue
adding /
moving
functionality
to the
prototype
runtime. Next
up will be
eh-frame
registration
and resolver
functions
(both
currently in
OrcTargetProcess).
After that
I'll try to
tackle support
for native
MachO thread
local storage.</div>
<div><br>
</div>
<div>As
always:
Questions and
comments are
very welcome.</div>
<div><br>
</div>
<div>-- Lang.</div>
<div><br>
</div>
<div>
<div
style="color:rgb(0,0,0)">
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch % cat
foo.swift</font></div>
<div><font
face="monospace">class
MyClass {</font></div>
<div><font
face="monospace">
func foo() {</font></div>
<div><font
face="monospace">
print("foo")</font></div>
<div><font
face="monospace">
}</font></div>
<div><font
face="monospace">}</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">let
m = MyClass()</font></div>
<div><font
face="monospace">m.foo();</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
xcrun swiftc
-emit-object
-o foo.o
foo.swift
</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
-dlopen
/usr/lib/swift/libswiftCore.dylib
foo.o
</font></div>
<div><font
face="monospace">foo</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
-oop-executor
-dlopen
/usr/lib/swift/libswiftCore.dylib
foo.o</font></div>
<div><font
face="monospace">foo</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch % cat
inits.cpp </font></div>
<div><font
face="monospace">#include
<iostream></font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">class
Foo {</font></div>
<div><font
face="monospace">public:</font></div>
<div><font
face="monospace">
Foo() {
std::cout
<<
"Foo::Foo()\n";
}</font></div>
<div><font
face="monospace">
~Foo() {
std::cout
<<
"Foo::~Foo()\n";
}</font></div>
<div><font
face="monospace">
void foo() {
std::cout
<<
"Foo::foo()\n";
}</font></div>
<div><font
face="monospace">};</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">Foo
F;</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">int
main(int argc,
char *argv[])
{</font></div>
<div><font
face="monospace">
F.foo();</font></div>
<div><font
face="monospace">
return 0;</font></div>
<div><font
face="monospace">}</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
xcrun clang++
-c -o inits.o
inits.cpp</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
inits.o
</font></div>
<div><font
face="monospace">Foo::Foo()</font></div>
<div><font
face="monospace">Foo::foo()</font></div>
<div><font
face="monospace">Foo::~Foo()</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
-oop-executor
inits.o</font></div>
<div><font
face="monospace">Foo::Foo()</font></div>
<div><font
face="monospace">Foo::foo()</font></div>
<div><font
face="monospace">Foo::~Foo()</font></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<pre cols="72">--
<a href="https://flowcrypt.com/pub/stefan.graenitz@gmail.com" target="_blank" moz-do-not-send="true">https://flowcrypt.com/pub/stefan.graenitz@gmail.com</a></pre>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
<pre class="moz-signature" cols="72">--
<a class="moz-txt-link-freetext" href="https://flowcrypt.com/pub/stefan.graenitz@gmail.com">https://flowcrypt.com/pub/stefan.graenitz@gmail.com</a></pre>
</body>
</html>