Test for change to cache templates by site, not contents (#972)

* Test for change to cache templates by site, not contents

These tests are against a specification change based on discussion in
https://github.com/tc39/ecma262/issues/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
This commit is contained in:
Daniel Ehrenberg 2018-02-05 20:40:19 +01:00 committed by Leo Balter
parent 31dfa8761a
commit d5fc8b25af
12 changed files with 159 additions and 54 deletions

View File

@ -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'
);

View File

@ -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;
@ -23,4 +22,4 @@ assert(firstObject !== null);
previousObject = null;
eval('tag`head${b}tail`');
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);

View File

@ -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;
@ -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'
);

View File

@ -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;
@ -22,4 +22,4 @@ assert(firstObject !== null);
previousObject = null;
tag`head${b}tail`;
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);

View File

@ -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;

View File

@ -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;

View File

@ -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;
@ -21,4 +21,4 @@ assert(firstObject !== null);
previousObject = null;
eval('tag`head${a}tail`');
assert.sameValue(previousObject, firstObject);
assert.notSameValue(previousObject, firstObject);

View File

@ -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;
@ -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);

View File

@ -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;
@ -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'
);

View File

@ -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]
---*/

View File

@ -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'
);

View File

@ -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'
);