UNPKG

ember-legacy-class-transform

Version:
320 lines (319 loc) 13.1 kB
import { initializeGuid, fillNulls, unreachable, typePos } from '@glimmer/util'; /** * Registers * * For the most part, these follows MIPS naming conventions, however the * register numbers are different. */ export var Register; (function (Register) { // $0 or $pc (program counter): pointer into `program` for the next insturction; -1 means exit Register[Register["pc"] = 0] = "pc"; // $1 or $ra (return address): pointer into `program` for the return Register[Register["ra"] = 1] = "ra"; // $2 or $fp (frame pointer): pointer into the `evalStack` for the base of the stack Register[Register["fp"] = 2] = "fp"; // $3 or $sp (stack pointer): pointer into the `evalStack` for the top of the stack Register[Register["sp"] = 3] = "sp"; // $4-$5 or $s0-$s1 (saved): callee saved general-purpose registers Register[Register["s0"] = 4] = "s0"; Register[Register["s1"] = 5] = "s1"; // $6-$7 or $t0-$t1 (temporaries): caller saved general-purpose registers Register[Register["t0"] = 6] = "t0"; Register[Register["t1"] = 7] = "t1"; })(Register || (Register = {})); export function debugSlice(env, start, end) { if (!false && false) { /* tslint:disable:no-console */ let { program } = env; let { constants } = program; // console is not available in IE9 if (typeof console === 'undefined') { return; } // IE10 does not have `console.group` if (typeof console.group !== 'function') { return; } console.group(`%c${start}:${end}`, 'color: #999'); for (let i = start; i < end; i = i + 4) { let { type, op1, op2, op3 } = program.opcode(i); let [name, params] = debug(constants, type, op1, op2, op3); console.log(`${i}. ${logOpcode(name, params)}`); } console.groupEnd(); /* tslint:enable:no-console */ } } function logOpcode(type, params) { if (!false && false) { let out = type; if (params) { let args = Object.keys(params).map(p => ` ${p}=${json(params[p])}`).join(''); out += args; } return `(${out})`; } } function json(param) { if (typeof param === 'function') { return '<function>'; } let string; try { string = JSON.stringify(param); } catch (e) { return '<cannot generate JSON>'; } if (string === undefined) { return 'undefined'; } let debug = JSON.parse(string); if (typeof debug === 'object' && debug !== null && debug.GlimmerDebug !== undefined) { return debug.GlimmerDebug; } return string; } function debug(c, op, op1, op2, op3) { if (!false && false) { switch (op) { case 0 /* Bug */: throw unreachable(); case 1 /* Helper */: return ['Helper', { helper: c.getFunction(op1) }]; case 2 /* Function */: return ['Function', { function: c.getFunction(op1) }]; case 4 /* SetVariable */: return ['SetVariable', { symbol: op1 }]; case 5 /* GetVariable */: return ['GetVariable', { symbol: op1 }]; case 6 /* GetProperty */: return ['GetProperty', { key: c.getString(op1) }]; case 7 /* PushBlock */: return ['PushBlock', { block: c.getBlock(op1) }]; case 8 /* GetBlock */: return ['GetBlock', { symbol: op1 }]; case 9 /* HasBlock */: return ['HasBlock', { block: op1 }]; case 10 /* HasBlockParams */: return ['HasBlockParams', { block: op1 }]; case 11 /* Concat */: return ['Concat', { size: op1 }]; case 12 /* Immediate */: return ['Immediate', { value: op1 }]; case 13 /* Constant */: return ['Constant', { value: c.getOther(op1) }]; case 14 /* PrimitiveReference */: return ['PrimitiveReference', { primitive: op1 }]; case 15 /* Dup */: return ['Dup', { register: Register[op1], offset: op2 }]; case 16 /* Pop */: return ['Pop', { count: op1 }]; case 17 /* Load */: return ['Load', { register: Register[op1] }]; case 18 /* Fetch */: return ['Fetch', { register: Register[op1] }]; /// PRELUDE & EXIT case 19 /* RootScope */: return ['RootScope', { symbols: op1, bindCallerScope: !!op2 }]; case 20 /* ChildScope */: return ['ChildScope', {}]; case 21 /* PopScope */: return ['PopScope', {}]; case 22 /* Return */: return ['Return', {}]; case 23 /* ReturnTo */: return ['ReturnTo', { offset: op1 }]; /// HTML case 24 /* Text */: return ['Text', { text: c.getString(op1) }]; case 25 /* Comment */: return ['Comment', { comment: c.getString(op1) }]; case 26 /* DynamicContent */: return ['DynamicContent', { value: c.getOther(op1) }]; case 27 /* OpenElement */: return ['OpenElement', { tag: c.getString(op1) }]; case 28 /* OpenElementWithOperations */: return ['OpenElementWithOperations', { tag: c.getString(op1) }]; case 29 /* OpenDynamicElement */: return ['OpenDynamicElement', {}]; case 30 /* StaticAttr */: return ['StaticAttr', { name: c.getString(op1), value: c.getString(op2), namespace: op3 ? c.getString(op3) : null }]; case 31 /* DynamicAttr */: return ['DynamicAttr', { name: c.getString(op1), trusting: !!op2 }]; case 32 /* DynamicAttrNS */: return ['DynamicAttrNS', { name: c.getString(op1), ns: c.getString(op2), trusting: !!op2 }]; case 33 /* FlushElement */: return ['FlushElement', {}]; case 34 /* CloseElement */: return ['CloseElement', {}]; /// MODIFIER case 35 /* Modifier */: return ['Modifier', {}]; /// WORMHOLE case 36 /* PushRemoteElement */: return ['PushRemoteElement', {}]; case 37 /* PopRemoteElement */: return ['PopRemoteElement', {}]; /// DYNAMIC SCOPE case 38 /* BindDynamicScope */: return ['BindDynamicScope', {}]; case 39 /* PushDynamicScope */: return ['PushDynamicScope', {}]; case 40 /* PopDynamicScope */: return ['PopDynamicScope', {}]; /// VM case 41 /* CompileDynamicBlock */: return ['CompileDynamicBlock', {}]; case 42 /* InvokeStatic */: return ['InvokeStatic', { block: c.getBlock(op1) }]; case 43 /* InvokeDynamic */: return ['InvokeDynamic', { invoker: c.getOther(op1) }]; case 44 /* Jump */: return ['Jump', { to: op1 }]; case 45 /* JumpIf */: return ['JumpIf', { to: op1 }]; case 46 /* JumpUnless */: return ['JumpUnless', { to: op1 }]; case 47 /* PushFrame */: return ['PushFrame', {}]; case 48 /* PopFrame */: return ['PopFrame', {}]; case 49 /* Enter */: return ['Enter', { args: op1 }]; case 50 /* Exit */: return ['Exit', {}]; case 51 /* Test */: return ['ToBoolean', {}]; /// LISTS case 52 /* EnterList */: return ['EnterList', { start: op1 }]; case 53 /* ExitList */: return ['ExitList', {}]; case 54 /* PutIterator */: return ['PutIterator', {}]; case 55 /* Iterate */: return ['Iterate', { end: op1 }]; /// COMPONENTS case 56 /* PushComponentManager */: return ['PushComponentManager', { definition: c.getOther(op1) }]; case 57 /* PushDynamicComponentManager */: return ['PushDynamicComponentManager', {}]; case 58 /* PushArgs */: return ['PushArgs', { synthetic: !!op2 }]; case 59 /* PrepareArgs */: return ['PrepareArgs', { state: Register[op1] }]; case 60 /* CreateComponent */: return ['CreateComponent', { flags: op1, state: Register[op2] }]; case 61 /* RegisterComponentDestructor */: return ['RegisterComponentDestructor', {}]; case 62 /* PushComponentOperations */: return ['PushComponentOperations', {}]; case 63 /* GetComponentSelf */: return ['GetComponentSelf', { state: Register[op1] }]; case 64 /* GetComponentLayout */: return ['GetComponentLayout', { state: Register[op1] }]; case 65 /* BeginComponentTransaction */: return ['BeginComponentTransaction', {}]; case 66 /* CommitComponentTransaction */: return ['CommitComponentTransaction', {}]; case 67 /* DidCreateElement */: return ['DidCreateElement', { state: Register[op1] }]; case 68 /* DidRenderLayout */: return ['DidRenderLayout', {}]; /// PARTIALS case 69 /* GetPartialTemplate */: return ['CompilePartial', {}]; case 70 /* ResolveMaybeLocal */: return ['ResolveMaybeLocal', { name: c.getString(op1) }]; /// DEBUGGER case 71 /* Debugger */: return ['Debugger', { symbols: c.getOther(op1), evalInfo: c.getArray(op2) }]; /// STATEMENTS case 72 /* Size */: throw unreachable(); } throw unreachable(); } return ['', {}]; } export class AppendOpcodes { constructor() { this.evaluateOpcode = fillNulls(72 /* Size */).slice(); } add(name, evaluate) { this.evaluateOpcode[name] = evaluate; } evaluate(vm, opcode, type) { let func = this.evaluateOpcode[type]; if (!false && false) { /* tslint:disable */ let [name, params] = debug(vm.constants, opcode.type, opcode.op1, opcode.op2, opcode.op3); console.log(`${typePos(vm['pc'])}. ${logOpcode(name, params)}`); // console.log(...debug(vm.constants, type, opcode.op1, opcode.op2, opcode.op3)); /* tslint:enable */ } func(vm, opcode); if (!false && false) { /* tslint:disable */ console.log('%c -> pc: %d, ra: %d, fp: %d, sp: %d, s0: %O, s1: %O, t0: %O, t1: %O', 'color: orange', vm['pc'], vm['ra'], vm['fp'], vm['sp'], vm['s0'], vm['s1'], vm['t0'], vm['t1']); console.log('%c -> eval stack', 'color: red', vm.stack.toArray()); console.log('%c -> scope', 'color: green', vm.scope()['slots'].map(s => s && s['value'] ? s['value']() : s)); console.log('%c -> elements', 'color: blue', vm.elements()['elementStack'].toArray()); /* tslint:enable */ } } } export const APPEND_OPCODES = new AppendOpcodes(); export class AbstractOpcode { constructor() { initializeGuid(this); } toJSON() { return { guid: this._guid, type: this.type }; } } export class UpdatingOpcode extends AbstractOpcode { constructor() { super(...arguments); this.next = null; this.prev = null; } } export function inspect(opcodes) { let buffer = []; opcodes.forEach((opcode, i) => { _inspect(opcode.toJSON(), buffer, 0, i); }); return buffer.join(''); } function _inspect(opcode, buffer, level, index) { let indentation = []; for (let i = 0; i < level; i++) { indentation.push(' '); } buffer.push(...indentation); buffer.push(`${index}. ${opcode.type}`); if (opcode.args || opcode.details) { buffer.push('('); if (opcode.args) { buffer.push(opcode.args.join(', ')); } if (opcode.details) { let keys = Object.keys(opcode.details); if (keys.length) { if (opcode.args && opcode.args.length) { buffer.push(', '); } buffer.push(keys.map(key => `${key}=${opcode.details && opcode.details[key]}`).join(', ')); } } buffer.push(')'); } buffer.push('\n'); if (opcode.children && opcode.children.length) { for (let i = 0; i < opcode.children.length; i++) { _inspect(opcode.children[i], buffer, level + 1, i); } } }