Architecture
BrowserSm Architecture
BrowserSm implements a complete Squeak Smalltalk virtual machine in JavaScript, enabling standard Squeak applications to run in web browsers without plugins or external dependencies. This document explores the VM architecture and the reference browser application that demonstrates its capabilities.
Table of Contents
- Design Principles
- Two-Layer Architecture
- Core Components
- Data Flow
- Rendering Pipeline
- Script Execution
- Memory Management
- Performance Considerations
Design Principles
BrowserSm is built on the foundational Smalltalk design principles articulated by Dan Ingalls:
Personal Mastery
Every component of BrowserSm can be understood, inspected, and modified by a single developer. The system is transparent and comprehensible.
1
2
3
4
"Every object is inspectable"
browser inspect. "Browse the browser itself"
browser currentPage document inspect. "Examine the DOM tree"
browser cssProcessor inspect. "Debug CSS processing"
Uniform Metaphor
Everything is an object, everything sends messages. There are no special cases or foreign concepts.
1
2
3
4
5
6
7
8
9
10
"HTML elements are objects"
element := BSDOMElement tag: 'div'.
element setAttribute: 'class' value: 'container'.
element appendChild: (BSDOMText content: 'Hello, World!').
"CSS rules are objects"
rule := BSCSSRule selector: '.container' declarations: {
BSCSSDeclaration property: 'color' value: 'blue'.
BSCSSDeclaration property: 'font-size' value: '16px'.
}.
Modularity
Clean separation of concerns with well-defined interfaces between components.
Factoring
Common functionality is extracted into reusable components and protocols.
Reactive Principle
All objects can present themselves meaningfully for observation and manipulation.
Virtual Machine Architecture
BrowserSm implements the complete Squeak virtual machine in JavaScript, providing a standards-compliant Smalltalk execution environment in web browsers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
┌─────────────────────────────────────────────────────────┐
│ Standard Squeak Applications │
│ (Unmodified .image files) │
├─────────────────────────────────────────────────────────┤
│ IDE Tools │ Browser App │ Custom Apps │ Games │
│ (Inspector) │ (Reference) │ (User) │ (Fun) │
│ │ │ │ │
│ ┌─────────┐ │ ┌───────────┐ │ ┌────────┐ │ ┌───┐ │
│ │ Debug │ │ │ DOM/CSS │ │ │ Custom │ │ │Tet│ │
│ │ Browse │ │ │ HTML │ │ │ Logic │ │ │ris│ │
│ │ Inspect │ │ │ Morphic │ │ │ │ │ │ │ │
│ └─────────┘ │ └───────────┘ │ └────────┘ │ └───┘ │
├─────────────────────────────────────────────────────────┤
│ Squeak Object Memory │
│ (Standard Spur Format) │
├─────────────────────────────────────────────────────────┤
│ Class │ Method │ Context │ Special │
│ Objects │ Dictionary │ Stack │ Objects │
│ │ │ │ │
│ ┌─────────┐ │ ┌─────────┐ │ ┌────────┐ │ ┌───────┐ │
│ │ Behav. │ │ │ Compile │ │ │ Frame │ │ │ nil │ │
│ │ Inst. │ │ │ Lookup │ │ │ Temp │ │ │ true │ │
│ │ Meta │ │ │ Cache │ │ │ Args │ │ │ false │ │
│ └─────────┘ │ └─────────┘ │ └────────┘ │ └───────┘ │
├─────────────────────────────────────────────────────────┤
│ BrowserSm VM (JavaScript) │
│ (Bytecode Interpreter) │
├─────────────────────────────────────────────────────────┤
│ Bytecode │ Primitive │ Garbage │ Platform │
│ Dispatch │ Operations │ Collector │ Bridge │
│ │ │ │ │
│ ┌───────┐ │ ┌─────────┐ │ ┌────────┐ │ ┌────────┐ │
│ │ Fetch │ │ │ Numbers │ │ │ Mark │ │ │ DOM │ │
│ │ Exec │ │ │ Arrays │ │ │ Sweep │ │ │ Events │ │
│ │ Stack │ │ │ Stream │ │ │ Weak │ │ │ Canvas │ │
│ └───────┘ │ └─────────┘ │ └────────┘ │ └────────┘ │
├─────────────────────────────────────────────────────────┤
│ Browser Platform │
│ (JavaScript Engine + Web APIs) │
└─────────────────────────────────────────────────────────┘
The Virtual Machine Layer
JavaScript implementation that provides complete Squeak VM functionality:
- Bytecode Interpreter: Executes all standard Squeak bytecodes
- Object Memory: Implements Spur object format with automatic garbage collection
- Primitive Operations: Maps Squeak primitives to JavaScript/browser operations
- Image Management: Loads, saves, and snapshots standard .image files
The Application Layer
Standard Squeak applications running unmodified on the VM:
- Development Environment: Complete Squeak IDE with browser-based tools
- Reference Browser: Web browser application demonstrating VM capabilities
- Custom Applications: Any Squeak software can run without modification
Core Components
1. Browser Core (BSBrowser)
The main browser object that coordinates all other components:
1
2
3
4
5
Object subclass: #BSBrowser
instanceVariableNames: 'window tabs configuration webPageLoader'
classVariableNames: ''
poolDictionaries: ''
category: 'BrowserSm-Core'
Responsibilities:
- Window and tab management
- Navigation and history
- Configuration and preferences
- Resource loading coordination
2. DOM Engine (BrowserSm-DOM)
Complete implementation of W3C DOM specifications:
1
2
3
4
5
6
"Core DOM classes"
Object subclass: #BSDOMNode. "Base node type"
BSDOMNode subclass: #BSDOMElement. "HTML elements"
BSDOMNode subclass: #BSDOMText. "Text nodes"
BSDOMNode subclass: #BSDOMDocument. "Document root"
Object subclass: #BSDOMEvent. "Event system"
Features:
- Live object tree with parent/child relationships
- Event propagation (capturing/bubbling)
- CSS selector matching
- XPath evaluation
- Mutation observation
3. HTML Parser (BrowserSm-HTML)
WHATWG HTML5-compliant parser with full error recovery:
1
2
Object subclass: #BSHTMLParser
instanceVariableNames: 'tokenizer treeBuilder errorHandler'
Capabilities:
- Streaming tokenization
- Tree construction with insertion modes
- Error recovery following HTML5 specification
- Fragment parsing
- Custom element support
4. CSS Engine (BrowserSm-CSS)
Complete CSS3 implementation with modern layout algorithms:
1
2
3
4
5
6
"CSS processing pipeline"
Object subclass: #BSCSSParser. "Parse stylesheets"
Object subclass: #BSCSSSelector. "Selector matching"
Object subclass: #BSCSSRule. "Style rules"
Object subclass: #BSCSSLayoutEngine. "Layout calculation"
Object subclass: #BSCSSPaintEngine. "Rendering"
Layout Algorithms:
- Normal flow (block/inline)
- Flexbox (CSS Flexible Box Layout)
- Grid (CSS Grid Layout) — planned
- Positioned elements (absolute/relative/fixed)
- Floating elements
5. Script Runtime (BrowserSm-Script)
Sandboxed Smalltalk execution for web page scripts:
1
2
3
4
5
Object subclass: #BSScriptRuntime
instanceVariableNames: 'sandbox whitelistedClasses'
Object subclass: #BSSandbox
instanceVariableNames: 'timeoutDuration whitelistedMethods'
Security Features:
- Capability-based sandboxing
- Execution timeouts
- Class/method whitelisting
- DOM access controls
6. Morphic Integration (BrowserSm-UI)
Browser UI implemented entirely in Squeak’s Morphic framework:
1
2
3
4
5
Morph subclass: #BSBrowserWindow. "Main window"
Morph subclass: #BSToolbar. "Address bar, buttons"
Morph subclass: #BSTabBar. "Tab management"
Morph subclass: #BSViewport. "Web page rendering area"
Morph subclass: #BSDeveloperTools. "Debugging interface"
Data Flow
1. Page Loading
1
2
3
User Input → Navigation → Resource Loading → Parsing → DOM Construction
↓ ↓ ↓ ↓ ↓
[Address Bar] [BSHistory] [BSResourceLoader] [BSHTMLParser] [BSDOMDocument]
2. Rendering Pipeline
1
2
3
DOM Tree → Style Computation → Layout → Paint → Display
↓ ↓ ↓ ↓ ↓
[BSDOMDocument] [BSCSSEngine] [BSLayout] [BSPaint] [Morphic Canvas]
3. Event Handling
1
2
3
Platform Event → Morphic → Browser UI → DOM Event → Script Execution
↓ ↓ ↓ ↓ ↓
[Mouse/Keyboard] [Morph] [BSViewport] [BSDOMEvent] [BSScriptRuntime]
Rendering Pipeline
BrowserSm implements a modern browser rendering pipeline entirely in Smalltalk:
1. Parse
HTML text is tokenized and parsed into a DOM tree:
1
2
3
"Parse HTML content"
parser := BSHTMLParser new.
document := parser parse: htmlContent.
2. Style
CSS rules are matched to DOM elements and computed styles calculated:
1
2
3
"Apply stylesheets"
styleEngine := BSCSSEngine new.
styleEngine applyStylesheets: document stylesheets to: document.
3. Layout
Element positions and dimensions are calculated:
1
2
3
"Perform layout"
layoutEngine := BSCSSLayoutEngine new.
layoutTree := layoutEngine layout: document inBox: viewportBounds.
4. Paint
Visual representation is rendered to a canvas:
1
2
3
"Paint to canvas"
paintEngine := BSCSSPaintEngine new.
paintEngine paint: layoutTree on: canvas.
5. Composite
Final image is composited and displayed in Morphic:
1
2
"Display in browser viewport"
viewport displayCanvas: canvas.
Script Execution
BrowserSm executes Smalltalk scripts instead of JavaScript:
Sandbox Architecture
1
2
3
4
5
"Script execution example"
runtime := BSScriptRuntime default.
result := runtime
evaluateScript: 'document getElementById: ''myButton'' setAttributes: #(#class ''clicked'')'
inDocument: document.
Security Model
Scripts run in a capability-based sandbox:
- Timeout Protection: Scripts are terminated after configurable time limits
- Class Whitelisting: Only approved classes are accessible
- DOM Mediation: DOM access is mediated through safe proxies
- Resource Limits: Memory and computation limits prevent abuse
API Bindings
Scripts access web APIs through Smalltalk objects:
1
2
3
4
5
6
"Web APIs available to scripts"
console log: 'Hello from Smalltalk script!'.
localStorage setItem: 'key' value: 'data'.
fetch url: 'https://api.example.com/data'
then: [ :response | console log: response ]
catch: [ :error | console error: error ].
Memory Management
Object Lifecycle
BrowserSm manages complex object graphs efficiently:
- DOM Trees: Automatic cleanup when pages are unloaded
- CSS Objects: Cached and reused across page loads
- Layout Trees: Rebuilt incrementally on changes
- Script Objects: Garbage collected with sandbox cleanup
Performance Optimizations
- Incremental Layout: Only recalculate changed subtrees
- Display List Caching: Cache painted content between frames
- Resource Pooling: Reuse parser and layout objects
- Weak References: Break cycles between DOM and layout objects
Performance Considerations
Rendering Performance
1
2
3
4
5
6
"Enable performance optimizations"
BSConfiguration default
enableIncrementalLayout: true;
enableDisplayListCaching: true;
enableHardwareAcceleration: false; "Future: WebGL backend"
maxFrameRate: 60.
Memory Usage
1
2
3
4
5
6
"Configure memory management"
BSConfiguration default
enableAggressiveGC: true;
maxCachedResources: 100;
maxDOMTreeSize: 10000;
scriptMemoryLimit: 16 * 1024 * 1024. "16MB"
Network Performance
1
2
3
4
5
6
"HTTP client configuration"
BSResourceLoader default
maxConcurrentConnections: 6;
enablePipelining: false;
enableCompression: true;
userAgent: 'BrowserSm/0.9 (Squeak; Smalltalk)'.
Extensibility
BrowserSm’s architecture supports extension through standard Smalltalk mechanisms:
Custom Elements
1
2
3
4
5
6
7
8
"Define a custom HTML element"
BSDOMElement subclass: #BSCustomButton
instanceVariableNames: 'clickHandler'
BSCustomButton>>initialize
super initialize.
self tagName: 'custom-button'.
self addEventListener: 'click' handler: [ self handleClick ].
CSS Extensions
1
2
3
4
5
"Add a custom CSS property"
BSCSSProperty subclass: #BSCustomTransform
BSCustomTransform>>applyToElement: element value: value
"Custom property implementation"
Plugin Architecture
1
2
3
4
5
6
7
8
"Browser extension example"
BSBrowserPlugin subclass: #BSAdBlocker
BSAdBlocker>>processRequest: request
"Filter requests based on ad blocking rules"
^ self shouldBlock: request url
ifTrue: [ nil ]
ifFalse: [ super processRequest: request ].
This architecture enables BrowserSm to provide a complete web browsing experience while maintaining the transparency, flexibility, and power that makes Smalltalk unique. Every component can be inspected, modified, and extended using familiar Smalltalk development tools.