<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds/atom-style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://657.life/en/</id>
    <title>657's Life</title>
    <updated>2025-09-30T02:07:50.433Z</updated>
    <generator>Astro-Theme-Retypeset with Feed for Node.js</generator>
    <author>
        <name>657</name>
        <uri>https://657.life</uri>
    </author>
    <link rel="alternate" href="https://657.life/en/"/>
    <link rel="self" href="https://657.life/en/atom.xml"/>
    <subtitle>This is my personal website, where I record the sky I see from the bottom of the well.</subtitle>
    <rights>Copyright © 2025 657</rights>
    <entry>
        <title type="html"><![CDATA[Mungstern Coffee]]></title>
        <id>https://657.life/en/posts/mungstern-coffee/</id>
        <link href="https://657.life/en/posts/mungstern-coffee/"/>
        <updated>2024-04-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Mungstern is most famous for its local coffee. Unlike ordinary coffee, it is not made from coffee beans. Instead, the people of Mungstern use the seeds of papa grass, a plant that grows only in this region, to make Mungstern coffee.]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>[!NOTE]
This is a practice piece; all content is fictional.</p>
<p>This article was translated by ChatGPT.</p>
</blockquote>
<p>Mungstern is most famous for its local coffee. Unlike ordinary coffee, it is not made from coffee beans. Instead, the people of Mungstern use the seeds of papa grass, a plant that grows only in this region, to make Mungstern coffee.</p>
<p>Papa grass looks no different from common roadside weeds, but its seeds are quite unusual: they are blue in color and shaped much like sunflower seeds. Papa grass does not bloom; its seeds grow from the tips of its stems and leaves. In March, papa grass sprouts. By May, tiny blue dots begin to appear at the tips of the leaves. Another month later, the seeds ripen, and the plant’s slender, soft stems bend under the seeds’ weight until the seeds touch the ground. Finally, in August, the seeds detach from the plant and begin to put down roots, drawing in the nutrients they will need for the next sprouting season.</p>
<p>The ancestors of the Mungstern people discovered that freshly detached seeds carried a faint fragrance—at first like lemon, then, upon closer sniffing, like osmanthus, and after a while, the scent turned into that of pine wood. Adventurous Mungsterners tried drying the seeds, grinding them, and steeping them in hot water. The resulting liquid was also blue—deeper than the sky, yet brighter than the sea. This freshly steeped papa seed infusion smelled of fresh grass, tasted slightly bitter with a hint of tartness, but left a lingering sweetness on the palate. This curious taste experience made papa juice (as it was originally called) popular among the Mungstern people.</p>
<p>One day, a Mungsterner had a bold idea: what if the seeds were roasted before grinding? He tried it—and the flavor changed dramatically. The papa juice became smoother, its bitterness deepened, the tartness vanished, and the final sweetness grew richer, like the last moment of chocolate melting on the tongue. The color changed, too—the roasted-seed infusion turned a light brown, somewhat like a latte.</p>
<p>In the 1960s, Mungstern was discovered by a German expedition team. Upon returning home, they published their travel logs, and for the first time, the Mungstern people became known to the outside world. Among the entries was a description of a “drink with a marvelous taste,” which caught the attention of the famous barista Mr. Edwin. The month after the expedition returned, Edwin set out for Mungstern; a month later, he came back with about 15 pounds of papa grass seeds and held a tasting event dedicated to papa juice. It was there that he named it Mungstern coffee. Although it was not made from coffee beans, its appearance, flavor, and preparation method closely resembled coffee—and it had an even stronger energizing effect along with a uniquely complex taste. Calling papa juice “coffee” was therefore not entirely wrong (though in truth, it was mostly Edwin’s passion for coffee that inspired the name).</p>
<p>Thus, Mungstern coffee made its official debut to the world.</p>
]]></content>
        <author>
            <name>657</name>
            <uri>https://657.life</uri>
        </author>
        <published>2024-04-23T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to Use QuickJS in Flutter]]></title>
        <id>https://657.life/en/posts/how-to-use-quick-js-in-flutter/</id>
        <link href="https://657.life/en/posts/how-to-use-quick-js-in-flutter/"/>
        <updated>2023-11-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article explains how to embed QuickJS in Flutter, including how to build runtime libraries for Windows and Android, and how to execute JavaScript code via QuickJS.]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>[!Note]
