Skip to content

Commit

Permalink
Pipe a block's scope through the compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
mmun committed Sep 11, 2017
1 parent ae05bdb commit c7f052f
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 12 deletions.
5 changes: 5 additions & 0 deletions packages/@glimmer/opcode-compiler/lib/opcode-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -882,8 +882,13 @@ export abstract class OpcodeBuilder<Specifier> {
}
}

pushBlockScope(): void {
this.push(Op.PushBlockScope);
}

pushYieldableBlock(block: Option<CompilableBlock>): void {
this.pushSymbolTable(block && block.symbolTable);
this.pushBlockScope();
this.pushBlock(block);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Tag, TagWrapper, VersionedPathReference, Reference } from "@glimmer/ref
import { Arguments } from '../../vm/arguments';
import { ComponentState } from './component';
import { ComponentManager } from '../../internal-interfaces';
import { Scope } from '../../environment';
import { BlockSymbolTable } from "@glimmer/interfaces";
import { ICompilableTemplate } from "@glimmer/opcode-compiler";

Expand All @@ -17,6 +18,8 @@ export const CheckReference: Checker<Reference> =

export const CheckArguments = CheckInstanceof(Arguments);

export const CheckScope = CheckInstanceof(Scope);

export const CheckComponentManager: Checker<ComponentManager> =
CheckInterface({ getCapabilities: CheckFunction });

