<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lauro Moura</title>
    <description>The latest articles on DEV Community by Lauro Moura (@lauromoura).</description>
    <link>https://dev.to/lauromoura</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F192248%2F2bf504ff-d17e-41d7-9a7f-12ff706a0d17.jpg</url>
      <title>DEV Community: Lauro Moura</title>
      <link>https://dev.to/lauromoura</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lauromoura"/>
    <language>en</language>
    <item>
      <title>Using Breakpad to generate crash dumps with WPE WebKit</title>
      <dc:creator>Lauro Moura</dc:creator>
      <pubDate>Mon, 29 Aug 2022 03:57:36 +0000</pubDate>
      <link>https://dev.to/lauromoura/using-breakpad-to-generate-crash-dumps-with-wpe-webkit-5da8</link>
      <guid>https://dev.to/lauromoura/using-breakpad-to-generate-crash-dumps-with-wpe-webkit-5da8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction and BreakPad overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://chromium.googlesource.com/breakpad/breakpad/" rel="noopener noreferrer"&gt;Breakpad&lt;/a&gt; is a tool from Google that helps generate crash reports. From &lt;a href="https://chromium.googlesource.com/breakpad/breakpad/+/HEAD/docs/getting_started_with_breakpad.md" rel="noopener noreferrer"&gt;its description&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Breakpad is a library and tool suite that allows you to distribute an application to users with compiler-provided debugging information removed, record crashes in compact "minidump" files, send them back to your server, and produce C and C++ stack traces from these minidumps. Breakpad can also write minidumps on request for programs that have not crashed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It works by stripping the debug information from the executable and saving it into "symbol files." When a crash occurs or upon request, the Breakpad client library generates the crash information in these "minidumps." The Breakpad minidump processor combines these files with the symbol files and generates a human-readable stack trace. The following picture, also from Breakpad's documentation, describes this process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9js0r01f1aghw3ja5glr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9js0r01f1aghw3ja5glr.png" alt="Breakpad overview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://wpewebkit.org" rel="noopener noreferrer"&gt;WPE&lt;/a&gt;, Breakpad support was added initially for the &lt;a href="https://github.com/WebPlatformForEmbedded/WPEWebKit/tree/wpe-2.28" rel="noopener noreferrer"&gt;downstream 2.28 branch&lt;/a&gt; by &lt;a href="https://github.com/varumugam123" rel="noopener noreferrer"&gt;Vivek Arumugam&lt;/a&gt; and backported &lt;a href="https://github.com/WebKit/WebKit/pull/2893" rel="noopener noreferrer"&gt;upstream&lt;/a&gt;. It'll be available in the soon-to-be-released 2.38 version, and the WebKit Flatpak SDK bundles the Breakpad client library since late May 2022.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling Breakpad in WebKit
&lt;/h2&gt;

&lt;p&gt;As a developer feature, Breakpad support is disabled by default but can be enabled by passing &lt;code&gt;-DENABLE_BREAKPAD=1&lt;/code&gt; to cmake when building WebKit. Optionally, you can also set &lt;code&gt;-DBREAKPAD_MINIDUMP_DIR=&amp;lt;some path&amp;gt;&lt;/code&gt; to hardcode the path used by Breakpad to save the minidumps. If not set during build time, &lt;code&gt;BREAKPAD_MINIDUMP_DIR&lt;/code&gt; must be set as an environment variable pointing to a valid directory when running the application. If defined, this variable also overrides the path defined during the build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the symbols
&lt;/h2&gt;

&lt;p&gt;To generate the symbol files, Breakpad provides the &lt;code&gt;dump_syms&lt;/code&gt; tool. It takes a path to the executable/library and dumps to stdout the symbol information.&lt;/p&gt;

