218 lines
7.9 KiB
HTML
218 lines
7.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Phase 9.7 ExternCall Demo - Nyash WASM FFI</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
background: #f5f5f5;
|
|
}
|
|
.container {
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
}
|
|
h1 {
|
|
color: #333;
|
|
text-align: center;
|
|
}
|
|
.status {
|
|
background: #e8f5e8;
|
|
border: 1px solid #4caf50;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
}
|
|
canvas {
|
|
border: 2px solid #333;
|
|
display: block;
|
|
margin: 20px auto;
|
|
}
|
|
button {
|
|
background: #4caf50;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
margin: 5px;
|
|
}
|
|
button:hover {
|
|
background: #45a049;
|
|
}
|
|
.code-demo {
|
|
background: #f8f8f8;
|
|
border: 1px solid #ddd;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
white-space: pre-wrap;
|
|
}
|
|
.log-output {
|
|
background: #1e1e1e;
|
|
color: #00ff00;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
height: 150px;
|
|
overflow-y: auto;
|
|
margin: 10px 0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🌐 Phase 9.7: Box FFI/ABI + ExternCall Demo</h1>
|
|
|
|
<div class="status">
|
|
✅ <strong>ExternCall Implementation Complete!</strong><br>
|
|
Universal Library Integration via WASM Runtime Imports
|
|
</div>
|
|
|
|
<h2>🎯 Architecture Overview</h2>
|
|
<div class="code-demo">// Nyash External Call Pattern
|
|
console.log("Hello from Nyash!")
|
|
canvas.fillRect("demo-canvas", 50, 50, 100, 100, "red")
|
|
|
|
// Generated MIR ExternCall Instructions:
|
|
ExternCall {
|
|
dst: None,
|
|
iface_name: "env.console",
|
|
method_name: "log",
|
|
args: [string_ptr, string_len],
|
|
effects: IO
|
|
}
|
|
|
|
// Generated WASM Imports:
|
|
(import "env" "console_log" (func $console_log (param i32 i32)))
|
|
(import "env" "canvas_fillRect" (func $canvas_fillRect (param i32 i32 i32 i32 i32 i32 i32 i32)))</div>
|
|
|
|
<h2>🎮 Interactive Demo</h2>
|
|
<canvas id="demo-canvas" width="400" height="300"></canvas>
|
|
|
|
<div>
|
|
<button onclick="testConsoleLog()">🖥️ Test Console Log</button>
|
|
<button onclick="testCanvasFillRect()">🎨 Test Canvas Fill Rectangle</button>
|
|
<button onclick="testCanvasFillText()">📝 Test Canvas Fill Text</button>
|
|
<button onclick="clearCanvas()">🧹 Clear Canvas</button>
|
|
</div>
|
|
|
|
<h3>📊 Console Output:</h3>
|
|
<div id="log-output" class="log-output"></div>
|
|
|
|
<h2>🔧 Implementation Status</h2>
|
|
<div class="status">
|
|
<strong>✅ Core Components Complete:</strong><br>
|
|
• MIR ExternCall instruction with effect tracking<br>
|
|
• WASM RuntimeImports with console/canvas operations<br>
|
|
• JavaScript import object generation<br>
|
|
• BID specification compliance (console.yaml, canvas.yaml)<br>
|
|
• String handling via (ptr, len) parameters<br><br>
|
|
|
|
<strong>🚀 Ready for Universal Exchange:</strong><br>
|
|
External libraries can now be integrated via Box FFI/ABI!
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let logBuffer = [];
|
|
|
|
function updateLogDisplay() {
|
|
const logElement = document.getElementById('log-output');
|
|
logElement.textContent = logBuffer.join('\n');
|
|
logElement.scrollTop = logElement.scrollHeight;
|
|
}
|
|
|
|
function log(message) {
|
|
logBuffer.push(`[${new Date().toLocaleTimeString()}] ${message}`);
|
|
if (logBuffer.length > 20) logBuffer.shift();
|
|
updateLogDisplay();
|
|
}
|
|
|
|
// Simulate the import object that would be generated by Nyash WASM runtime
|
|
const importObject = {
|
|
env: {
|
|
console_log: (ptr, len) => {
|
|
// In real implementation, this would read from WASM memory
|
|
const message = `console.log called with ptr=${ptr}, len=${len}`;
|
|
console.log(message);
|
|
log(`Console: ${message}`);
|
|
},
|
|
canvas_fillRect: (canvasIdPtr, canvasIdLen, x, y, w, h, colorPtr, colorLen) => {
|
|
// In real implementation, this would read strings from WASM memory
|
|
const canvas = document.getElementById('demo-canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Mock color (in real implementation, would read from WASM memory)
|
|
const colors = ['red', 'blue', 'green', 'purple', 'orange'];
|
|
const color = colors[Math.floor(Math.random() * colors.length)];
|
|
|
|
ctx.fillStyle = color;
|
|
ctx.fillRect(x, y, w, h);
|
|
|
|
const message = `canvas.fillRect(${x}, ${y}, ${w}, ${h}, ${color})`;
|
|
console.log(message);
|
|
log(`Canvas: ${message}`);
|
|
},
|
|
canvas_fillText: (canvasIdPtr, canvasIdLen, textPtr, textLen, x, y, fontPtr, fontLen, colorPtr, colorLen) => {
|
|
const canvas = document.getElementById('demo-canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Mock text and color
|
|
const texts = ['Nyash!', 'FFI/ABI', 'ExternCall', 'WASM', '🌐'];
|
|
const text = texts[Math.floor(Math.random() * texts.length)];
|
|
const color = `hsl(${Math.random() * 360}, 70%, 50%)`;
|
|
|
|
ctx.font = '16px Arial';
|
|
ctx.fillStyle = color;
|
|
ctx.fillText(text, x, y);
|
|
|
|
const message = `canvas.fillText("${text}", ${x}, ${y}, ${color})`;
|
|
console.log(message);
|
|
log(`Canvas: ${message}`);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Demo functions
|
|
function testConsoleLog() {
|
|
log('🖥️ Calling external console.log...');
|
|
importObject.env.console_log(0x1000, 25); // Simulated WASM call
|
|
}
|
|
|
|
function testCanvasFillRect() {
|
|
log('🎨 Calling external canvas.fillRect...');
|
|
const x = Math.random() * 300;
|
|
const y = Math.random() * 200;
|
|
const w = 20 + Math.random() * 80;
|
|
const h = 20 + Math.random() * 80;
|
|
importObject.env.canvas_fillRect(0x2000, 11, x, y, w, h, 0x3000, 3);
|
|
}
|
|
|
|
function testCanvasFillText() {
|
|
log('📝 Calling external canvas.fillText...');
|
|
const x = Math.random() * 350;
|
|
const y = 30 + Math.random() * 250;
|
|
importObject.env.canvas_fillText(0x2000, 11, 0x4000, 6, x, y, 0x5000, 9, 0x6000, 5);
|
|
}
|
|
|
|
function clearCanvas() {
|
|
const canvas = document.getElementById('demo-canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
log('🧹 Canvas cleared');
|
|
}
|
|
|
|
// Initialize
|
|
log('🌐 Phase 9.7 ExternCall Demo Ready!');
|
|
log('✅ WASM Runtime Imports: console_log, canvas_fillRect, canvas_fillText');
|
|
log('🎯 Click buttons to test external function calls');
|
|
</script>
|
|
</body>
|
|
</html> |