Skip to content
Permalink
Browse files
Apply poisoning to some native code pointers.
https://bugs.webkit.org/show_bug.cgi?id=180541
<rdar://problem/35916875>

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Renamed g_classInfoPoison to g_globalDataPoison.
Renamed g_masmPoison to g_jitCodePoison.
Introduced g_nativeCodePoison.
Applied g_nativeCodePoison to poisoning some native code pointers.

Introduced non-random Int32 poison values (in JSCPoison.h) for use with pointers
to malloc allocated data structures (where needed).

* API/JSCallbackFunction.h:
(JSC::JSCallbackFunction::functionCallback):
* JavaScriptCore.xcodeproj/project.pbxproj:
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
* llint/LowLevelInterpreter64.asm:
* runtime/CustomGetterSetter.h:
(JSC::CustomGetterSetter::getter const):
(JSC::CustomGetterSetter::setter const):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::getCallData):
(JSC::InternalFunction::getConstructData):
* runtime/InternalFunction.h:
(JSC::InternalFunction::nativeFunctionFor):
* runtime/JSCPoison.h: Added.
* runtime/JSCPoisonedPtr.cpp:
(JSC::initializePoison):
* runtime/JSCPoisonedPtr.h:
* runtime/Lookup.h:
* runtime/NativeExecutable.cpp:
(JSC::NativeExecutable::hashFor const):
* runtime/NativeExecutable.h:
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::setSingleTransition):
* runtime/StructureTransitionTable.h:
(JSC::StructureTransitionTable::StructureTransitionTable):
(JSC::StructureTransitionTable::isUsingSingleSlot const):
(JSC::StructureTransitionTable::map const):
(JSC::StructureTransitionTable::weakImpl const):
(JSC::StructureTransitionTable::setMap):

Source/WTF:

Ensure that the resultant poisoned bits still looks like a pointer in that its
bottom bits are 0, just like the alignment bits of a pointer.  This allows the
client to use the bottom bits of the poisoned bits as flag bits just like the
client was previously able to do with pointer values.

Note: we only ensure that the bottom alignment bits of the generated poison
value is 0.  We're not masking out the poisoned bits.  This means that the bottom
bits of the poisoned bits will only be null if the original pointer is aligned.
Hence, if the client applies the poison to an unaligned pointer, we do not lose
any information on the low bits.

Also removed 2 wrong assertions in PoisonedImpl's constructors.  We were
asserting that Poisoned will never be used with a null value, but that's invalid.
We do want to allow a null value so that we don't have to constantly do null
checks in the clients.  This was uncovered by some layout tests.

* wtf/Poisoned.cpp:
(WTF::makePoison):
* wtf/Poisoned.h:
(WTF::PoisonedImpl::PoisonedImpl):



Canonical link: https://commits.webkit.org/196479@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225659 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Mark Lam committed Dec 8, 2017
1 parent 329f002 commit c63f066ee645a143be4cf77922e276f912a9d315
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2006-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,9 +51,9 @@ class JSCallbackFunction : public InternalFunction {
JSCallbackFunction(VM&, Structure*, JSObjectCallAsFunctionCallback);
void finishCreation(VM&, const String& name);

JSObjectCallAsFunctionCallback functionCallback() { return m_callback; }
JSObjectCallAsFunctionCallback functionCallback() { return m_callback.unpoisoned(); }

JSObjectCallAsFunctionCallback m_callback;
Poisoned<g_nativeCodePoison, JSObjectCallAsFunctionCallback> m_callback;
};

} // namespace JSC
@@ -1,3 +1,50 @@
2017-12-07 Mark Lam <mark.lam@apple.com>

Apply poisoning to some native code pointers.
https://bugs.webkit.org/show_bug.cgi?id=180541
<rdar://problem/35916875>

Reviewed by Filip Pizlo.

