Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (245212 => 245213)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2019-05-12 19:43:16 UTC (rev 245213)
@@ -963,6 +963,7 @@
runtime/Symbol.h
runtime/SymbolPrototype.h
runtime/SymbolTable.h
+ runtime/SymbolTableOrScopeDepth.h
runtime/TemplateObjectDescriptor.h
runtime/TestRunnerUtils.h
runtime/ThrowScope.h
Modified: trunk/Source/_javascript_Core/ChangeLog (245212 => 245213)
--- trunk/Source/_javascript_Core/ChangeLog 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-05-12 19:43:16 UTC (rev 245213)
@@ -1,3 +1,43 @@
+2019-05-12 Yusuke Suzuki <[email protected]>
+
+ [JSC] Compact generator code's bytecode size
+ https://bugs.webkit.org/show_bug.cgi?id=197822
+
+ Reviewed by Michael Saboff.
+
+ op_put_to_scope's symbolTableOrScopeDepth is represented as int. This was OK for the old bytecode format since
+ VirtualRegister / scope depth can be represented by int anyway. But it is problematic now since only int8_t range
+ will be represented in narrow bytecode. When this field is used for symbol table constant index, it is always
+ larger than FirstConstantRegisterIndex. So it always exceeds the range of int8_t, and results in wide bytecode.
+ It makes all generator's op_put_to_scope wide bytecode.
+
+ In this patch, we introduce a new (logically) union type SymbolTableOrScopeDepth. It holds unsigned value, and we store the
+ SymbolTableConstantIndex - FirstConstantRegisterIndex in this unsigned value to make op_put_to_scope narrow bytecode.
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * bytecode/BytecodeGeneratorification.cpp:
+ (JSC::BytecodeGeneratorification::run):
+ * bytecode/BytecodeList.rb:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finishCreation):
+ * bytecode/Fits.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitProfileType):
+ (JSC::BytecodeGenerator::emitPutToScope):
+ (JSC::BytecodeGenerator::localScopeDepth const):
+ * bytecompiler/BytecodeGenerator.h:
+ * runtime/SymbolTableOrScopeDepth.h: Added.
+ (JSC::SymbolTableOrScopeDepth::symbolTable):
+ (JSC::SymbolTableOrScopeDepth::scopeDepth):
+ (JSC::SymbolTableOrScopeDepth::raw):
+ (JSC::SymbolTableOrScopeDepth::symbolTable const):
+ (JSC::SymbolTableOrScopeDepth::scopeDepth const):
+ (JSC::SymbolTableOrScopeDepth::raw const):
+ (JSC::SymbolTableOrScopeDepth::dump const):
+ (JSC::SymbolTableOrScopeDepth::SymbolTableOrScopeDepth):
+
2019-05-10 Saam barati <[email protected]>
Call to JSToWasmICCallee::createStructure passes in wrong prototype value
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (245212 => 245213)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-05-12 19:43:16 UTC (rev 245213)
@@ -1742,6 +1742,7 @@
DE26E9031CB5DD0500D2BE82 /* BuiltinExecutableCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = DE26E9021CB5DD0500D2BE82 /* BuiltinExecutableCreator.h */; };
DEA7E2451BBC677F00D78440 /* JSTypedArrayViewPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E31179AA2288386100514B2C /* SymbolTableOrScopeDepth.h in Headers */ = {isa = PBXBuildFile; fileRef = E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */; settings = {ATTRIBUTES = (Private, ); }; };
E31618131EC5FE170006A218 /* DOMAnnotation.h in Headers */ = {isa = PBXBuildFile; fileRef = E31618101EC5FE080006A218 /* DOMAnnotation.h */; settings = {ATTRIBUTES = (Private, ); }; };
E31618151EC5FE270006A218 /* DOMAttributeGetterSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = E31618121EC5FE080006A218 /* DOMAttributeGetterSetter.h */; settings = {ATTRIBUTES = (Private, ); }; };
E318CBC11B8AEF5100A2929D /* JSModuleNamespaceObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E318CBBF1B8AEF5100A2929D /* JSModuleNamespaceObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4721,6 +4722,7 @@
E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VM.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = VM.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E30677971B8BC6F5003F87F0 /* ModuleLoader.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = ModuleLoader.js; sourceTree = "<group>"; };
+ E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolTableOrScopeDepth.h; sourceTree = "<group>"; };
E31618101EC5FE080006A218 /* DOMAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAnnotation.h; sourceTree = "<group>"; };
E31618111EC5FE080006A218 /* DOMAttributeGetterSetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMAttributeGetterSetter.cpp; sourceTree = "<group>"; };
E31618121EC5FE080006A218 /* DOMAttributeGetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAttributeGetterSetter.h; sourceTree = "<group>"; };
@@ -7299,6 +7301,7 @@
705B41AA1A6E501E00716757 /* SymbolPrototype.h */,
0F919D2715856770004A4E7D /* SymbolTable.cpp */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
+ E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */,
BDB4B5E099CD4C1BB3C1CF05 /* TemplateObjectDescriptor.cpp */,
70ECA6041AFDBEA200449739 /* TemplateObjectDescriptor.h */,
0FA2C17917D7CF84009D015F /* TestRunnerUtils.cpp */,
@@ -9857,6 +9860,7 @@
705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
996B73281BDA08EF00331B84 /* SymbolPrototype.lut.h in Headers */,
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
+ E31179AA2288386100514B2C /* SymbolTableOrScopeDepth.h in Headers */,
0FD79A2D1EBBBDBB00DA88D3 /* Synchronousness.h in Headers */,
0F1FB38F1E173A6700A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h in Headers */,
A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp (245212 => 245213)
--- trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp 2019-05-12 19:43:16 UTC (rev 245213)
@@ -252,7 +252,7 @@
storage.identifierIndex, // identifier
operand, // value
GetPutInfo(DoNotThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization), // info
- m_generatorFrameSymbolTableIndex, // symbol table constant index
+ SymbolTableOrScopeDepth::symbolTable(VirtualRegister { m_generatorFrameSymbolTableIndex }), // symbol table constant index
storage.scopeOffset.offset() // scope offset
);
});
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.rb (245212 => 245213)
--- trunk/Source/_javascript_Core/bytecode/BytecodeList.rb 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.rb 2019-05-12 19:43:16 UTC (rev 245213)
@@ -50,6 +50,7 @@
:StructureID,
:StructureChain,
:SymbolTable,
+ :SymbolTableOrScopeDepth,
:ToThisStatus,
:TypeLocation,
:WatchpointSet,
@@ -881,7 +882,7 @@
value: VirtualRegister, # offset 3
# $begin: :private,
getPutInfo: GetPutInfo,
- symbolTableOrScopeDepth: int,
+ symbolTableOrScopeDepth: SymbolTableOrScopeDepth,
offset: unsigned,
},
metadata: {
@@ -977,7 +978,7 @@
op :profile_type,
args: {
targetVirtualRegister: VirtualRegister,
- symbolTableOrScopeDepth: int,
+ symbolTableOrScopeDepth: SymbolTableOrScopeDepth,
flag: ProfileTypeBytecodeFlag,
identifier?: unsigned,
resolveType: ResolveType,
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (245212 => 245213)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2019-05-12 19:43:16 UTC (rev 245213)
@@ -643,7 +643,7 @@
if (bytecode.m_getPutInfo.resolveType() == LocalClosureVar) {
// Only do watching if the property we're putting to is not anonymous.
if (bytecode.m_var != UINT_MAX) {
- SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(bytecode.m_symbolTableOrScopeDepth));
+ SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(bytecode.m_symbolTableOrScopeDepth.symbolTable().offset()));
const Identifier& ident = identifier(bytecode.m_var);
ConcurrentJSLocker locker(symbolTable->m_lock);
auto iter = symbolTable->find(locker, ident.impl());
@@ -657,7 +657,7 @@
const Identifier& ident = identifier(bytecode.m_var);
metadata.m_watchpointSet = nullptr;
- ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), bytecode.m_symbolTableOrScopeDepth, scope, ident, Put, bytecode.m_getPutInfo.resolveType(), bytecode.m_getPutInfo.initializationMode());
+ ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), bytecode.m_symbolTableOrScopeDepth.scopeDepth(), scope, ident, Put, bytecode.m_getPutInfo.resolveType(), bytecode.m_getPutInfo.initializationMode());
RETURN_IF_EXCEPTION(throwScope, false);
metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode());
@@ -687,7 +687,7 @@
switch (bytecode.m_flag) {
case ProfileTypeBytecodeClosureVar: {
const Identifier& ident = identifier(bytecode.m_identifier);
- unsigned localScopeDepth = bytecode.m_symbolTableOrScopeDepth;
+ unsigned localScopeDepth = bytecode.m_symbolTableOrScopeDepth.scopeDepth();
// Even though type profiling may be profiling either a Get or a Put, we can always claim a Get because
// we're abstractly "read"ing from a JSScope.
ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization);
@@ -711,7 +711,7 @@
break;
}
case ProfileTypeBytecodeLocallyResolved: {
- int symbolTableIndex = bytecode.m_symbolTableOrScopeDepth;
+ int symbolTableIndex = bytecode.m_symbolTableOrScopeDepth.symbolTable().offset();
SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex));
const Identifier& ident = identifier(bytecode.m_identifier);
ConcurrentJSLocker locker(symbolTable->m_lock);
Modified: trunk/Source/_javascript_Core/bytecode/Fits.h (245212 => 245213)
--- trunk/Source/_javascript_Core/bytecode/Fits.h 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/bytecode/Fits.h 2019-05-12 19:43:16 UTC (rev 245213)
@@ -33,6 +33,7 @@
#include "PutByIdFlags.h"
#include "ResultType.h"
#include "SpecialPointer.h"
+#include "SymbolTableOrScopeDepth.h"
#include "VirtualRegister.h"
#include <type_traits>
@@ -133,6 +134,25 @@
};
template<>
+struct Fits<SymbolTableOrScopeDepth, OpcodeSize::Narrow> {
+ static bool check(SymbolTableOrScopeDepth u)
+ {
+ return u.raw() <= UINT8_MAX;
+ }
+
+ static uint8_t convert(SymbolTableOrScopeDepth u)
+ {
+ ASSERT(check(u));
+ return static_cast<uint8_t>(u.raw());
+ }
+
+ static SymbolTableOrScopeDepth convert(uint8_t u)
+ {
+ return SymbolTableOrScopeDepth::raw(u);
+ }
+};
+
+template<>
struct Fits<Special::Pointer, OpcodeSize::Narrow> : Fits<int, OpcodeSize::Narrow> {
using Base = Fits<int, OpcodeSize::Narrow>;
static bool check(Special::Pointer sp) { return Base::check(static_cast<int>(sp)); }
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (245212 => 245213)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2019-05-12 19:43:16 UTC (rev 245213)
@@ -551,7 +551,7 @@
entry.disableWatching(*m_vm);
functionSymbolTable->set(NoLockingNecessary, name, entry);
}
- OpPutToScope::emit(this, m_lexicalEnvironmentRegister, UINT_MAX, virtualRegisterForArgument(1 + i), GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization), symbolTableConstantIndex, offset.offset());
+ OpPutToScope::emit(this, m_lexicalEnvironmentRegister, UINT_MAX, virtualRegisterForArgument(1 + i), GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization), SymbolTableOrScopeDepth::symbolTable(VirtualRegister { symbolTableConstantIndex }), offset.offset());
}
// This creates a scoped arguments object and copies the overflow arguments into the
@@ -589,7 +589,7 @@
static_cast<const BindingNode*>(parameters.at(i).first)->boundProperty();
functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(offset)));
- OpPutToScope::emit(this, m_lexicalEnvironmentRegister, addConstant(ident), virtualRegisterForArgument(1 + i), GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization), symbolTableConstantIndex, offset.offset());
+ OpPutToScope::emit(this, m_lexicalEnvironmentRegister, addConstant(ident), virtualRegisterForArgument(1 + i), GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization), SymbolTableOrScopeDepth::symbolTable(VirtualRegister { symbolTableConstantIndex }), offset.offset());
}
}
@@ -1803,7 +1803,7 @@
if (!registerToProfile)
return;
- OpProfileType::emit(this, registerToProfile, 0, flag, { }, resolveType());
+ OpProfileType::emit(this, registerToProfile, { }, flag, { }, resolveType());
// Don't emit _expression_ info for this version of profile type. This generally means
// we're profiling information for something that isn't in the actual text of a _javascript_
@@ -1823,7 +1823,7 @@
if (!registerToProfile)
return;
- OpProfileType::emit(this, registerToProfile, 0, flag, { }, resolveType());
+ OpProfileType::emit(this, registerToProfile, { }, flag, { }, resolveType());
emitTypeProfilerExpressionInfo(startDivot, endDivot);
}
@@ -1836,14 +1836,14 @@
return;
ProfileTypeBytecodeFlag flag;
- int symbolTableOrScopeDepth;
+ SymbolTableOrScopeDepth symbolTableOrScopeDepth;
if (var.local() || var.offset().isScope()) {
flag = ProfileTypeBytecodeLocallyResolved;
ASSERT(var.symbolTableConstantIndex());
- symbolTableOrScopeDepth = var.symbolTableConstantIndex();
+ symbolTableOrScopeDepth = SymbolTableOrScopeDepth::symbolTable(VirtualRegister { var.symbolTableConstantIndex() });
} else {
flag = ProfileTypeBytecodeClosureVar;
- symbolTableOrScopeDepth = localScopeDepth();
+ symbolTableOrScopeDepth = SymbolTableOrScopeDepth::scopeDepth(localScopeDepth());
}
OpProfileType::emit(this, registerToProfile, symbolTableOrScopeDepth, flag, addConstant(var.ident()), resolveType());
@@ -2512,18 +2512,18 @@
case VarKind::Scope:
case VarKind::Invalid: {
GetPutInfo getPutInfo(0);
- int scopeDepth;
+ SymbolTableOrScopeDepth symbolTableOrScopeDepth;
ScopeOffset offset;
if (variable.offset().isScope()) {
offset = variable.offset().scopeOffset();
getPutInfo = GetPutInfo(resolveMode, LocalClosureVar, initializationMode);
- scopeDepth = variable.symbolTableConstantIndex();
+ symbolTableOrScopeDepth = SymbolTableOrScopeDepth::symbolTable(VirtualRegister { variable.symbolTableConstantIndex() });
} else {
ASSERT(resolveType() != LocalClosureVar);
getPutInfo = GetPutInfo(resolveMode, resolveType(), initializationMode);
- scopeDepth = localScopeDepth();
+ symbolTableOrScopeDepth = SymbolTableOrScopeDepth::scopeDepth(localScopeDepth());
}
- OpPutToScope::emit(this, scope, addConstant(variable.ident()), value, getPutInfo, scopeDepth, !!offset ? offset.offset() : 0);
+ OpPutToScope::emit(this, scope, addConstant(variable.ident()), value, getPutInfo, symbolTableOrScopeDepth, !!offset ? offset.offset() : 0);
m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return value;
} }
@@ -3743,7 +3743,7 @@
return dst;
}
-int BytecodeGenerator::localScopeDepth() const
+unsigned BytecodeGenerator::localScopeDepth() const
{
return m_localScopeDepth;
}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (245212 => 245213)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2019-05-11 23:17:17 UTC (rev 245212)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2019-05-12 19:43:16 UTC (rev 245213)
@@ -1235,10 +1235,10 @@
SegmentedVector<Label, 32> m_labels;
SegmentedVector<LabelScope, 32> m_labelScopes;
unsigned m_finallyDepth { 0 };
- int m_localScopeDepth { 0 };
+ unsigned m_localScopeDepth { 0 };
const CodeType m_codeType;
- int localScopeDepth() const;
+ unsigned localScopeDepth() const;
void pushLocalControlFlowScope();
void popLocalControlFlowScope();
Added: trunk/Source/_javascript_Core/runtime/SymbolTableOrScopeDepth.h (0 => 245213)
--- trunk/Source/_javascript_Core/runtime/SymbolTableOrScopeDepth.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/SymbolTableOrScopeDepth.h 2019-05-12 19:43:16 UTC (rev 245213)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "VirtualRegister.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+class SymbolTableOrScopeDepth {
+public:
+ SymbolTableOrScopeDepth() = default;
+
+ static SymbolTableOrScopeDepth symbolTable(VirtualRegister reg)
+ {
+ ASSERT(reg.isConstant());
+ return SymbolTableOrScopeDepth(reg.offset() - FirstConstantRegisterIndex);
+ }
+
+ static SymbolTableOrScopeDepth scopeDepth(unsigned scopeDepth)
+ {
+ return SymbolTableOrScopeDepth(scopeDepth);
+ }
+
+ static SymbolTableOrScopeDepth raw(unsigned value)
+ {
+ return SymbolTableOrScopeDepth(value);
+ }
+
+ VirtualRegister symbolTable() const
+ {
+ return VirtualRegister(m_raw + FirstConstantRegisterIndex);
+ }
+
+ unsigned scopeDepth() const
+ {
+ return m_raw;
+ }
+
+ unsigned raw() const { return m_raw; }
+
+ void dump(PrintStream& out) const
+ {
+ out.print(m_raw);
+ }
+
+private:
+ SymbolTableOrScopeDepth(unsigned value)
+ : m_raw(value)
+ { }
+
+ unsigned m_raw { 0 };
+};
+
+} // namespace JSC