Skip to content

Releases: confh/Tiny

Tiny v0.2.9 - Observer Telemetry, Dynamic VMs, and Interface Implementations

Choose a tag to compare

@confh confh released this 29 Jun 12:38

This release adds support for class interface implementations, compile-time interface verification, a live process telemetry and control library (observer), in-process compilation and nested VM instantiation (runtime), window management controls for WebView desktop apps, and developer watch capabilities.

Language & VM Changes

  • Interface Implementation Support: Classes can now explicitly declare implementation of one or more interfaces using the implements keyword. The compiler and semantic analyzer validate that the class implements all fields and methods defined by the interface.
    interface Greeter {
        greet: function(string)
    }
    
    class Human implements Greeter {
        fn greet(name: string): string {
            return `Hello, ${name}`
        }
    }
  • Compile-time Interface Verification: Improved the compiler's type checker to verify class compatibility against expected interface parameters, allowing class instances to be passed to functions or slots expecting implemented interfaces.
  • Dynamic VM Nesting: Added the ability to instantiate, control, and run isolated child Tiny VMs dynamically from within Tiny code using runtime.newVM. Child VMs can be configured with custom arguments, JIT compilation control, isolated standard library limitations, and custom global variables.
    import std "runtime"
    
    const child = runtime.newVM({
        isolated: true,
        allowedStdlib: { "io": true },
        globals: { "tag": "child-vm" }
    })
  • Host-to-VM Function Exposure: Host VMs can now register callbacks and expose functions to child VMs using runtime.VM.exposeFunction.
  • In-Process Compilation: Added runtime.compileSource and runtime.compileFile to compile Tiny source code directly to bytecode at runtime.
    import std "runtime"
    
    const code = `
        export fn calculate(a: number, b: number): number {
            return a + b
        }
    `
    
    const bytecode = runtime.compileSource(code) // returns bytecode as a buffer
    child.loadBytecode(bytecode)
    const result = child.call("calculate", [10, 20]) // returns 30
  • WebView Window Controls: Added support for frameless windows, showing/hiding windows, drag and resize operations, window minimization, maximization, restoration, and programmatically closing windows.

Tooling & CLI Changes

  • Watch Mode: Added the watch command (tiny watch or tiny --watch) to monitor a source program and all of its imported file dependencies for changes. The command clears the screen and restarts the program upon file edits.
  • Executable Icon Customization: Added the --icon flag to tiny pack and tiny dist to set a custom .ico file icon for Windows executables.
  • Runtimes Auto-Update: Updated tiny update to check the local runtimes directory ($HOME/.tiny/runtimes) and update each cached target runtime binary to match the latest compiler release.

LSP Changes

  • Multiline String & Comment Filtering: Rewrote string and comment boundary resolution to run a document-wide scanner. Unused inlay hints, diagnostics, hovers, implementation lookups, and auto-completions are now correctly ignored inside multiline string literals (backticks) and comments.

Standard Library Modules

  • Observer (Telemetry): Added the observer standard library module. It starts a local telemetry HTTP endpoint exposing memory statistics, task pools, variables, functions, and events, allowing remote control of the running VM.
    import std "observer"
    
    observer.start({ port: 4040, password: "tiny" })
    observer.status("processing tasks")
    observer.event("job.started", "Task queue initiated")
  • Telemetry Dashboard App: Added the observer developer application under observer/src/main.tiny, which uses ui WebViews to connect to the observer HTTP endpoint and visualize VM telemetry.

Installation and Downloads

To install Tiny, download the compiler binary for your specific operating system:

  • Windows: Download tiny_windows_amd64.exe
  • Linux: Download tiny_linux_amd64 for amd64 or tiny_linux_arm64 for arm64
  • macOS (Apple Silicon): Download tiny_darwin_arm64

Note: The tiny_runtime_* assets listed in the releases page are managed automatically by the compiler during the pack and dist commands. You do not need to download them manually.

Tiny v0.2.8 - Implicit Null Initialization and LSP Overhaul

Choose a tag to compare

@confh confh released this 22 Jun 12:44

This release adds implicit null initialization for variables and fields, restricts imports to exported symbols only, and rewrites the LSP's symbol analysis to use AST-based indexing instead of regex scanning.