Renamed g_classInfoPoison to g_globalDataPoison.
Renamed g_masmPoison to g_jitCodePoison.
Introduced g_nativeCodePoison.
Applied g_nativeCodePoison to poisoning some native code pointers.

Introduced non-random Int32 poison values (in JSCPoison.h) for use with pointers
to malloc allocated data structures (where needed).

* API/JSCallbackFunction.h:
(JSC::JSCallbackFunction::functionCallback):
* JavaScriptCore.xcodeproj/project.pbxproj:
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
* llint/LowLevelInterpreter64.asm:
* runtime/CustomGetterSetter.h:
(JSC::CustomGetterSetter::getter const):
(JSC::CustomGetterSetter::setter const):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::getCallData):
(JSC::InternalFunction::getConstructData):
* runtime/InternalFunction.h:
(JSC::InternalFunction::nativeFunctionFor):
* runtime/JSCPoison.h: Added.
* runtime/JSCPoisonedPtr.cpp:
(JSC::initializePoison):
* runtime/JSCPoisonedPtr.h:
* runtime/Lookup.h:
* runtime/NativeExecutable.cpp:
(JSC::NativeExecutable::hashFor const):
* runtime/NativeExecutable.h:
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::setSingleTransition):
* runtime/StructureTransitionTable.h:
(JSC::StructureTransitionTable::StructureTransitionTable):
(JSC::StructureTransitionTable::isUsingSingleSlot const):
(JSC::StructureTransitionTable::map const):
(JSC::StructureTransitionTable::weakImpl const):
(JSC::StructureTransitionTable::setMap):

2017-12-07 Joseph Pecoraro <pecoraro@apple.com>

Web Inspector: Fix style in remote inspector classes
@@ -1721,6 +1721,7 @@
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE2A87601F02381600EB31B2 /* MinimumReservedZoneSize.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2A875F1F02381600EB31B2 /* MinimumReservedZoneSize.h */; };
FE2B0B691FD227E00075DA5F /* JSCPoisonedPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2B0B671FD0D2960075DA5F /* JSCPoisonedPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE2B0B731FD9EF700075DA5F /* JSCPoison.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2B0B701FD8C4630075DA5F /* JSCPoison.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE3022D31E3D73A500BAC493 /* SigillCrashAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3022D11E3D739600BAC493 /* SigillCrashAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE3022D71E42857300BAC493 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3022D51E42856700BAC493 /* VMInspector.h */; };
FE318FE01CAC982F00DFCC54 /* ECMAScriptSpecInternalFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE318FDE1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.h */; };
@@ -4600,6 +4601,7 @@
FE2A875F1F02381600EB31B2 /* MinimumReservedZoneSize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinimumReservedZoneSize.h; sourceTree = "<group>"; };
FE2B0B671FD0D2960075DA5F /* JSCPoisonedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCPoisonedPtr.h; sourceTree = "<group>"; };
FE2B0B681FD0D2970075DA5F /* JSCPoisonedPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCPoisonedPtr.cpp; sourceTree = "<group>"; };
FE2B0B701FD8C4630075DA5F /* JSCPoison.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCPoison.h; sourceTree = "<group>"; };
FE2E6A7A1D6EA5FE0060F896 /* ThrowScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThrowScope.cpp; sourceTree = "<group>"; };
FE3022D01E3D739600BAC493 /* SigillCrashAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SigillCrashAnalyzer.cpp; sourceTree = "<group>"; };
FE3022D11E3D739600BAC493 /* SigillCrashAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SigillCrashAnalyzer.h; sourceTree = "<group>"; };
@@ -6543,6 +6545,7 @@
F692A8870255597D01FF60F7 /* JSCJSValue.cpp */,
14ABB36E099C076400E2A24F /* JSCJSValue.h */,
865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
FE2B0B701FD8C4630075DA5F /* JSCPoison.h */,
FE2B0B681FD0D2970075DA5F /* JSCPoisonedPtr.cpp */,
FE2B0B671FD0D2960075DA5F /* JSCPoisonedPtr.h */,
72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */,
@@ -8101,6 +8104,7 @@
0F338DFA1BE96AA80013C88F /* B3CCallValue.h in Headers */,
0F33FCFB1C1625BE00323F67 /* B3CFG.h in Headers */,
0FEC85061BDACDAC0080FF74 /* B3CheckSpecial.h in Headers */,
FE2B0B731FD9EF700075DA5F /* JSCPoison.h in Headers */,
0FEC85081BDACDAC0080FF74 /* B3CheckValue.h in Headers */,
0FEC850A1BDACDAC0080FF74 /* B3Common.h in Headers */,
0FDCE12D1FAFB4E5006F3901 /* IsoSubspace.h in Headers */,
@@ -507,7 +507,7 @@ class LowerMacros {
GPRReg scratch = params.gpScratch(0);
GPRReg poisonScratch = params.gpScratch(1);

jit.move(CCallHelpers::TrustedImm64(g_masmPoison), poisonScratch);
jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), poisonScratch);
jit.move(CCallHelpers::TrustedImmPtr(jumpTable), scratch);
jit.load64(CCallHelpers::BaseIndex(scratch, index, CCallHelpers::timesPtr()), scratch);
jit.xor64(poisonScratch, scratch);
@@ -13033,7 +13033,7 @@ void testInterpreter()
GPRReg poisonScratch = params.gpScratch(1);