&lt;p&gt;Once generated, the symbol files must be laid out in a specific tree structure so &lt;code&gt;minidump_stackwalk&lt;/code&gt; can find them when merging with the crash information. The folder containing the symbol files must match a hash code generated for that specific binary. For example, in the case of the &lt;code&gt;libWPEWebKit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dump_syms WebKitBuild/WPE/Release/lib/libWPEWebKit-1.1.so &amp;gt; libWPEWebKit-1.1.so.0.sym
$ head -n 1 libWPEWebKit-1.1.so.0.sym
MODULE Linux x86_64 A2DA230C159B97DC00000000000000000 libWPEWebKit-1.1.so.0
$ mkdir -p ./symbols/libWPEWebKit-1.1.so.0/A2DA230C159B97DC00000000000000000
$ cp libWPEWebKit-1.1.so.0.sym ./symbols/libWPEWebKit-1.1.so.0/A2DA230C159B97DC00000000000000000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generating the crash log
&lt;/h2&gt;

&lt;p&gt;Besides the symbol files, we need a minidump file with the stack information, which can be generated in two ways. First, by asking Breakpad to create it. The other way is, well, when the application crashes :)&lt;/p&gt;

&lt;p&gt;To generate a minidump manually, you can either call &lt;code&gt;google_breakpad::WriteMiniDump(path, callback, context)&lt;/code&gt; or send one of the crashing signals Breakpad recognizes. The former is helpful to generate the dumps programmatically at specific points, while the signal approach might be helpful to inspect hanging processes. These are the signals Breakpad handles as crashing ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SIGSEGV&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SIGABRT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SIGFPE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SIGILL&lt;/code&gt; (Note: this is for illegal instruction, not the ordinary &lt;code&gt;SIGKILL&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SIGBUS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SIGTRAP&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, first we must run Cog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ BREAKPAD_MINIDUMP_DIR=/home/lauro/minidumps ./Tools/Scripts/run-minibrowser --wpe --release https://www.wpewebkit.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crashing the &lt;code&gt;WebProcess&lt;/code&gt; using &lt;code&gt;SIGTRAP&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ps aux | grep WebProcess
&amp;lt;SOME-PID&amp;gt; ... /app/webkit/.../WebProcess
$ kill -TRAP &amp;lt;SOME-PID&amp;gt;
$ ls /home/lauro/minidumps
5c2d93f2-6e9f-48cf-6f3972ac-b3619fa9.dmp
$ file ~/minidumps/5c2d93f2-6e9f-48cf-6f3972ac-b3619fa9.dmp
/home/lauro/minidumps/5c2d93f2-6e9f-48cf-6f3972ac-b3619fa9.dmp: Mini DuMP crash report, 13 streams, Thu Aug 25 20:29:11 2022, 0 type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In the current form, WebKit supports Breakpad dumps in the WebProcess and NetworkProcess, which WebKit spawns itself. The developer must manually add support for it in the UIProcess (the browser/application using WebKit). The exception handler should be installed as early as possible, and many programs might do some initialization before initializing WebKit itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Translating the crash log
&lt;/h2&gt;

&lt;p&gt;Once we have a &lt;code&gt;.dmp&lt;/code&gt; crash log and the symbol files, we can use &lt;code&gt;minidump_stackwalk&lt;/code&gt; to show the human-readable crash log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ minidump_stackwalk ~/minidumps/5c2d93f2-6e9f-48cf-6f3972ac-b3619fa9.dmp ./symbols/
&amp;lt;snip long header&amp;gt;
Operating system: Linux
                  0.0.0 Linux 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64
CPU: amd64
     family 23 model 113 stepping 0
     1 CPU

GPU: UNKNOWN

Crash reason:  SIGTRAP
Crash address: 0x3e800000000
Process uptime: not available

Thread 0 (crashed)
 0  libc.so.6 + 0xf71fd
    rax = 0xfffffffffffffffc   rdx = 0x0000000000000090
    rcx = 0x00007f6ae47d61fd   rbx = 0x00007f6ae4f0c2e0
    rsi = 0x0000000000000001   rdi = 0x000056187adbf6d0
    rbp = 0x00007fffa9268f10   rsp = 0x00007fffa9268ef0
     r8 = 0x0000000000000000    r9 = 0x00007f6ae4fdc2c0
    r10 = 0x00007fffa9333080   r11 = 0x0000000000000293
    r12 = 0x0000000000000001   r13 = 0x00007fffa9268f34
    r14 = 0x0000000000000090   r15 = 0x000056187ade7aa0
    rip = 0x00007f6ae47d61fd
    Found by: given as instruction pointer in context
 1  libglib-2.0.so.0 + 0x585ce
    rsp = 0x00007fffa9268f20   rip = 0x00007f6ae4efc5ce
    Found by: stack scanning
 2  libglib-2.0.so.0 + 0x58943
    rsp = 0x00007fffa9268f80   rip = 0x00007f6ae4efc943
    Found by: stack scanning
 3  libWPEWebKit-1.1.so.0!WTF::RunLoop::run() + 0x120
    rsp = 0x00007fffa9268fa0   rip = 0x00007f6ae8923180
    Found by: stack scanning
 4  libWPEWebKit-1.1.so.0!WebKit::WebProcessMain(int, char**) + 0x11e
    rbx = 0x000056187a5428d0   rbp = 0x0000000000000003
    rsp = 0x00007fffa9268fd0   r12 = 0x00007fffa9269148
    rip = 0x00007f6ae74719fe
    Found by: call frame info
&amp;lt;snip remaining trace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;This article briefly overviews enabling and using Breakpad to generate crash dumps. In a future article, we'll cover using Breakpad to get crashdumps while running WPE on embedded boards like RaspberryPis.&lt;/p&gt;

&lt;p&gt;o/&lt;/p&gt;

</description>
      <category>wpewebkit</category>
      <category>webkit</category>
      <category>breakpad</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>WebAssembly Runtimes - WASI and Wasmtime</title>
      <dc:creator>Lauro Moura</dc:creator>
      <pubDate>Fri, 18 Oct 2019 02:54:32 +0000</pubDate>
      <link>https://dev.to/lauromoura/webassembly-runtimes-wasi-and-wasmtime-1pl7</link>
      <guid>https://dev.to/lauromoura/webassembly-runtimes-wasi-and-wasmtime-1pl7</guid>
      <description>&lt;p&gt;After a while (and a &lt;a href="https://www.enlightenment.org/news/efl-1.23.0"&gt;release&lt;/a&gt; at work), here we are again. To continue the series, we will take a quick look at wasmtime and WASI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wasmtime
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/CraneStation/wasmtime"&gt;Wasmtime&lt;/a&gt; is a "standalone wasm-only runtime for WebAssembly using the &lt;a href="https://github.com/CraneStation/cranelift"&gt;Cranelift&lt;/a&gt; JIT". It is part of CraneStation, an "umbrella" project for compiler tools where Mozilla is one (if not the main) parties involved.&lt;/p&gt;

&lt;p&gt;The Cranelift JIT is kinda similar to LLVM. Other runtimes like Wasmer - which we will talk about in a future post can switch between Cranelift and LLVM as the backend to generate the code.&lt;/p&gt;

&lt;p&gt;But before we go into more wasmtime details, it is important to talk about how we will be interacting with these runtimes.&lt;/p&gt;

&lt;h2&gt;
  
  
  WASI
&lt;/h2&gt;

&lt;p&gt;As I said in the first post, portability is an important target of WebAssembly. Not only about running a given &lt;code&gt;.wasm&lt;/code&gt; file in any place, but also about WebAssembly providing a - as much as possible - portable interface to build programs on top of it. This led to the development of the WebAssembly System Interface - WASI (&lt;a href="https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/"&gt;here is a great post&lt;/a&gt; by the great Lin Clark about what is a system interface and why, what, how and who is developing one for WebAssembly).&lt;/p&gt;

&lt;p&gt;While system interfaces like POSIX served us well for decades, the challenges of a truly universal system interface in the context of WASM are more strict. This happens because, like a webpage in the browser, you could be running WASM programs from any source and this demands a new approach to security.&lt;/p&gt;

&lt;p&gt;WASI thus is being developed with a capability-oriented approach. Instead of the POSIX way of a program inheriting all access rights of the user, in WASI it behaves kinda like installing an app on your phone. Each time a WASM program tries to access a restricted resource, the runtime checks if the user granted access to that resource. We will see more details later in a WASI example.&lt;/p&gt;

&lt;p&gt;To begin, we need to install the &lt;code&gt;wasi-sdk&lt;/code&gt; that will make it easier for us to create WASI-ready wasm files. It is a clang-based toolchain that is also part of the CraneStation initiative. There are packages &lt;a href="https://github.com/CraneStation/wasi-sdk/releases"&gt;available in Github&lt;/a&gt;. In my Ubuntu install, the executables were installed to &lt;code&gt;/opt/wasi-sdk/bin&lt;/code&gt;. The tutorial for wasi-sdk is &lt;a href="https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-tutorial.md"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting wasmtime
&lt;/h2&gt;

&lt;p&gt;The easiest way to get wasmtime is by running their installer with the command below. It will install the runtime to &lt;code&gt;$HOME/.wasmtime/bin&lt;/code&gt; and automatically set up the profile scripts to add it to the &lt;code&gt;$PATH&lt;/code&gt; when you open a new terminal. Don't forget to re-add the wasi-sdk bin folder to &lt;code&gt;PATH&lt;/code&gt; in this new terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://wasmtime.dev/install.sh -sSf | bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As expected a hello world in wasm/wasi is the same as in the desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To compile, you use the &lt;code&gt;wasi-sdk&lt;/code&gt; &lt;code&gt;clang&lt;/code&gt; just like you would with a regular C compiler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ clang hello.c -o hello.wasm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And to run, just call the wasmtime executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wasmtime hello.wasm
Hello, World
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. You should have the message printed in your terminal. WASI allows the standard output and error descriptors (&lt;code&gt;stdout&lt;/code&gt; and &lt;code&gt;stderr&lt;/code&gt;) to be freely accessed.&lt;/p&gt;

&lt;p&gt;Now, what if we tried to access files? For example, let's implement a &lt;code&gt;cat&lt;/code&gt; program. It just reads a file and prints it to the terminal. Save the program below to a file named &lt;code&gt;cat.c&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"usage: %s &amp;lt;input file&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BUFSIZ&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"error opening file %s: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;strerror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errno&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BUFSIZ&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%.*s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"read error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strerror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errno&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Like the previous example, compile...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ clang cat.c -o cat.wasm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And run...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wasmtime cat.wasm hello.c
error opening file hello.c: Capabilities insufficient
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ooops. Looks like reading files is a restricted operation. Which makes sense, given files could hold sensitive information. So, how do we grant access to them? With wasmtime, just use the option &lt;code&gt;--dir=&amp;lt;path&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wasmtime --dir=. cat.wasm hello.c
#include &amp;lt;stdio.h&amp;gt;...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This was just a gentle introduction to using &lt;code&gt;wasi-sdk&lt;/code&gt; and &lt;code&gt;wasmtime&lt;/code&gt; to play with WASI-based Webassembly programs. In the next post, we will see how to embed wasmtime into other programs and do more complex interactions.&lt;/p&gt;

</description>
      <category>webassembly</category>
    </item>
    <item>
      <title>WebAssembly runtimes overview - intro</title>
      <dc:creator>Lauro Moura</dc:creator>
      <pubDate>Sat, 28 Sep 2019 03:30:14 +0000</pubDate>
      <link>https://dev.to/lauromoura/webassembly-runtimes-overview-intro-3ch</link>
      <guid>https://dev.to/lauromoura/webassembly-runtimes-overview-intro-3ch</guid>
      <description>&lt;h2&gt;
  
  
  Write once, run anywhere - the Holy Grail of Portability
&lt;/h2&gt;

&lt;p&gt;Since long time ago, one of the holy grails of computing is portability. In the 90's Java promised, "write once, run anywhere (WORA)". But while you could do that with simple programs, you probably would quickly start fighting the details of the different OS's, devices, versions, you had to run. WORA then quickly becomes WODE (Write Once, Debug Everywhere). Another issue is that you would end up depending on the JVM being available on the target and having to program mainly with just Java or other JVM languages like - at the time - Groovy, JRuby, etc.&lt;/p&gt;

&lt;p&gt;Fast forward to the 2010s, and another "Java" - I know, I know - is what had got us the closest to the WORA world so far. Javascript slowly overcame some hurdles from &lt;a href="https://www.destroyallsoftware.com/talks/wat"&gt;being something like a joke&lt;/a&gt; to become a - slightly more - &lt;a href="https://en.wikipedia.org/wiki/ECMAScript"&gt;respectable language&lt;/a&gt; and &lt;em&gt;the&lt;/em&gt; universal programming language of the Web.&lt;/p&gt;

&lt;p&gt;But we are still kinda tied to a single language. Transpilers try to mitigate this issue but you could need to develop systems for the Web in other programming languages completely different from JavaScript, to reuse existing components, for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter WebAssembly
&lt;/h2&gt;

&lt;p&gt;All this led to the creation of &lt;a href="https://webassembly.org/"&gt;WebAssembly&lt;/a&gt;. It is a compact binary format aimed at fast execution and small binaries sizes. Like Javascript, it runs sandboxed, providing security features that allow running code from the Web without - mostly - putting your system at risk. It already allows running C, C++, Rust and many other languages (thanks, LVVM) "anywhere".&lt;/p&gt;

&lt;p&gt;The quotes are because, unfortunately, there is still the issue of dealing with the details of where you run. To try to reduce this task, there is an ongoing work to standardize the basic operations in a system interface (&lt;a href="https://wasi.dev/"&gt;WASI&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what now?
&lt;/h2&gt;

&lt;p&gt;Sometimes you need portability without all the bloat of HTML/CSS/JS parsing/rendering/etc. This led to the creation of platforms like Docker, where you could reuse the software from practically any language and run anywhere you had the docker engine running.&lt;/p&gt;

&lt;p&gt;While the main showcase of WebAssembly initially was the web browser, there is new exciting work on using it outside it too. Like Solomon Hykes (of docker itself) &lt;a href="https://twitter.com/solomonstre/status/1111004913222324225?lang=en"&gt;said&lt;/a&gt;:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--sSaEOM1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1148186197296070657/ow43KBGn_normal.jpg" alt="Solomon Hykes profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Solomon Hykes
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @solomonstre
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      If WASM+WASI existed in 2008, we wouldn't have needed to created Docker. That's how important it is. Webassembly on the server is the future of computing. A standardized system interface was the missing link. Let's hope WASI is up to the task! &lt;a href="https://t.co/wnXQg4kwa4"&gt;twitter.com/linclark/statu…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      20:39 PM - 27 Mar 2019
    &lt;/div&gt;

      &lt;div class="ltag__twitter-tweet__quote"&gt;
        &lt;div class="ltag__twitter-tweet__quote__header"&gt;
          &lt;span class="ltag__twitter-tweet__quote__header__name"&gt;
            Lin Clark
          &lt;/span&gt;
          @linclark
        &lt;/div&gt;
        WebAssembly running outside the web has a huge future. And that future gets one giant leap closer today with...

📢 Announcing WASI: A system interface for running WebAssembly outside the web (and inside it too)

https://t.co/HdEAZAyqYu
      &lt;/div&gt;

    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1111004913222324225" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1111004913222324225" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      694
      &lt;a href="https://twitter.com/intent/like?tweet_id=1111004913222324225" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      1691
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;This series of posts is intended to be a quick overview of some of the main tools that allow running WebAssembly &lt;a href="https://webassembly.org/docs/non-web/"&gt;outside the browser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The initial list of runtimes we'll be checking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/wasmerio/wasmer"&gt;Wasmer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CraneStation/wasmtime"&gt;Wasmtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fastly/lucet"&gt;Lucet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/intel/wasm-micro-runtime"&gt;Wasm micro runtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://v8.dev/blog/v8-release-78"&gt;Wee8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll cover the scenarios each runtime tries to address. From running standalone wasm binaries to embedding the runtime into an actual application.&lt;/p&gt;

&lt;p&gt;A more extensive list of WebAssembly runtimes can be &lt;a href="https://github.com/appcypher/awesome-wasm-runtimes"&gt;found on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, on to the runtimes.&lt;/p&gt;

</description>
      <category>webassembly</category>
    </item>
    <item>
      <title>Generic extension methods ambiguity in C#</title>
      <dc:creator>Lauro Moura</dc:creator>
      <pubDate>Thu, 15 Aug 2019 19:33:59 +0000</pubDate>
      <link>https://dev.to/lauromoura/generic-extension-methods-ambiguity-in-c-4c7f</link>
      <guid>https://dev.to/lauromoura/generic-extension-methods-ambiguity-in-c-4c7f</guid>
      <description>&lt;p&gt;As part of &lt;a href="http://expertisesolutions.com.br/"&gt;our&lt;/a&gt; work in the &lt;a href="https://www.enlightenment.org/develop/tutorials/csharp/start.md"&gt;C# bindings for EFL&lt;/a&gt;, recently I stumbled upon a kinda non-obvious issue using C#'s extension methods.&lt;/p&gt;

&lt;p&gt;While implementing support for the MVVM factories, extension methods on the factories were generated so you could bind properties from the model to properties of the objects that would be created. For example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Efl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ListItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"modelProperty"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The factory will create instances of &lt;code&gt;ListItem&lt;/code&gt; and upon instantiating them, will bind the &lt;code&gt;modelProperty&lt;/code&gt; of the associated model element to the &lt;code&gt;Text&lt;/code&gt; property of the newly created &lt;code&gt;ListItem&lt;/code&gt; so whenever the model changes, the created widget shows the updated value.&lt;/p&gt;

&lt;p&gt;To make these properties available, the following extension methods were generated for each property in each "wrappable" class (i.e. class that could go inside a factory):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// Extensions for ListItem&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Bindable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;ItemFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fac&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ListItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;/// Extensions for GridItem&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Bindable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;ItemFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fac&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GridItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So far, so good. But the code above has an important limitation. The &lt;code&gt;where&lt;/code&gt; constraint &lt;a href="https://blogs.msdn.microsoft.com/ericlippert/2009/12/10/constraints-are-not-part-of-the-signature/"&gt;is not part of the signature&lt;/a&gt;. And if we tried to call one of these extension methods that have the same name but two different &lt;code&gt;T&lt;/code&gt;s, ambiguity arises and the compilation will fail with &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0121"&gt;CS0121&lt;/a&gt; &lt;code&gt;The call is ambiguous between the following methods or properties:...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The solution we used (thank god &lt;a href="https://stackoverflow.com/a/14624904/347889"&gt;Stack Overflow&lt;/a&gt;) was to add an extra default parameter dependent on the T and the type of the constraint. This would allow selecting an unique method based on the generic type parameter.&lt;/p&gt;

&lt;p&gt;Using said method, we could do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// Magic tag to select the unique method&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MagicTag&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TInherited&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TInherited&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;/// Extensions for ListItem&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Bindable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;ItemFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fac&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MagicTag&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ListItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ListItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;/// Extensions for GridItem&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Bindable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;ItemFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fac&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MagicTag&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GridItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GridItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This successfully gives enough info to the compiler select the single correct method without ambiguity &lt;em&gt;in most cases&lt;/em&gt;. The exception is where we would have two methods with the same name and &lt;code&gt;TInherited&lt;/code&gt; &lt;strong&gt;is actually a derived class&lt;/strong&gt; from &lt;code&gt;TBase&lt;/code&gt;. But in our case the code generator avoids generating repeated methods for inherited classes, bypassing this issue.&lt;/p&gt;

&lt;p&gt;o/&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>generics</category>
    </item>
  </channel>
</rss>