Language Changes

  • Implicit Null Initialization: Variables and fields can now be declared without an initializer. let x; is equivalent to let x = null;. Class fields follow the same rule, except const fields which still require an explicit initializer.
  • Function Stub Declarations: Functions can now have their bodies omitted with a semicolon, allowing forward-declaration style stubs.
  • Multiple Defer Statements: The restriction on a single defer per function scope has been removed. Multiple defer statements are now allowed.
  • Enum Match Safety: Pattern matching on enums now validates that the value is an object before inspecting enum tags, preventing incorrect matches on non-object values.

Compiler Changes

  • Semantic Error Pre-check: The compiler now runs semantic analysis before bytecode generation. Errors such as undefined variables and type mismatches are caught and reported upfront instead of silently producing broken bytecode.
  • Target Normalization from Config: The pack and dist commands now read the target field from tiny.json and normalize it correctly. Previously, the config target was sometimes ignored when a CLI target was not provided.

LSP Changes

  • AST-Based Symbol Indexing: The language server now builds its symbol index directly from the parsed AST when available, replacing the previous regex-based line scanning. This improves accuracy for nested classes, enums, interfaces, namespaces, and destructured variables.
  • Private Import Filtering: Symbols not exported from imported files are now hidden from completions, hover, signature help, and document symbols. This prevents internal implementation details from leaking into the editor.
  • Type Reference Tracking: Symbols now carry structured TypeRef information instead of plain strings, improving type display in inlay hints and completion items. Class, interface, and enum prefixes are stripped from inlay hint labels.
  • Return Type Inference: Function return types are now inferred from the function body when not explicitly annotated, using analysis of all return statements.
  • Enum Member Positions: Enum member symbols now track their actual line and column positions from the source text rather than defaulting to the enum declaration line.
  • Union Type Callback Resolution: Callback parameter type resolution now correctly handles union types, extracting function signatures from individual union members.

Standard Library Stubs

  • All standard library stubs have been updated to remove empty function bodies {} from declarations. Method signatures now end at the return type, matching the new parser support for stub declarations.
  • HTTP server route handlers now specify their callback parameter types (e.g., function(RequestObject) instead of plain function).

Error Formatting

  • Compiler and runtime errors are now colorized. File paths, line numbers, column numbers, error kinds, and stack traces are each styled with distinct colors for easier readability.
  • Stack trace frames show function names in a distinct color with file and line information highlighted.

Installation and Downloads

To install Tiny, download the compiler binary for your specific operating system:

  • Windows: Download tiny_windows_amd64.exe
  • Linux: Download tiny_linux_amd64 for amd64 or tiny_linux_arm64 for arm64
  • macOS (Apple Silicon): Download tiny_darwin_arm64

Note: The tiny_runtime_* assets listed in the releases page are managed automatically by the compiler during the pack and dist commands. You do not need to download them manually.

Tiny v0.2.7 - Dynamic Runtime Downloading and Binary Size Reduction

Choose a tag to compare

@confh confh released this 21 Jun 14:43

This release introduces dynamic runtime downloading, significantly reducing the compiler's binary size.

Compiler and Toolchain Changes

  • Dynamic Runtime Caching: The compiler no longer embeds target platform runtimes inside its own binary. Runtimes are now cached locally in the ~/.tiny/runtimes folder (and equivalent on Windows) when first required.
  • On-Demand Runtime Downloads: If a target runtime is not present locally, the compiler dynamically downloads it from the GitHub releases page using the current compiler version.
  • Binary Size Reduction: Removing the embedded runtimes reduces the tiny compiler binary size from approximately 62 MB to 16 MB.
  • Normalized Target Names: Standardized CLI target flags to use linux-arm64 and darwin-arm64 for ARM64 platforms.

Installation and Downloads

To install Tiny, download the compiler binary for your specific operating system:

  • Windows: Download tiny_windows_amd64.exe
  • Linux: Download tiny_linux_amd64 for amd64 or tiny_linux_arm64 for arm64
  • macOS (Apple Silicon): Download tiny_darwin_arm64

thanks to @lodenrogue for the initial linux arm64 issue and pull request that helped surface the missing target support.

Note: The tiny_runtime_* assets listed in the releases page are managed automatically by the compiler during the pack and dist commands. You do not need to download them manually.

Tiny v0.2.6 - Destructuring, Sum Types, and LSP Enhancements

Choose a tag to compare

@confh confh released this 16 Jun 23:24