This article was translated by ChatGPT.</p>
</blockquote>
<h2>1. Introduction to QuickJS</h2>
<p>The following excerpt is from the <a href="https://bellard.org/quickjs/">QuickJS official website</a>.</p>
<p>QuickJS is a small and embeddable JavaScript engine. It supports the ES2020 specification, including modules, async generators, proxies, and BigInt. It optionally supports mathematical extensions such as BigDecimal, BigFloat, and operator overloading.</p>
<p>Key features:</p>
<ul>
<li><strong>Compact and embeddable</strong> – only a few C source files, no external dependencies. For a simple “Hello World” program, the x86 code size is only 210 KiB.</li>
<li><strong>Fast interpreter with extremely short startup time</strong> – On a single desktop CPU core, it can run 75,000 ECMAScript tests from the Test262 suite in around 100 seconds. A runtime instance’s full lifecycle takes under 300 microseconds.</li>
<li><strong>Near-complete ES2020 support</strong> – includes modules, async generators, and full Annex B support for legacy web compatibility.</li>
<li><strong>High compliance with Test262</strong> – when ES2020 features are enabled, QuickJS passes close to 100% of the ECMAScript test suite.</li>
<li><strong>AOT compilation</strong> – JavaScript source can be compiled into standalone executables with no external dependencies.</li>
<li><strong>Deterministic garbage collection</strong> – uses reference counting with cycle removal to minimize memory usage.</li>
<li><strong>Math extensions</strong> – BigDecimal, BigFloat, operator overloading, bigint mode, math mode.</li>
<li><strong>Small built-in standard library</strong> – basic C library wrappers.</li>
<li><strong>CLI interpreter</strong> – implemented in JavaScript with syntax highlighting support.</li>
</ul>
<h2>2. How Dart Interacts with C</h2>
<p>Flutter apps are written in Dart. To interface with C libraries, Dart uses the <code>dart:ffi</code> library.</p>
<p><code>dart:ffi</code> is designed for calling native C APIs. <strong>FFI</strong> stands for <a href="https://en.wikipedia.org/wiki/Foreign_function_interface">Foreign Function Interface</a>. For detailed usage, refer to the <a href="https://dart.dev/guides/libraries/c-interop">official documentation</a>.</p>
<h2>3. Building QuickJS for Different Platforms</h2>
<p>Since Flutter is cross-platform, you need to compile QuickJS into platform-specific dynamic libraries.</p>
<ul>
<li>On Windows: build a <code>.dll</code> file.</li>
<li>On Linux/Android: build a <code>.so</code> file.</li>
</ul>
<p>This section focuses on building for <strong>Windows</strong> and <strong>Android</strong> (Linux builds are simpler and omitted).</p>
<h3>3.1 Building QuickJS for Windows</h3>
<ol>
<li>Install <a href="https://www.msys2.org/">MSYS2</a> – compilation requires the MINGW toolchain inside MSYS2.</li>
<li>Launch the <strong>MINGW64</strong> terminal (or MINGW32 for 32-bit) and install the toolchain:</li>
</ol>
<ul>
<li><strong>For 64-bit builds</strong>:</li>
</ul>
<pre><code>pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-dlfcn
echo "#! /bin/sh" &gt; /mingw64/bin/make
echo "\"mingw32-make\" \"\$@\"" &gt;&gt; /mingw64/bin/make
</code></pre>
<ul>
<li><strong>For 32-bit builds</strong>:</li>
</ul>
<pre><code>pacman -S mingw-w64-i686-gcc mingw-w64-i686-make mingw-w64-i686-dlfcn
echo "#! /bin/sh" &gt; /mingw32/bin/make
echo "\"mingw32-make\" \"\$@\"" &gt;&gt; /mingw32/bin/make
</code></pre>
<ol>
<li>Clone the QuickJS repository:</li>
</ol>
<pre><code>git clone https://github.com/bellard/quickjs.git
</code></pre>
<ol>
<li>Compile QuickJS:</li>
</ol>
<pre><code>cd quickjs &amp;&amp; make
</code></pre>
<ol>
<li>After <code>make</code> finishes, you’ll get <code>libquickjs.a</code>. Create the DLL:</li>
</ol>
<pre><code>gcc -shared -o libquickjs.dll -static -s -Wl,--whole-archive libquickjs.a -lm -Wl,--no-whole-archive
</code></pre>
<h3>3.2 Building QuickJS for Android</h3>
<p>For Android, you’ll need a <code>CMakeLists.txt</code> to compile the C code:</p>
<pre><code>cmake_minimum_required(VERSION 3.4.1)

project(quickjs LANGUAGES C)

include_directories(quickjs)

set(QUICK_JS_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../quickjs)

set(
  SOURCE_DIR
  ${QUICK_JS_DIR}/cutils.c
  ${QUICK_JS_DIR}/libbf.c
  ${QUICK_JS_DIR}/libregexp.c
  ${QUICK_JS_DIR}/libunicode.c
  ${QUICK_JS_DIR}/quickjs.c
  ${QUICK_JS_DIR}/quickjs-libc.c
)