jit.move(CCallHelpers::TrustedImmPtr(jumpTable), scratch);
jit.move(CCallHelpers::TrustedImm64(g_masmPoison), poisonScratch);
jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), poisonScratch);
jit.load64(CCallHelpers::BaseIndex(scratch, params[0].gpr(), CCallHelpers::timesPtr()), scratch);
jit.xor64(poisonScratch, scratch);
jit.jump(scratch);
@@ -8706,7 +8706,7 @@ void SpeculativeJIT::compileCheckSubClass(Node* node)
m_jit.emitLoadStructure(*m_jit.vm(), baseGPR, otherGPR, specifiedGPR);
m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR);
#if USE(JSVALUE64)
m_jit.move(CCallHelpers::TrustedImm64(g_classInfoPoison), specifiedGPR);
m_jit.move(CCallHelpers::TrustedImm64(g_globalDataPoison), specifiedGPR);
m_jit.xor64(specifiedGPR, otherGPR);
#endif
m_jit.move(CCallHelpers::TrustedImmPtr(node->classInfo()), specifiedGPR);
@@ -9784,7 +9784,7 @@ void SpeculativeJIT::emitSwitchIntJump(
data->fallThrough.block);
UNUSED_PARAM(poisonScratch); // Placate the 32-bit build.
#if USE(JSVALUE64)
m_jit.move(TrustedImm64(g_masmPoison), poisonScratch);
m_jit.move(TrustedImm64(g_jitCodePoison), poisonScratch);
#endif
m_jit.move(TrustedImmPtr(table.ctiOffsets.begin()), scratch);
m_jit.loadPtr(JITCompiler::BaseIndex(scratch, value, JITCompiler::timesPtr()), scratch);
@@ -11171,7 +11171,7 @@ class LowerDFGToB3 {

LValue structure = loadStructure(cell);
LValue poisonedClassInfo = m_out.loadPtr(structure, m_heaps.Structure_classInfo);
LValue classInfo = m_out.bitXor(poisonedClassInfo, m_out.constInt64(g_classInfoPoison));
LValue classInfo = m_out.bitXor(poisonedClassInfo, m_out.constInt64(g_globalDataPoison));
ValueFromBlock otherAtStart = m_out.anchor(classInfo);
m_out.jump(loop);

@@ -214,7 +214,7 @@ MacroAssemblerCodeRef virtualThunkFor(VM* vm, CallLinkInfo& callLinkInfo)
// Now we know that we have a CodeBlock, and we're committed to making a fast
// call.
#if USE(JSVALUE64)
jit.move(CCallHelpers::TrustedImm64(g_masmPoison), GPRInfo::regT1);
jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), GPRInfo::regT1);
jit.xor64(GPRInfo::regT1, GPRInfo::regT4);
#endif