Tiny v0.2.6 - Destructuring, Sum Types, and LSP Enhancements

This release introduces major language features including object and array destructuring, data-carrying enum variants, and significant improvements to the built-in Language Server (LSP).

Language Features

  • Destructuring Assignment: Support for object and array destructuring in let and const statements. Includes support for nested patterns, property renaming, and spread elements.
  • Enum Variants with Data: Enums now support variants with associated data, enabling the use of Sum Types (Algebraic Data Types).
  • Advanced Pattern Matching: The match statement now supports union patterns (A | B), guard patterns (if conditions), and binding patterns for extracting enum variant payloads.
  • Bitwise Operators: Added support for bitwise operators: AND (&), OR (|), XOR (^), NOT (~), and bitwise shifts (<<, >>). Corresponding assignment operators (&=, |=, etc.) are also supported.
  • Nullable Type Shorthand: Added the ? suffix as a shorthand for nullable types (e.g., string? is equivalent to string | null).
  • Function Type Hints: Support for detailed function type signatures in hints, such as function(number, string): bool.
  • Numeric Separators: Numbers can now include underscores for better readability (e.g., 1_000_000).

Language Server (LSP) Enhancements

  • Semantic Tokens: Full semantic highlighting for keywords, types, classes, enums, functions, and variables.
  • Inlay Hints: Added callback parameter type hints. The LSP now infers and displays parameter types for anonymous functions used as callbacks.
  • Document Highlights: Highlighting of all references to the symbol currently under the cursor.
  • Improved Type Narrowing: Enhanced flow analysis for typeof and instanceof guards, providing better autocompletion within conditional blocks.
  • Native Block Isolation: The analyzer and formatter now correctly handle go { ... } blocks inside native functions, preventing false syntax errors.

VM and JIT Optimizations

  • Wasm Object Array Packing: Optimized access to homogeneous object arrays by mirroring them in Wasm linear memory. JIT code now accesses properties via direct offsets.
  • JIT String Join: Enabled JIT acceleration for string joining operations.
  • Dynamic Memory Growth: JIT object allocation now utilizes a host import that handles Wasm memory growth safely.
  • Native Timers: Added support for time.timeout(ms, callback) and time.interval(ms, callback), returning manageable Timer objects.
  • Advanced Array Methods: Added native implementations for reduce, sort, slice, flat, flatMap, and findIndex.

Bug Fixes

  • Fixed signed integer to string conversion for negative numbers and minimum values.
  • Improved LSP organize imports logic to preserve formatting around native Go blocks.

Tiny v0.2.5 - JIT Region Outlining and Packed Arrays

Choose a tag to compare

@confh confh released this 15 Jun 18:10

Tiny v0.2.5 - JIT Region Outlining and Packed Arrays

This release introduces significant performance optimizations to the JIT engine, a new data validation library, and substantial enhancements to the language server.

JIT Engine Enhancements

  • Region Outlining: Implemented a loop-profiling pass that automatically outlines hot loops from top-level code and function bodies into specialized JIT regions (__jit_region_*). This enables JIT acceleration for performance-critical logic regardless of whether it is encapsulated in a function.
  • Packed Object Arrays: Introduced host-memory mirroring for arrays containing objects of uniform shape. The JIT engine now generates direct linear memory access patterns via field-column pointer tables, bypassing expensive host-side VM property lookups during array iterations.
  • Default Parameter Injection: The JIT compiler now supports calls to functions with default parameters by statically injecting literal default values into the WASM stack, maintaining full arity without interpreter fallbacks.
  • Result Memoization: Side-effect-free functions are now identified during compilation and eligible for JIT-level memoization. Results are cached based on input identity, eliminating redundant computation for deterministic paths.

Compiler and Optimizer

  • Advanced Superinstructions: The bytecode optimizer now emits new superinstructions, including OP_ARRAY_INDEX_LOCAL_STORE and OP_JUMP_PROPERTY_LOCAL_FALSE/TRUE, consolidating multiple operations into single dispatch cycles.
  • Enhanced Type Propagation: Improved the internal type flow analysis to track property hints for local objects and element types for arrays across complex control flow, enabling tighter JIT code generation.
  • Specialized Property Access: Constant string indices in IndexExpr are now automatically lowered to OP_GET_PROPERTY_SAFE and OP_SET_PROPERTY opcodes for faster resolution.

