Skip to content

Commit

Permalink
Test for change to cache templates by site, not contents (#972)
Browse files Browse the repository at this point in the history
* Test for change to cache templates by site, not contents

These tests are against a specification change based on discussion in
tc39/ecma262#840

The tests here passed on SpiderMonkey but failed on other
implementations, which implement the current specification.

* Add a test that caching is by source location, not function identity

* Update existing tests to reference the spec properly
  • Loading branch information
littledan authored and leobalter committed Feb 5, 2018
1 parent 31dfa87 commit d5fc8b2
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-gettemplateobject
description: Templates are cached by source location inside a function
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
}

var a = 1;
var firstObject = null;
var previousObject = null;

function factory() {
return function() {
tag`head${a}tail`;
}
}

factory()();
firstObject = previousObject;

assert(firstObject !== null);
previousObject = null;

factory()();

assert.sameValue(
previousObject,
firstObject,
'The realm\'s template cache is for source code locations in a function'
);

Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
esid: sec-gettemplateobject
description: Template caching using distinct expressions within `eval`
info: |
Previously-created template objects should be retrieved from the internal
template registry when their source is identical but their expressions
evaluate to different values and the tagged template is being evaluated in
an `eval` context.
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
Expand All @@ -23,4 +22,4 @@ assert(firstObject !== null);
previousObject = null;

eval('tag`head${b}tail`');
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
esid: sec-gettemplateobject
description: Template caching using distinct expressions within `new Function`
info: |
Previously-created template objects should be retrieved from the internal
template registry when their source is identical but their expressions
evaluate to different values and the tagged template is being evaluated in
an `eval` context.
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
Expand All @@ -23,8 +22,8 @@ assert(firstObject !== null);
previousObject = null;

(new Function('tag', 'a', 'b', 'return tag`head${b}tail`;'))(tag, 1, 2);
assert.sameValue(
assert.notSameValue(
previousObject,
firstObject,
'The realm\'s template cache is referenced when tagged templates are declared within "new Function" contexts and templated values differ'
'The realm\'s template cache is by site, not string contents'
);
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
esid: sec-gettemplateobject
description: Template caching using distinct expressions
info: |
Previously-created template objects should be retrieved from the internal
template registry when their source is identical but their expressions
evaluate to different values.
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
Expand All @@ -22,4 +22,4 @@ assert(firstObject !== null);
previousObject = null;

tag`head${b}tail`;
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
description: Templates are cached according to their "raw" representation
info: |
The internal template registry should be queried according to the "raw"
strings of the tagged template.
esid: sec-gettemplateobject
description: Templates are cached according to their site
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
var previousObject = null;
var firstObject = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
description: Templates are cached according to the number of "raw" strings
info: |
The internal template registry should be queried according to the number of
"raw" strings in the tagged template.
esid: sec-gettemplateobject
description: Templates are cached according to the site
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
var previousObject = null;
var firstObject = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
description: Template caching using identical expressions within `eval`
info: |
Previously-created template objects should be retrieved from the internal
template registry when their source is identical and the tagged template is
being evaluated in an `eval` context.
esid: sec-gettemplateobject
description: Templates are cached by site, even using identical expressions within `eval`
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
Expand All @@ -21,4 +21,4 @@ assert(firstObject !== null);
previousObject = null;

eval('tag`head${a}tail`');
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
description: Template caching using identical expressions within `new Function`
info: |
Previously-created template objects should be retrieved from the internal
template registry when their source is identical and the tagged template is
being evaluated in a `new Function` context.
esid: sec-gettemplateobject
description: Template caching is by site, using identical expressions within `new Function`
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
Expand All @@ -21,4 +21,4 @@ assert(firstObject !== null);
previousObject = null;

(new Function('tag', 'a', 'b', 'return tag`head${b}tail`;'))(tag, 1, 2);
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright (C) 2014 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 12.2.8
description: Template caching using identical expressions
info: |
Previously-created template objects should be retrieved from the internal
template registry when their source is identical.
esid: sec-gettemplateobject
description: Templates are cached by site, even when using identical expressions
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
Expand All @@ -20,8 +21,8 @@ assert(firstObject !== null);
previousObject = null;

tag`head${a}tail`;
assert.sameValue(
assert.notSameValue(
previousObject,
firstObject,
'The realm\'s template cache is used when tagged templates are executed in the source code directly'
'The realm\'s template cache is by site, not string contents'
);
3 changes: 1 addition & 2 deletions test/language/expressions/tagged-template/cache-realm.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ info: |
2. Let realm be the current Realm Record.
3. Let templateRegistry be realm.[[TemplateMap]].
4. For each element e of templateRegistry, do
a, If e.[[Strings]] and rawStrings contain the same values in the same
order, then
a. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
i. Return e.[[Array]].
features: [cross-realm]
---*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-gettemplateobject
description: Templates are cached by source location inside a function
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/

let templates = [];

function tag(templateObject) {
templates.push(templateObject);
}

let a = 1;
for (let i = 0; i < 2; i++) {
tag`head${a}tail`;
}

assert.sameValue(templates.length, 2);

assert.sameValue(
templates[0],
templates[1],
'The realm\'s template cache is for source code locations in a top-level script'
);


36 changes: 36 additions & 0 deletions test/language/expressions/tagged-template/cache-same-site.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-gettemplateobject
description: Templates are cached by source location inside a function
info: >
1. For each element _e_ of _templateRegistry_, do
1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then
1. Return _e_.[[Array]].
---*/
function tag(templateObject) {
previousObject = templateObject;
}

var a = 1;
var firstObject = null;
var previousObject = null;

function runTemplate() {
tag`head${a}tail`;
}

runTemplate();
firstObject = previousObject;

assert(firstObject !== null);
previousObject = null;

runTemplate();

assert.sameValue(
previousObject,
firstObject,
'The realm\'s template cache is for source code locations in a function'
);

0 comments on commit d5fc8b2

Please sign in to comment.