@@ -307,9 +307,12 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, ThunkFunctionType thunkF
jit.emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, X86Registers::esi);
if (thunkFunctionType == ThunkFunctionType::JSFunction) {
jit.loadPtr(JSInterfaceJIT::Address(X86Registers::esi, JSFunction::offsetOfExecutable()), X86Registers::r9);
jit.call(JSInterfaceJIT::Address(X86Registers::r9, executableOffsetToFunction));
jit.loadPtr(JSInterfaceJIT::Address(X86Registers::r9, executableOffsetToFunction), X86Registers::r9);
} else
jit.call(JSInterfaceJIT::Address(X86Registers::esi, InternalFunction::offsetOfNativeFunctionFor(kind)));
jit.loadPtr(JSInterfaceJIT::Address(X86Registers::esi, InternalFunction::offsetOfNativeFunctionFor(kind)), X86Registers::r9);
jit.move(JSInterfaceJIT::TrustedImm64(g_nativeCodePoison), X86Registers::esi);
jit.xor64(X86Registers::esi, X86Registers::r9);
jit.call(X86Registers::r9);

#else
// Calling convention: f(ecx, edx, r8, r9, ...);
@@ -341,9 +344,13 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, ThunkFunctionType thunkF
jit.emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, ARM64Registers::x1);
if (thunkFunctionType == ThunkFunctionType::JSFunction) {
jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x1, JSFunction::offsetOfExecutable()), ARM64Registers::x2);
jit.call(JSInterfaceJIT::Address(ARM64Registers::x2, executableOffsetToFunction));
jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x2, executableOffsetToFunction), ARM64Registers::x2);
} else
jit.call(JSInterfaceJIT::Address(ARM64Registers::x1, InternalFunction::offsetOfNativeFunctionFor(kind)));
jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x1, InternalFunction::offsetOfNativeFunctionFor(kind)), ARM64Registers::x2);
jit.move(JSInterfaceJIT::TrustedImm64(g_nativeCodePoison), ARM64Registers::x1);
jit.xor64(ARM64Registers::x1, ARM64Registers::x2);
jit.call(ARM64Registers::x2);

#elif CPU(ARM) || CPU(MIPS)
#if CPU(MIPS)
// Allocate stack space for (unused) 16 bytes (8-byte aligned) for 4 arguments.
@@ -1163,7 +1170,7 @@ MacroAssemblerCodeRef boundThisNoArgsFunctionCallGenerator(VM* vm)
CCallHelpers::Jump noCode = jit.branchTestPtr(CCallHelpers::Zero, GPRInfo::regT0);

#if USE(JSVALUE64)
jit.move(CCallHelpers::TrustedImm64(g_masmPoison), GPRInfo::regT1);
jit.move(CCallHelpers::TrustedImm64(g_jitCodePoison), GPRInfo::regT1);
jit.xor64(GPRInfo::regT1, GPRInfo::regT0);
#endif
emitPointerValidation(jit, GPRInfo::regT0);
@@ -1950,7 +1950,7 @@ macro doCall(slowPath, prepareCall)
prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
else
loadp _g_masmPoison, t2
loadp _g_jitCodePoison, t2
xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
prepareCall(t2, t1, t3, t4)
callTargetFunction(t2)
@@ -2080,10 +2080,12 @@ macro nativeCallTrampoline(executableOffsetToFunction)
else
if X86_64_WIN
subp 32, sp
end
call executableOffsetToFunction[t1]
if X86_64_WIN
call executableOffsetToFunction[t1]
addp 32, sp
else
loadp _g_nativeCodePoison, t2
xorp executableOffsetToFunction[t1], t2
call t2
end
end