Standard Library

  • Schema Validation library: Added the validate library, providing a chainable, type-safe API for defining and enforcing data schemas. It includes support for nested objects, arrays, unions, and custom refinement predicates with detailed error reporting.
  • URL library: Added the url library for URL encoding & decoding.
  • Standard Library Extensions:
    • array: Added find(callback) method.
    • object: Added forEach(callback), pick(keys), and omit(keys) utilities.
    • http: Refined request body handling for direct JIT-to-Native object serialization.

Language Server (LSP)

  • Organize Imports: New code action to automatically sort and deduplicate import statements while removing unused aliases.
  • Semantic Error Recovery: The analyzer can now provide semantic diagnostics in files with active syntax errors by performing partial statement recovery during the scan pass.
  • Refactoring Integrity: Enhanced reference tracking and rename logic to correctly filter out object literal keys and string occurrences, ensuring refactors only affect intended identifiers.
  • Type Narrowing: Improved narrowing logic for complex conditional guards and guard-return patterns.

Internal Changes

  • Bytecode Version: Internal bytecode version bumped to 25.
  • VM Configuration: NewVM now requires a VMInfo configuration struct instead of positional arguments.

Tiny v0.2.4 - Optimization and Robustness

Choose a tag to compare

@confh confh released this 13 Jun 19:43

Tiny v0.2.4 - Optimization and Robustness

This release introduces a suite of advanced compiler optimizations and a significant overhaul of the JIT engine to support mid-function deoptimization and native memory management.

Compiler Optimizations

  • Object Virtualization: Implemented a sophisticated escape analysis pass that identifies non-escaping object literals. These objects are now virtualized into stack slots, completely eliminating heap allocation overhead for temporary data structures.
  • Interpreter Superinstructions: The bytecode optimizer now emits broad superinstructions (e.g., OP_LOCAL_CONST_OP_STORE, OP_ADD_LOCAL_PROPERTIES_STORE) that consolidate common instruction patterns, significantly reducing dispatch overhead in the interpreter.
  • Standard Library Intrinsics: Core methods from math, io, and json are now lowered directly to specialized opcodes, bypassing the standard method dispatch and native call overhead.

JIT Engine Overhaul

  • Mid-Function Deoptimization: Added support for robust deoptimization checkpoints. JIT-compiled functions can now safely bail out to the interpreter at any point (e.g., on type mismatches or side-effect boundaries) while maintaining full local and stack state.
  • Inlined WASM Allocators: JIT-compiled functions now utilize a high-performance bump-pointer allocator directly within WASM linear memory. Allocation is tracked via a bitset to ensure zero-copy interop with the interpreter.
  • Optimized String Joins: Implemented a fully-native WASM fast path for string concatenation and interpolation, reducing context switches to the host for common string operations.
  • Advanced Type Flow Analysis: The JIT compiler now performs a multi-pass type inference on parameters and return values to generate more specialized and efficient WASM code.

Runtime and Performance

  • Fast JSON Provider: Introduced a hand-rolled, reflection-free JSON parser and stringifier. This provider operates directly on TinyValue types, delivering substantial performance gains over standard library implementations.
  • VM Task Pooling: Optimized async task and server performance by implementing a configurable worker pool (VMPool). This provides better resource isolation and prevents excessive memory pressure under high concurrency.
  • Enhanced String Equality: Added a direct WASM-native string comparison loop for JIT-compiled code, further reducing host-call overhead.

Breaking Changes

  • Internal Bytecode Version: Bumped to 23 to accommodate new superinstruction opcodes and JIT deoptimization metadata.
  • Standard Module Dispatch: Standard module calls in JIT code now dispatch through a centralized call_stdlib_wasm import for improved side-effect tracking.

Tiny v0.2.3 - Advanced JIT and Native Data Structures

Choose a tag to compare

@confh confh released this 11 Jun 21:25

Tiny v0.2.3 - Advanced JIT and Native Data Structures

This release focuses on a complete overhaul of the JIT compilation engine, transitioning to a unified multi-function architecture and introducing high-performance native memory management for objects and arrays.

