🤭
JSCのUCDを更新するスクリプト
正規表現のプロパティエスケープなどの実装のために、JavaScriptエンジンはUCD(=Unicode Character Database)に関する情報を知っている必要がある。
WebKitのJSエンジンであるJavaScriptCoreではUCDを ./Source/JavaScriptCore/ucd
配下にファイルとしてそのまま配置している。
Unicodeのバージョンが上がるとtest262の方に更新が入るので、それに追従する形でJSエンジンのUCDのバージョンを上げる必要がある。
前回 15.1 に上げたときはすべて手動でやったが、手動でやるのは面倒くさいのでスクリプトを書いた。
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const version = '16.0.0';
const versionWithoutPatch = '16.0';
const files = [
{ name: 'CaseFolding.txt', url: `https://unicode.org/Public/${version}/ucd/CaseFolding.txt` },
{ name: 'DerivedBinaryProperties.txt', url: `https://unicode.org/Public/${version}/ucd/extracted/DerivedBinaryProperties.txt` },
{ name: 'DerivedCoreProperties.txt', url: `https://unicode.org/Public/${version}/ucd/DerivedCoreProperties.txt` },
{ name: 'DerivedNormalizationProps.txt', url: `https://unicode.org/Public/${version}/ucd/DerivedNormalizationProps.txt` },
{ name: 'emoji-data.txt', url: `https://unicode.org/Public/${version}/ucd/emoji/emoji-data.txt` },
{ name: 'emoji-sequences.txt', url: `https://unicode.org/Public/emoji/${versionWithoutPatch}/emoji-sequences.txt` },
{ name: 'emoji-zwj-sequences.txt', url: `https://unicode.org/Public/emoji/${versionWithoutPatch}/emoji-zwj-sequences.txt` },
{ name: 'PropertyAliases.txt', url: `https://unicode.org/Public/${version}/ucd/PropertyAliases.txt` },
{ name: 'PropertyValueAliases.txt', url: `https://unicode.org/Public/${version}/ucd/PropertyValueAliases.txt` },
{ name: 'PropList.txt', url: `https://unicode.org/Public/${version}/ucd/PropList.txt` },
{ name: 'ScriptExtensions.txt', url: `https://unicode.org/Public/${version}/ucd/ScriptExtensions.txt` },
{ name: 'Scripts.txt', url: `https://unicode.org/Public/${version}/ucd/Scripts.txt` },
{ name: 'UnicodeData.txt', url: `https://unicode.org/Public/${version}/ucd/UnicodeData.txt` }
];
const targetDir = path.join(process.cwd(), 'Source', 'JavaScriptCore', 'ucd');
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
async function downloadFile(file) {
const filePath = path.join(targetDir, file.name);
try {
console.log(`Downloading ${file.name}...`);
const response = await fetch(file.url);
if (!response.ok) {
throw new Error(`Failed to download ${file.name}: ${response.statusText}`);
}
const fileStream = fs.createWriteStream(filePath);
const reader = response.body.getReader();
let done = false;
while (!done) {
const { value, done: readerDone } = await reader.read();
if (value) {
fileStream.write(value);
}
done = readerDone;
}
fileStream.close();
console.log(`${file.name} has been downloaded`);
} catch (error) {
console.error(`Error downloading ${file.name}: ${error.message}`);
}
}
(async () => {
await Promise.all(files.map(downloadFile));
})();
Discussion