Expand Down
7 changes: 4 additions & 3 deletions packages/@glimmer/runtime/lib/compiled/opcodes/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
PublicComponentSpec
} from '../../component/interfaces';
import { normalizeStringValue } from '../../dom/normalize';
import { DynamicScope, ScopeBlock, ScopeSlot } from '../../environment';
import { DynamicScope, ScopeBlock, ScopeSlot, Scope } from '../../environment';
import { APPEND_OPCODES, UpdatingOpcode } from '../../opcodes';
import { UNDEFINED_REFERENCE } from '../../references';
import { UpdatingVM, VM } from '../../vm';
Expand All @@ -33,7 +33,7 @@ import { check, expectStackChange, CheckInstanceof, CheckFunction, CheckInterfac
import { Op, Register } from '@glimmer/vm';
import { TemplateMeta } from "@glimmer/wire-format";
import { ATTRS_BLOCK } from '@glimmer/opcode-compiler';
import { CheckReference, CheckArguments, CheckPathReference, CheckComponentState, CheckCompilableBlock } from './-debug-strip';
import { CheckReference, CheckArguments, CheckPathReference, CheckComponentState, CheckScope, CheckCompilableBlock } from './-debug-strip';

const ARGS = new Arguments();

Expand Down Expand Up @@ -441,9 +441,10 @@ APPEND_OPCODES.add(Op.InvokeComponentLayout, vm => {
let bindBlock = (name: string) => {
let symbol = symbols.indexOf(name);
let handle = check(stack.pop(), CheckOr(CheckOption(CheckHandle), CheckOption(CheckCompilableBlock)));
let blockScope = check(stack.pop(), CheckOption(CheckScope)) as Option<Scope>; // FIXME(mmun): shouldn't need to cast this
let table = check(stack.pop(), CheckOption(CheckBlockSymbolTable));

let block: Option<ScopeBlock> = table ? [handle!, table] : null;
let block: Option<ScopeBlock> = table ? [handle!, blockScope!, table] : null;

if (symbol !== -1) {
scope.bindBlock(symbol + 1, block);
Expand Down
13 changes: 9 additions & 4 deletions packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Opaque, Option } from '@glimmer/interfaces';
import { VersionedPathReference } from '@glimmer/reference';
import { Op } from '@glimmer/vm';
import { ScopeBlock } from '../../environment';
import { Scope, ScopeBlock } from '../../environment';
import { APPEND_OPCODES } from '../../opcodes';
import { FALSE_REFERENCE, TRUE_REFERENCE } from '../../references';
import { PublicVM } from '../../vm';
import { ConcatReference } from '../expressions/concat';
import { assert } from "@glimmer/util";
import { check, expectStackChange, CheckFunction, CheckOption, CheckHandle, CheckBlockSymbolTable, CheckOr } from '@glimmer/debug';
import { stackAssert } from './assert';
import { CheckArguments, CheckPathReference, CheckCompilableBlock } from './-debug-strip';
import { CheckArguments, CheckPathReference, CheckCompilableBlock, CheckScope } from './-debug-strip';

export type FunctionExpression<T> = (vm: PublicVM) => VersionedPathReference<T>;

Expand All @@ -36,9 +36,10 @@ APPEND_OPCODES.add(Op.SetVariable, (vm, { op1: symbol }) => {

APPEND_OPCODES.add(Op.SetBlock, (vm, { op1: symbol }) => {
let handle = check(vm.stack.pop(), CheckOr(CheckOption(CheckHandle), CheckCompilableBlock));
let scope = check(vm.stack.pop(), CheckScope) as Option<Scope>; // FIXME(mmun): shouldn't need to cast this
let table = check(vm.stack.pop(), CheckOption(CheckBlockSymbolTable));

let block: Option<ScopeBlock> = table ? [handle!, table] : null;
let block: Option<ScopeBlock> = table ? [handle!, scope!, table] : null;

vm.scope().bindBlock(symbol, block);
});
Expand Down Expand Up @@ -70,14 +71,16 @@ APPEND_OPCODES.add(Op.GetBlock, (vm, { op1: _block }) => {
let block = vm.scope().getBlock(_block);

if (block) {
stack.push(block[2]);
stack.push(block[1]);
stack.push(block[0]);
} else {
stack.push(null);
stack.push(null);
stack.push(null);
}

expectStackChange(vm.stack, 2, 'GetBlock');
expectStackChange(vm.stack, 3, 'GetBlock');
});

APPEND_OPCODES.add(Op.HasBlock, (vm, { op1: _block }) => {
Expand All @@ -86,7 +89,9 @@ APPEND_OPCODES.add(Op.HasBlock, (vm, { op1: _block }) => {
});

APPEND_OPCODES.add(Op.HasBlockParams, (vm) => {
// FIXME(mmun): should only need to push the symbol table
check(vm.stack.pop(), CheckOption(CheckOr(CheckHandle, CheckCompilableBlock)));
check(vm.stack.pop(), CheckOption(CheckScope));
let table = check(vm.stack.pop(), CheckOption(CheckBlockSymbolTable));

assert(table === null || (table && typeof table === 'object' && Array.isArray(table.parameters)), stackAssert('Option<BlockSymbolTable>', table));
Expand Down
15 changes: 15 additions & 0 deletions packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ import { initializeGuid, assert } from '@glimmer/util';
import { expectStackChange, CheckNumber, check, CheckInstanceof, CheckOption, CheckBlockSymbolTable, CheckHandle, CheckPrimitive } from '@glimmer/debug';
import { stackAssert } from './assert';
import { APPEND_OPCODES, UpdatingOpcode } from '../../opcodes';
import { Scope } from '../../environment';
import { PrimitiveReference } from '../../references';
import { CompilableTemplate } from '../../syntax/interfaces';
import { VM, UpdatingVM } from '../../vm';
import { Arguments } from '../../vm/arguments';
import { LazyConstants, PrimitiveType } from "@glimmer/program";
<<<<<<< ae05bdbd9fce6d71a49b2d8bc42d3908ff080114
import { CheckReference } from './-debug-strip';
||||||| merged common ancestors
import { VMHandle } from "@glimmer/opcode-compiler";
import { CheckReference } from './-debug-strip';
=======
import { VMHandle } from "@glimmer/opcode-compiler";
import { CheckReference, CheckScope } from './-debug-strip';
>>>>>>> Pipe a block's scope through the compiler

APPEND_OPCODES.add(Op.ChildScope, vm => vm.pushChildScope());

Expand Down Expand Up @@ -108,6 +117,11 @@ APPEND_OPCODES.add(Op.PushSymbolTable, (vm, { op1: _table }) => {
stack.push(vm.constants.getSymbolTable(_table));
});

APPEND_OPCODES.add(Op.PushBlockScope, (vm) => {
let stack = vm.stack;
stack.push(vm.scope());
});

APPEND_OPCODES.add(Op.CompileBlock, vm => {
let stack = vm.stack;
let block = stack.pop<Option<CompilableTemplate> | 0>();
Expand All @@ -128,6 +142,7 @@ APPEND_OPCODES.add(Op.InvokeYield, vm => {
let { stack } = vm;

let handle = check(stack.pop(), CheckOption(CheckHandle));
let _scope = check(stack.pop(), CheckOption(CheckScope)) as Option<Scope>; // FIXME(mmun): shouldn't need to cast this
let table = check(stack.pop(), CheckOption(CheckBlockSymbolTable));

assert(table === null || (table && typeof table === 'object' && Array.isArray(table.parameters)), stackAssert('Option<BlockSymbolTable>', table));
Expand Down
2 changes: 1 addition & 1 deletion packages/@glimmer/runtime/lib/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { Simple, RuntimeResolver, BlockSymbolTable, VMHandle } from "@glimmer/in
import { Component, ComponentManager } from "./internal-interfaces";
import { Program } from "@glimmer/program";

export type ScopeBlock = [VMHandle | ICompilableTemplate<BlockSymbolTable>, BlockSymbolTable];
export type ScopeBlock = [VMHandle | ICompilableTemplate<BlockSymbolTable>, Scope, BlockSymbolTable];
export type ScopeSlot = Option<VersionedPathReference<Opaque>> | Option<ScopeBlock>;

export interface DynamicScope {
Expand Down
14 changes: 10 additions & 4 deletions packages/@glimmer/vm/lib/-debug-strip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ OPCODE_METADATA(Op.PushSymbolTable, {
stackChange: 1
});

OPCODE_METADATA(Op.PushBlockScope, {
name: 'PushBlockScope',
stackChange: 1
});

OPCODE_METADATA(Op.CompileBlock, {
name: 'CompileBlock'
});
Expand All @@ -237,7 +242,8 @@ OPCODE_METADATA(Op.InvokeStatic, {

OPCODE_METADATA(Op.InvokeYield, clearsArgs({
name: 'InvokeYield',
argsPosition: 2
argsPosition: 3,
netPops: 1
}));

OPCODE_METADATA(Op.Jump, {
Expand Down Expand Up @@ -584,7 +590,7 @@ OPCODE_METADATA(Op.SetBlock, {
name: 'SetBlock',
ops: [ScopeSymbol('symbol')],
operands: 1,
stackChange: -2
stackChange: -3
});

OPCODE_METADATA(Op.GetVariable, {
Expand All @@ -604,7 +610,7 @@ OPCODE_METADATA(Op.GetBlock, {
name: 'GetBlock',
ops: [ScopeBlock('block')],
operands: 1,
stackChange: 2
stackChange: 3
});

OPCODE_METADATA(Op.HasBlock, {
Expand All @@ -617,7 +623,7 @@ OPCODE_METADATA(Op.HasBlock, {
OPCODE_METADATA(Op.HasBlockParams, {
name: 'HasBlockParams',
ops: [ScopeBlock('block')],
stackChange: -1
stackChange: -2
});

OPCODE_METADATA(Op.Concat, {
Expand Down
10 changes: 10 additions & 0 deletions packages/@glimmer/vm/lib/opcodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,16 @@ export const enum Op {
*/
CompileBlock,

/**
* Operation: Push a scope onto the stack.
* Format:
* (PushBlockScope #Scope)
* Operand Stack:
* ..., →
* ..., Scope
*/
PushBlockScope,

/**
* Operation: Push a symbol table onto the stack.
* Format:
Expand Down

0 comments on commit c7f052f

Please sign in to comment.