Skip to content

Commit

Permalink
Finish implementing {{partial}}s
Browse files Browse the repository at this point in the history
  • Loading branch information
chancancode committed Feb 28, 2017
1 parent 65ca5a0 commit 702d1de
Show file tree
Hide file tree
Showing 27 changed files with 446 additions and 558 deletions.
4 changes: 2 additions & 2 deletions packages/@glimmer/compiler/lib/javascript-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,8 @@ export default class JavaScriptCompiler<T extends TemplateMeta> {
this.pushValue<Expressions.Get>([Ops.Get, head, path]);
}

doubtful(path: string[]) {
this.pushValue<Expressions.Doubtful>([Ops.Doubtful, path]);
maybeLocal(path: string[]) {
this.pushValue<Expressions.MaybeLocal>([Ops.MaybeLocal, path]);
}

concat() {
Expand Down
2 changes: 1 addition & 1 deletion packages/@glimmer/compiler/lib/template-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export default class TemplateCompiler<T extends TemplateMeta> {
} else if (isSimplePath(path)) {
this.opcode('unknown', expr, path.parts[0]);
} else {
this.opcode('doubtful', expr, path.parts);
this.opcode('maybeLocal', expr, path.parts);
}
}

Expand Down
16 changes: 0 additions & 16 deletions packages/@glimmer/compiler/lib/template-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export abstract class SymbolTable {

abstract allocateNamed(name: string): number;
abstract allocateBlock(name: string): number;
abstract allocateEvalSlot(): number;
abstract allocate(identifier: string): number;

child(locals: string[]): BlockSymbolTable {
Expand All @@ -30,7 +29,6 @@ export class ProgramSymbolTable extends SymbolTable {
private size = 1;
private named = dict<number>();
private blocks = dict<number>();
private evalSlot = null;

has(name: string): boolean {
return false;
Expand Down Expand Up @@ -68,16 +66,6 @@ export class ProgramSymbolTable extends SymbolTable {
return block;
}

allocateEvalSlot(): number {
let { evalSlot } = this;

if (!evalSlot) {
this.evalSlot = evalSlot = this.allocate('$eval');
}

return this.evalSlot;
}

allocate(identifier: string): number {
this.symbols.push(identifier);
return this.size++;
Expand Down Expand Up @@ -117,10 +105,6 @@ export class BlockSymbolTable extends SymbolTable {
return this.parent.allocateBlock(name);
}

allocateEvalSlot(): number {
return this.parent.allocateEvalSlot();
}

allocate(identifier: string): number {
return this.parent.allocate(identifier);
}
Expand Down
13 changes: 12 additions & 1 deletion packages/@glimmer/interfaces/lib/tier1/symbol-table.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,27 @@ import { TemplateMeta } from '@glimmer/wire-format';
export interface Symbols {
}

export interface CompilationMeta {
symbols: string[];
templateMeta: TemplateMeta;
asPartial: boolean;
}

export interface SymbolTable {
meta: TemplateMeta;
meta: CompilationMeta;
}

export interface ProgramSymbolTable extends SymbolTable {
hasEval: boolean;
symbols: string[];
}

export interface BlockSymbolTable extends SymbolTable {
parameters: number[];
}

export interface PartialSymbolTable extends SymbolTable {

}

export default SymbolTable;
2 changes: 1 addition & 1 deletion packages/@glimmer/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export {

export {
ClientSide,
RawTemplate,
CompilableTemplate,
ScannedBlock,
ScannedProgram,
Block,
Expand Down
60 changes: 25 additions & 35 deletions packages/@glimmer/runtime/lib/compiled/opcodes/builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TemplateMeta } from '@glimmer/wire-format';
import * as content from './content';
import * as vm from './vm';

Expand All @@ -11,7 +10,7 @@ import { ModifierManager } from '../../modifier/interfaces';
import { ComponentDefinition } from '../../component/interfaces';
import { PartialDefinition } from '../../partial';
import Environment, { Program } from '../../environment';
import { SymbolTable } from '@glimmer/interfaces';
import { SymbolTable, CompilationMeta } from '@glimmer/interfaces';
import { ComponentBuilder as IComponentBuilder } from '../../opcode-builder';
import { ComponentBuilder } from '../../compiler';
import { RawInlineBlock, ClientSide, Block } from '../../scanner';
Expand Down Expand Up @@ -81,7 +80,7 @@ export abstract class BasicOpcodeBuilder {
private locals = 0;
private _localsSize = 0;

constructor(public env: Environment, public meta: TemplateMeta, public program: Program) {
constructor(public env: Environment, public meta: CompilationMeta, public program: Program) {
this.constants = env.constants;
this.start = program.next;

Expand Down Expand Up @@ -146,21 +145,6 @@ export abstract class BasicOpcodeBuilder {
label.patch(this.program);
}

// partials

putPartialDefinition(_definition: PartialDefinition<Opaque>) {
let definition = this.constants.other(_definition);
this.push(Op.PutPartial, definition);
}

putDynamicPartialDefinition() {
// this.push(Op.PutDynamicPartial, this.constants.other(this.symbolTable));
}

evaluatePartial() {
// this.push(Op.EvaluatePartial, this.constants.other(this.symbolTable), this.constants.other(dict()));
}

// components

pushComponentManager(definition: ComponentDefinition<Opaque>) {
Expand Down Expand Up @@ -216,6 +200,16 @@ export abstract class BasicOpcodeBuilder {
this.push(Op.DidRenderLayout, state);
}

// partial

getPartialTemplate() {
this.push(Op.GetPartialTemplate);
}

resolveMaybeLocal(name: string) {
this.push(Op.ResolveMaybeLocal, this.string(name));
}

// content

dynamicContent(Opcode: content.AppendDynamicOpcode<Insertion>) {
Expand Down Expand Up @@ -381,14 +375,6 @@ export abstract class BasicOpcodeBuilder {
this.push(Op.BindSelf);
}

bindVirtualBlock(layout: number, block: number) {
this.push(Op.BindVirtualBlock, layout, block);
}

bindVirtualNamed(layout: number, name: string) {
this.push(Op.BindVirtualNamed, layout, this.string(name));
}

pushRootScope(symbols: number, bindCallerScope: boolean) {
this.push(Op.RootScope, symbols, <any>bindCallerScope|0);
}
Expand Down Expand Up @@ -419,7 +405,7 @@ export abstract class BasicOpcodeBuilder {
this.push(Op.PushReifiedArgs, positional, names, flag);
}

pushImmediate(value: Opaque) {
pushImmediate<T>(value: T) {
this.push(Op.Constant, this.other(value));
}

Expand Down Expand Up @@ -516,28 +502,32 @@ export abstract class BasicOpcodeBuilder {
invokeStatic(_block: Block, ...args: ((builder: BasicOpcodeBuilder) => void)[]): void;
invokeStatic(_block: Block, numArgs: number): void;
invokeStatic(_block: Block): void {
let paramSize = _block.symbolTable.parameters.length;
let { parameters } = _block.symbolTable;
let paramSize = parameters.length;
let argSize = arguments.length - 1;
let onStack = false;
let excess = 0;

if (argSize === 1 && typeof arguments[1] === 'number') {
// BUG: what happens if paramSize < argSize?
// e.g. #with pushes 1 arg, #each pushes 2 - but the block might consume fewer
argSize = arguments[1];
argSize = Math.min(paramSize, arguments[1]);
excess = Math.max(arguments[1] - paramSize, 0);
onStack = true;
} else {
argSize = Math.min(paramSize, argSize);
}

for (let i=0; i<excess; i++) {
this.pop();
}

if (argSize) {
let locals = _block.symbolTable.parameters;
this.pushChildScope();

for (let i=0; i<argSize; i++) {
for (let i=argSize-1; i>=0; i--) {
if (!onStack) {
arguments[i+1](this);
}
this.setVariable(locals[i]);
this.setVariable(parameters[i]);
}
}

Expand Down Expand Up @@ -616,7 +606,7 @@ function isCompilableExpression<E>(expr: Represents<E>): expr is CompilesInto<E>
export default class OpcodeBuilder extends BasicOpcodeBuilder {
public component: IComponentBuilder;

constructor(env: Environment, meta: TemplateMeta, program: Program = env.program) {
constructor(env: Environment, meta: CompilationMeta, program: Program = env.program) {
super(env, meta, program);
this.component = new ComponentBuilder(this);
}
Expand Down
13 changes: 12 additions & 1 deletion packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { APPEND_OPCODES, Op } from '../../opcodes';
import { ConcatReference } from '../expressions/concat';
import { Helper } from '../../environment';
import { EvaluatedArgs } from '../expressions/args';
import { FunctionExpression } from '../expressions/function';
import { TRUE_REFERENCE, FALSE_REFERENCE } from '../../references';
import { VersionedPathReference } from '@glimmer/reference';
import { Opaque } from '@glimmer/util';
Expand Down Expand Up @@ -31,6 +30,18 @@ APPEND_OPCODES.add(Op.SetVariable, (vm, { op1: symbol }) => {
vm.scope().bindSymbol(symbol, expr);
});

APPEND_OPCODES.add(Op.ResolveMaybeLocal, (vm, { op1: _name }) => {
let name = vm.constants.getString(_name);
let locals = vm.scope().getPartialMap()!;

let ref = locals[name];
if (ref === undefined) {
ref = vm.getSelf().get(name);
}

vm.evalStack.push(ref);
});

APPEND_OPCODES.add(Op.RootScope, (vm, { op1: symbols, op2: bindCallerScope }) => {
vm.pushRootScope(symbols, !!bindCallerScope);
});
Expand Down
58 changes: 9 additions & 49 deletions packages/@glimmer/runtime/lib/compiled/opcodes/partial.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,10 @@
import { Opaque } from '@glimmer/util';
import { ReferenceCache, isConst, map } from '@glimmer/reference';
import { Assert } from './vm';
import { SymbolTable } from '@glimmer/interfaces';
import { APPEND_OPCODES, Op as Op } from '../../opcodes';

APPEND_OPCODES.add(Op.PutDynamicPartial, (vm, { op1: _symbolTable }) => {
let env = vm.env;
let symbolTable = vm.constants.getOther<SymbolTable>(_symbolTable);

function lookupPartial(name: Opaque) {
let normalized = String(name);

if (!env.hasPartial(normalized, symbolTable)) {
throw new Error(`Could not find a partial named "${normalized}"`);
}

return env.lookupPartial(normalized, symbolTable);
}

let reference = map(vm.frame.getOperand<Opaque>(), lookupPartial);
let cache = isConst(reference) ? undefined : new ReferenceCache(reference);
let definition = cache ? cache.peek() : reference.value();

vm.frame.setImmediate(definition);

if (cache) {
vm.updateWith(new Assert(cache));
}
});

APPEND_OPCODES.add(Op.PutPartial, (_vm, { op1: _definition }) => {
// let definition = vm.constants.getOther<PartialDefinition<Opaque>>(_definition);
// vm.frame.setImmediate(definition);
});

APPEND_OPCODES.add(Op.EvaluatePartial, (_vm, { op1: _symbolTable, op2: _cache }) => {
// let symbolTable = vm.constants.getOther<SymbolTable>(_symbolTable);
// let cache = vm.constants.getOther<Dict<PartialBlock>>(_cache);

// let { template } = vm.frame.getImmediate<PartialDefinition<Opaque>>();

// let block = cache[template.id];

// if (!block) {
// block = template.asPartial(symbolTable);
// }

// vm.invokePartial(block);
import { TemplateMeta } from '@glimmer/wire-format';
import { VersionedPathReference } from '@glimmer/reference';
import { APPEND_OPCODES, Op } from '../../opcodes';
import { PartialDefinition } from '../../partial';

APPEND_OPCODES.add(Op.GetPartialTemplate, vm => {
let stack = vm.evalStack;
let definition = stack.pop<VersionedPathReference<PartialDefinition<TemplateMeta>>>();
stack.push(definition.value().template.asPartial());
});
20 changes: 1 addition & 19 deletions packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import {
} from '../expressions/args';

import {
Block,
Program
Block
} from '../../scanner';

import {
Expand Down Expand Up @@ -124,29 +123,12 @@ APPEND_OPCODES.add(Op.BindNamedArgs, (vm, { op1: _names, op2: _symbols }) => {
vm.bindNamedArgs(names, symbols);
});

APPEND_OPCODES.add(Op.BindVirtualBlock, (vm, { op1: _layout, op2: _block }) => {
let layout = vm.getLocal<Block>(_layout);
let symbol = layout.symbolTable.getSymbol('yields', _block ? 'inverse' : 'default')!;
vm.scope().bindBlock(symbol, vm.evalStack.pop<Block>());
});

APPEND_OPCODES.add(Op.BindVirtualNamed, (vm, { op1: _layout, op2: _name }) => {
let expr = vm.evalStack.pop<VersionedPathReference<Opaque>>();
let layout = vm.getLocal<Program>(_layout);
let symbol = layout.symbolTable.getSymbol('named', vm.constants.getString(_name))!;
vm.scope().bindSymbol(symbol, expr);
});

APPEND_OPCODES.add(Op.BindBlocks, (vm, { op1: _names, op2: _symbols }) => {
let names = vm.constants.getArray(_names);
let symbols = vm.constants.getArray(_symbols);
vm.bindBlocks(names, symbols);
});

APPEND_OPCODES.add(Op.BindPartialArgs, (vm, { op1: symbol }) => {
vm.bindPartialArgs(symbol);
});

APPEND_OPCODES.add(Op.BindCallerScope, vm => vm.bindCallerScope());

APPEND_OPCODES.add(Op.BindDynamicScope, (vm, { op1: _names }) => {
Expand Down
Loading

0 comments on commit 702d1de

Please sign in to comment.