JIT Compiler Overhaul

  • Multi-Function Compilation: The JIT engine now compiles all eligible functions into a single WASM module. This enables direct inter-function calls within WASM, significantly reducing context-switching overhead between the VM and host environment.
  • WASM-Native Allocations: Objects and arrays created within JIT-compiled functions are now allocated directly in WASM linear memory. This eliminates the need for Go-side allocation for hot code paths.
  • Expanded Opcode Support: Added JIT support for complex operations including property access (get, set), array indexing, and built-in method acceleration for push, get, and length.
  • Intelligent Type Inference: The compiler now performs static type flow analysis to optimize tagged value handling, specifically for boolean and numeric operations.

VM and Runtime Improvements

  • Unified Arithmetic Engine: Refactored core arithmetic operations into a centralized provider. This ensures strict behavioral parity between interpreted and JIT-compiled execution, particularly for floating-point division and modulo operations.
  • Zero-Copy Interop: Introduced proxy types for WASM-resident objects and arrays, allowing the interpreter to interact with JIT-allocated data structures without costly serialization.
  • Packing Detection: Added runtime.isPacked() to the standard library, enabling applications to detect if they are running within a standalone binary created by tiny pack.
  • Enhanced Debugging: Test infrastructure now captures stderr output from the VM, improving the diagnostic capabilities for JIT deoptimization and runtime panics.

Breaking Changes

  • Internal Bytecode Version: Bumped to 22 to accommodate new JIT metadata and assumption tracking.
  • Float Truncation: Removed implicit float-to-int truncation in several internal bytecode conversion paths to enforce stricter type adherence.

Tiny v0.2.2 - Generics, JIT, and Native Modules

Choose a tag to compare

@confh confh released this 11 Jun 12:21

Tiny v0.2.2 - Generics, JIT, and Native Modules

This release introduces a sophisticated generics system, a WASM-based JIT compiler for the runtime, and expands the standard library with native WebSocket and System Tray support.

Language and Type System

  • Generics (:T): Functions, classes, and interfaces now support type parameters. The compiler performs deep type checking and supports automatic type inference for constructor and function calls.
  • Enum Types: Added support for string and number-based enums. The compiler ensures type safety when assigning enum members and validates match exhaustiveness.
  • Type Narrowing: Enhanced LSP intelligence for typeof, instanceof, and null-check narrowing, including support for negated conditions and else-block inference.
  • Unreachable Code Detection: The analyzer now identifies and warns about unreachable code blocks and missing return paths in typed functions.

Runtime and Performance

  • WASM JIT Compiler: Introduced an experimental JIT compiler using wazero. It transparently compiles hot bytecode sequences specifically arithmetic and direct recursion into WASM for near-native execution speeds.
  • WebSocket Module: A new native websocket module providing both client and server implementations with support for JSON payloads and binary buffers.
  • System Tray Integration: Added a tray module for creating cross-platform system tray applications with support for custom menus, icons, and notifications.
  • Bytecode Refinement: Updated the bytecode format to preserve type parameter metadata for runtime interface validation.

Developer Experience (LSP)

  • Implement Missing Methods: A new code action for classes that embed interfaces or other classes, automatically generating stubs for missing fields and methods.
  • Enum Match Exhaustiveness: The LSP now warns if a match statement on an enum does not cover all possible members or lacks a default case.
  • Library Auto-Imports: Expanded the LSP's symbol discovery to include members of generic classes and interfaces.

CLI and Tooling

  • Interactive Help: Added a dedicated help command with detailed documentation for all CLI subcommands including build, pack, dist, and install.
  • Version Update: Bumped the internal bytecode version to 21 to support generic metadata.

Tiny v0.2.1 - Strong Typing and Networking Update

Choose a tag to compare

@confh confh released this 10 Jun 11:31

Tiny v0.2.1 - Strong Typing and Networking Update

This version introduces a revolutionary strong typing system for arrays, recursive dependency management, and a significantly enhanced HTTP standard library. Multilevel caching has also been implemented to drastically improve development performance for large projects.

Language and Type System

  • Typed Arrays (array:T): New syntax for specifying array element types. The compiler now provides deep type checking, supports nested structures (e.g., array:array:string), and automatically infers return types for array operations like push, pop, and get.
  • Deeply Nested Namespaces: Removed restrictions on namespace depth, allowing for more sophisticated module organization.
  • Enhanced Default Parameters: Function default arguments now support array and object literals with support for deep nesting.
  • ANSI Escape Support: The lexer now supports the \e escape sequence for building rich CLI applications.

