ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
320 lines (319 loc) • 13.1 kB
JavaScript
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);
}
}
}