file(STRINGS "${QUICK_JS_DIR}/VERSION" CONFIG_VERSION)

add_definitions(-DCONFIG_VERSION="${CONFIG_VERSION}")
add_definitions(-DCONFIG_BIGNUM)
add_definitions(-D_GNU_SOURCE)
add_definitions(-DCONFIG_CC="gcc")
add_definitions(-DCONFIG_PREFIX="/usr/local")

add_library(
  ${PROJECT_NAME}
  SHARED
  ${SOURCE_DIR}
)

target_include_directories(${PROJECT_NAME} PUBLIC .)
</code></pre>
<p>Place this file under <code>android/src/main/cpp</code> in your Flutter project, and put the QuickJS source in the project root.
When building for Android, Flutter will compile and package <code>libquickjs.so</code> automatically.</p>
<p>For details, see the <a href="https://developer.android.com/studio/projects/add-native-code">official guide on adding C/C++ code to Android</a>.</p>
<h2>4. Generating Bindings with ffigen</h2>
<p>To call C/C++ functions from Dart, you must first <strong>declare</strong> them in Dart.
For example, given a C function:</p>
<pre><code>int add(int a, int b) {
  return a + b;
}
</code></pre>
<p>You’d declare it in Dart as:</p>
<pre><code>import 'dart:ffi' as ffi;

final nativeAddFunc =
  dynamicLibrary.lookup&lt;ffi.NativeFunction&lt;ffi.Int Function(ffi.Int, ffi.Int)&gt;&gt;('add');
</code></pre>
<blockquote>
<p><code>dynamicLibrary.lookup</code> finds a C function by its name, return type, and parameter types.</p>
</blockquote>
<p>Declaring foreign functions in another language is known as <strong>language bindings</strong>.</p>
<p>Manually declaring every QuickJS function is tedious. Fortunately, Dart provides the <code>ffigen</code> package, which <strong>automatically generates bindings from header files</strong>.</p>
<p>Steps to generate QuickJS bindings:</p>
<ol>
<li>Install ffigen:</li>
</ol>
<pre><code>flutter pub add ffigen
</code></pre>
<ol>
<li>Add configuration in <code>pubspec.yaml</code>:</li>
</ol>
<pre><code>ffigen:
  name: QuickJSBindings
  description: generate bindings for quick js
  output: lib/bindings.dart
  headers:
    entry-points:
      - quickjs/quickjs.h
      - quickjs/quickjs-libc.h
</code></pre>
<ol>
<li>Run:</li>
</ol>
<pre><code>dart run ffigen
</code></pre>
<h2>5. Using QuickJS</h2>
<ol>
<li>Open the QuickJS dynamic library:</li>
</ol>
<pre><code>final _lib = DynamicLibrary.open(libquickjs);
final _ = QuickJSBindings(_lib);
</code></pre>
<ol>
<li>Create a <code>JSRuntime</code> and <code>JSContext</code>:</li>
</ol>
<pre><code>final _runtime = _.JS_NewRuntime();
final _context = _.JS_NewContext(_runtime);
</code></pre>
<ol>
<li>Execute JavaScript with <code>JS_Eval</code>:</li>
</ol>
<pre><code>const flag = JS_EVAL_FLAG_STRICT;
final input = code.toNativeUtf8().cast&lt;Char&gt;();
final name = filename.toNativeUtf8().cast&lt;Char&gt;();
final inputLen = _getPtrCharLen(input);
final jsValue = _.JS_Eval(_context, input, inputLen, name, flag);
calloc.free(input);
calloc.free(name);
final result = _js2Dart(_context, jsValue);
_jsStdLoop(_context);
_jsFreeValue(_context, jsValue);
if (result is Exception) {
  throw ret;
}
</code></pre>
<p>That’s the basic usage. Handling promises, implementing event loops, and other advanced topics are beyond the scope of this introductory article.</p>
<h2>References</h2>
<ul>
<li><a href="https://github.com/abner/flutter_js">A JavaScript engine for Flutter using QuickJS on Android and JavaScriptCore on iOS</a></li>
<li><a href="https://github.com/ekibun/flutter_qjs">A QuickJS engine for Flutter</a></li>
<li><a href="https://github.com/mengmo/QuickJS-Windows-Build">Build QuickJS on Windows</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/623863082">How to compile and use QuickJS on Windows (Chinese)</a></li>
</ul>
]]></content>
        <author>
            <name>657</name>
            <uri>https://657.life</uri>
        </author>
        <published>2023-11-02T00:00:00.000Z</published>
    </entry>
</feed>