Dependency and Tooling

  • Recursive Dependency Installation: tiny install now automatically resolves and installs the entire dependency tree, ensuring environment consistency.
  • Lockfile Optimization: Improved tiny.lock generation with precise dependency resolution based on the project root.
  • Target-Aware Packaging: The packager now automatically filters native plugins based on the target platform (Windows, Linux, macOS), significantly reducing distribution sizes.
  • Dependency Caching: Optimized local caching logic for faster secondary installations and cross-project development.

LSP and Developer Experience

  • Multilevel Performance Caching: Introduced scope and document block caching, greatly improving completion and diagnostic response times in large source files.
  • Library Auto-Imports: The LSP now discovers and suggests classes, functions, and constants from local libraries and installed dependencies, automatically inserting the required import statements.
  • Loop Variable Intelligence: Improved scope recognition and type inference for iteration variables in both standard for and for-in loops.
  • Improved Hover Resolution: Optimized hover logic for declaration members, resolving conflicts between interface fields and global functions with the same name.

Runtime and Standard Library

  • HTTP Module Overhaul:
    • Added native support for PUT, PATCH, and DELETE methods.
    • Introduced static routing for serving entire directories.
    • Added helper functions for HTML, Redirect, File, and Download responses.
    • New security configurations including readTimeoutMs, writeTimeoutMs, and maxBodySize.

Tiny v0.2.0 - The Lockfile and Tooling Update

Choose a tag to compare

@confh confh released this 09 Jun 20:38

Tiny v0.2.0 - The Lockfile and Tooling Update

This major update introduces the lockfile system for reproducible builds, significant performance optimizations through dependency caching, and a vastly improved developer experience with documentation hovers and smarter LSP integrations.

Dependency Management and Lockfiles

The package management system has been overhauled to provide better stability and performance.

  • Lockfile Support: Introduction of tiny.lock to track and pin exact dependency versions. This ensures consistent builds across different machines by resolving unpinned versions to a fixed state.
  • Dependency Caching: The installation process now checks for cached versions of libraries. This skips redundant downloads and prevents unnecessary rebuilds of native plugins.
  • Target-Aware Installation: Native plugin dependencies are now tracked by target architecture (e.g., windows-amd64, linux-amd64), ensuring that cached assets match the current execution environment.
  • Package Ignore Rules: Added an ignore field to tiny.json, allowing developers to exclude files and directories (such as documentation or tests) from distribution packages using glob patterns.

LSP and Developer Tooling

The language server has been enhanced with features typically found in mature ecosystems.

  • Documentation Hovers: The LSP now extracts // comments preceding declarations. These are displayed as formatted Markdown hovers when inspecting functions, classes, interfaces, and enums.
  • Context-Aware Completions: Improved object literal completions. The LSP now understands when the cursor is inside an object being passed to a function or assigned to a typed variable, offering precise key suggestions even when using quoted string keys.
  • Enhanced Stubs: Standard library stubs have been updated with comprehensive documentation comments, providing immediate context for built-in functions during development.
  • Signature Intelligence: Improved parameter inference for functions with default arguments.

Compiler and Language Features

The compiler and parser received updates to expand the language's expressiveness.

  • Array Default Parameters: Functions can now define array literals as default values for parameters.
  • Obfuscated Bytecode Metadata: Function names are now XOR-obfuscated within the .tbc stream, matching the protection level of strings and binary assets.
  • Bytecode Versioning: Bytecode version bumped to 21 to support new metadata structures.

Runtime and Standard Library

Critical stability fixes and behavior refinements have been implemented.

  • Stack Integrity Fixes: Resolved a bug in process.setEnv and process.unsetEnv where the VM stack was left in an inconsistent state. These functions now correctly push a null return value.
  • Return Type Enforcement: Class methods now strictly preserve and enforce their declared return types at the bytecode level.
  • Standard Library Documentation: Added documentation comments to all standard library stubs for better discoverability.

Maintenance and Testing

  • Version Bump: Tiny version updated to 0.2.0.
  • Regression Coverage: Added comprehensive tests for lockfile generation, dependency caching, object literal completion contexts, and array default parameter parsing.
  • Cleanup: Refined the copyDirectory logic to support recursive ignore patterns.

Note: This update changes the bytecode format. All existing .tinycache and .tbc files should be recompiled.