@@ -2119,10 +2121,12 @@ macro internalFunctionCallTrampoline(offsetOfFunction)
else
if X86_64_WIN
subp 32, sp
end
call offsetOfFunction[t1]
if X86_64_WIN
call offsetOfFunction[t1]
addp 32, sp
else
loadp _g_nativeCodePoison, t2
xorp offsetOfFunction[t1], t2
call t2
end
end

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Apple Inc. All rights reserved.
* Copyright (C) 2014-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@

#pragma once

#include "JSCPoisonedPtr.h"
#include "JSCell.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
@@ -47,8 +48,8 @@ class CustomGetterSetter : public JSCell {
return customGetterSetter;
}

CustomGetterSetter::CustomGetter getter() const { return m_getter; }
CustomGetterSetter::CustomSetter setter() const { return m_setter; }
CustomGetterSetter::CustomGetter getter() const { return m_getter.unpoisoned(); }
CustomGetterSetter::CustomSetter setter() const { return m_setter.unpoisoned(); }

static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
@@ -66,8 +67,11 @@ class CustomGetterSetter : public JSCell {
}

private:
CustomGetter m_getter;
CustomSetter m_setter;
template<typename T>
using PoisonedAccessor = Poisoned<g_nativeCodePoison, T>;

PoisonedAccessor<CustomGetter> m_getter;
PoisonedAccessor<CustomSetter> m_setter;
};

JS_EXPORT_PRIVATE bool callCustomSetter(ExecState*, CustomGetterSetter::CustomSetter, bool isAccessor, JSValue thisValue, JSValue);
@@ -88,7 +88,7 @@ CallType InternalFunction::getCallData(JSCell* cell, CallData& callData)
{
auto* function = jsCast<InternalFunction*>(cell);
ASSERT(function->m_functionForCall);
callData.native.function = function->m_functionForCall;
callData.native.function = function->m_functionForCall.unpoisoned();
return CallType::Host;
}

@@ -97,7 +97,7 @@ ConstructType InternalFunction::getConstructData(JSCell* cell, ConstructData& co
auto* function = jsCast<InternalFunction*>(cell);
if (function->m_functionForConstruct == callHostFunctionAsConstructor)
return ConstructType::None;
constructData.native.function = function->m_functionForConstruct;
constructData.native.function = function->m_functionForConstruct.unpoisoned();
return ConstructType::Host;
}

@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2003, 2006, 2007, 2008, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2003-2017 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
*
@@ -24,6 +24,7 @@
#pragma once

#include "CodeSpecializationKind.h"
#include "JSCPoisonedPtr.h"
#include "JSDestructibleObject.h"

namespace JSC {
@@ -55,9 +56,9 @@ class InternalFunction : public JSDestructibleObject {
NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
{
if (kind == CodeForCall)
return m_functionForCall;
return m_functionForCall.unpoisoned();
ASSERT(kind == CodeForConstruct);
return m_functionForConstruct;
return m_functionForConstruct.unpoisoned();
}

static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
@@ -69,6 +70,8 @@ class InternalFunction : public JSDestructibleObject {
}

protected:
using PoisonedNativeFunction = Poisoned<g_nativeCodePoison, NativeFunction>;

JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*, NativeFunction functionForCall, NativeFunction functionForConstruct);

enum class NameVisibility { Visible, Anonymous };
@@ -79,8 +82,8 @@ class InternalFunction : public JSDestructibleObject {
JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);

NativeFunction m_functionForCall;
NativeFunction m_functionForConstruct;
PoisonedNativeFunction m_functionForCall;
PoisonedNativeFunction m_functionForConstruct;
WriteBarrier<JSString> m_originalName;
};

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2017 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 <wtf/Poisoned.h>

namespace JSC {

enum Poison {
NotPoisoned = 0,
TransitionMapPoison,
WeakImplPoison,
};

} // namespace JSC

0 comments on commit c63f066

Please sign in to comment.