Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: Source/core/css/CSSValue.h

Issue 1164573002: CSSValue Immediates: Change CSSValue to an object instead of a pointer (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Some small fixes to (hopefully) fix some broken tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 12 matching lines...) Expand all
23 23
24 #include "core/CoreExport.h" 24 #include "core/CoreExport.h"
25 #include "platform/heap/Handle.h" 25 #include "platform/heap/Handle.h"
26 #include "platform/weborigin/KURL.h" 26 #include "platform/weborigin/KURL.h"
27 #include "wtf/HashMap.h" 27 #include "wtf/HashMap.h"
28 #include "wtf/ListHashSet.h" 28 #include "wtf/ListHashSet.h"
29 #include "wtf/RefCounted.h" 29 #include "wtf/RefCounted.h"
30 #include "wtf/RefPtr.h" 30 #include "wtf/RefPtr.h"
31 31
32 namespace blink { 32 namespace blink {
33 33
Timothy Loh 2015/06/02 04:54:03 This stuff should be moved to CSSValueObject.{h,cp
sashab 2015/06/05 06:16:29 Done.
34 class CORE_EXPORT CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CS SValue> { 34 class CORE_EXPORT CSSValueObject : public RefCountedWillBeGarbageCollectedFinali zed<CSSValueObject> {
35 public: 35 public:
36 #if ENABLE(OILPAN) 36 #if ENABLE(OILPAN)
37 // Override operator new to allocate CSSValue subtype objects onto 37 // Override operator new to allocate CSSValueObject subtype objects onto
38 // a dedicated heap. 38 // a dedicated heap.
39 GC_PLUGIN_IGNORE("crbug.com/443854") 39 GC_PLUGIN_IGNORE("crbug.com/443854")
40 void* operator new(size_t size) 40 void* operator new(size_t size)
41 { 41 {
42 return allocateObject(size); 42 return allocateObject(size);
43 } 43 }
44 static void* allocateObject(size_t size) 44 static void* allocateObject(size_t size)
45 { 45 {
46 ThreadState* state = ThreadStateFor<ThreadingTrait<CSSValue>::Affinity>: :state(); 46 ThreadState* state = ThreadStateFor<ThreadingTrait<CSSValueObject>::Affi nity>::state();
47 return Heap::allocateOnHeapIndex(state, size, CSSValueHeapIndex, GCInfoT rait<CSSValue>::index()); 47 return Heap::allocateOnHeapIndex(state, size, CSSValueHeapIndex, GCInfoT rait<CSSValueObject>::index());
48 } 48 }
49 #else 49 #else
50 // Override RefCounted's deref() to ensure operator delete is called on 50 // Override RefCounted's deref() to ensure operator delete is called on
51 // the appropriate subclass type. 51 // the appropriate subclass type.
52 void deref() 52 void deref()
53 { 53 {
54 if (derefBase()) 54 if (derefBase())
55 destroy(); 55 destroy();
56 } 56 }
57 #endif // !ENABLE(OILPAN) 57 #endif // !ENABLE(OILPAN)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 bool isLineBoxContainValue() const { return m_classType == LineBoxContainCla ss; } 89 bool isLineBoxContainValue() const { return m_classType == LineBoxContainCla ss; }
90 bool isCalcValue() const {return m_classType == CalculationClass; } 90 bool isCalcValue() const {return m_classType == CalculationClass; }
91 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAr easClass; } 91 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAr easClass; }
92 bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; } 92 bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
93 bool isContentDistributionValue() const { return m_classType == CSSContentDi stributionClass; } 93 bool isContentDistributionValue() const { return m_classType == CSSContentDi stributionClass; }
94 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } 94 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
95 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass ; } 95 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass ; }
96 96
97 bool hasFailedOrCanceledSubresources() const; 97 bool hasFailedOrCanceledSubresources() const;
98 98
99 bool equals(const CSSValue&) const; 99 bool equals(const CSSValueObject&) const;
100 100
101 void finalizeGarbageCollectedObject(); 101 void finalizeGarbageCollectedObject();
102 DEFINE_INLINE_TRACE_AFTER_DISPATCH() { } 102 DEFINE_INLINE_TRACE_AFTER_DISPATCH() { }
103 DECLARE_TRACE(); 103 DECLARE_TRACE();
104 104
105 // ~CSSValue should be public, because non-public ~CSSValue causes C2248 105 // ~CSSValueObject should be public, because non-public ~CSSValueObject caus es C2248
106 // error: 'blink::CSSValue::~CSSValue' : cannot access protected member 106 // error: 'blink::CSSValueObject::~CSSValueObject' : cannot access protected member
107 // declared in class 'blink::CSSValue' when compiling 107 // declared in class 'blink::CSSValueObject' when compiling
108 // 'source\wtf\refcounted.h' by using msvc. 108 // 'source\wtf\refcounted.h' by using msvc.
109 ~CSSValue() { } 109 ~CSSValueObject() { }
110 110
111 protected: 111 protected:
112 112
113 static const size_t ClassTypeBits = 6; 113 static const size_t ClassTypeBits = 6;
114 enum ClassType { 114 enum ClassType {
115 PrimitiveClass, 115 PrimitiveClass,
116 116
117 // Image classes. 117 // Image classes.
118 ImageClass, 118 ImageClass,
119 CursorImageClass, 119 CursorImageClass,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 160
161 static const size_t ValueListSeparatorBits = 2; 161 static const size_t ValueListSeparatorBits = 2;
162 enum ValueListSeparator { 162 enum ValueListSeparator {
163 SpaceSeparator, 163 SpaceSeparator,
164 CommaSeparator, 164 CommaSeparator,
165 SlashSeparator 165 SlashSeparator
166 }; 166 };
167 167
168 ClassType classType() const { return static_cast<ClassType>(m_classType); } 168 ClassType classType() const { return static_cast<ClassType>(m_classType); }
169 169
170 explicit CSSValue(ClassType classType) 170 explicit CSSValueObject(ClassType classType)
171 : m_primitiveUnitType(0) 171 : m_primitiveUnitType(0)
172 , m_hasCachedCSSText(false) 172 , m_hasCachedCSSText(false)
173 , m_isQuirkValue(false) 173 , m_isQuirkValue(false)
174 , m_valueListSeparator(SpaceSeparator) 174 , m_valueListSeparator(SpaceSeparator)
175 , m_classType(classType) 175 , m_classType(classType)
176 { 176 {
177 } 177 }
178 178
179 // NOTE: This class is non-virtual for memory and performance reasons. 179 // NOTE: This class is non-virtual for memory and performance reasons.
180 // Don't go making it virtual again unless you know exactly what you're doin g! 180 // Don't go making it virtual again unless you know exactly what you're doin g!
181 181
182 private: 182 private:
183 void destroy(); 183 void destroy();
184 184
185 protected: 185 protected:
186 // The bits in this section are only used by specific subclasses but kept he re 186 // The bits in this section are only used by specific subclasses but kept he re
187 // to maximize struct packing. 187 // to maximize struct packing.
188 188
189 // CSSPrimitiveValue bits: 189 // CSSPrimitiveValue bits:
190 unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType 190 unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType
191 mutable unsigned m_hasCachedCSSText : 1; 191 mutable unsigned m_hasCachedCSSText : 1;
192 unsigned m_isQuirkValue : 1; 192 unsigned m_isQuirkValue : 1;
193 193
194 unsigned m_valueListSeparator : ValueListSeparatorBits; 194 unsigned m_valueListSeparator : ValueListSeparatorBits;
195 195
196 private: 196 private:
197 unsigned m_classType : ClassTypeBits; // ClassType 197 unsigned m_classType : ClassTypeBits; // ClassType
198 }; 198 };
199 199
200 template<typename CSSValueType, size_t inlineCapacity> 200 // A non-nullable container for CSSValueObject. Takes ownership of the passed
201 inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSV alueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMemb er<CSSValueType>, inlineCapacity>& secondVector) 201 // CSSValueObject.
202 class CORE_EXPORT CSSValue : public NoBaseWillBeGarbageCollectedFinalized<CSSVal ue> {
203 friend class NullableCSSValue;
204 public:
205 // Not explicit to allow for casting.
206 CSSValue(const CSSValueObject* cssValueObject)
Timothy Loh 2015/06/02 04:54:03 This ctor seems wrong, I think we should be creati
sashab 2015/06/05 06:16:30 Done.
207 : m_data(const_cast<CSSValueObject*>(cssValueObject))
208 {
209 ASSERT(m_data);
210 m_data->ref();
211 }
212
213 template<class T> CSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject)
214 : m_data(cssValueObject.leakRef())
215 {
216 ASSERT(m_data);
217 m_data->ref();
218 }
219
220 template <class T> CSSValue(RefPtrWillBeRawPtr<T> cssValueObject)
Timothy Loh 2015/06/02 04:54:03 extra space after template :|
sashab 2015/06/05 06:16:29 Ty! Didn't notice
221 : m_data(cssValueObject.release().leakRef())
222 {
223 ASSERT(m_data);
224 m_data->ref();
225 }
226
227 CSSValue(const CSSValue& cssValue)
228 : m_data(cssValue.m_data)
229 {
230 m_data->ref();
231 }
232
233 ~CSSValue()
234 {
235 m_data->deref();
236 }
237
238 CSSValue& operator=(const CSSValue& rhs)
239 {
240 m_data->deref();
Timothy Loh 2015/06/02 04:54:03 Should switch order of ref and deref so that assig
sashab 2015/06/05 06:16:30 Ah, good one!
241 rhs.m_data->ref();
242 m_data = rhs.m_data;
243 return *this;
244 }
245
246 bool operator==(const CSSValue& other) const
247 {
248 return m_data->equals(*other.m_data);
249 }
250
251 // TODO: Remove this and update callsites to use operator== instead.
252 bool equals(const CSSValue& other) const
253 {
254 return m_data->equals(*other.m_data);
255 }
256
257 bool ptrEquals(const CSSValue& other) const
258 {
259 return m_data == other.m_data;
260 }
261
262 // Methods that proxy to CSSValueObject.
263 String cssText() const { return m_data->cssText(); }
264 bool hasFailedOrCanceledSubresources() const { return m_data->hasFailedOrCan celedSubresources(); };
265 bool isPrimitiveValue() const { return m_data->isPrimitiveValue(); }
266 bool isValueList() const { return m_data->isValueList(); }
267 bool isBaseValueList() const { return m_data->isBaseValueList(); }
268 bool isBorderImageSliceValue() const { return m_data->isBorderImageSliceValu e(); }
269 bool isCanvasValue() const { return m_data->isCanvasValue(); }
270 bool isCursorImageValue() const { return m_data->isCursorImageValue(); }
271 bool isCrossfadeValue() const { return m_data->isCrossfadeValue(); }
272 bool isFontFeatureValue() const { return m_data->isFontFeatureValue(); }
273 bool isFontFaceSrcValue() const { return m_data->isFontFaceSrcValue(); }
274 bool isFunctionValue() const { return m_data->isFunctionValue(); }
275 bool isImageGeneratorValue() const { return m_data->isImageGeneratorValue(); }
276 bool isGradientValue() const { return m_data->isGradientValue(); }
277 bool isImageSetValue() const { return m_data->isImageSetValue(); }
278 bool isImageValue() const { return m_data->isImageValue(); }
279 bool isImplicitInitialValue() const { return m_data->isImplicitInitialValue( ); };
280 bool isInheritedValue() const { return m_data->isInheritedValue(); };
281 bool isInitialValue() const { return m_data->isInitialValue(); };
282 bool isUnsetValue() const { return m_data->isUnsetValue(); };
283 bool isCSSWideKeyword() const { return m_data->isCSSWideKeyword(); };
284 bool isLinearGradientValue() const { return m_data->isLinearGradientValue(); };
285 bool isPathValue() const { return m_data->isPathValue(); };
286 bool isRadialGradientValue() const { return m_data->isRadialGradientValue(); };
287 bool isReflectValue() const { return m_data->isReflectValue(); };
288 bool isShadowValue() const { return m_data->isShadowValue(); };
289 bool isCubicBezierTimingFunctionValue() const { return m_data->isCubicBezier TimingFunctionValue(); };
290 bool isStepsTimingFunctionValue() const { return m_data->isStepsTimingFuncti onValue(); };
291 bool isLineBoxContainValue() const { return m_data->isLineBoxContainValue(); };
292 bool isCalcValue() const { return m_data->isCalcValue(); };
293 bool isGridTemplateAreasValue() const { return m_data->isGridTemplateAreasVa lue(); };
294 bool isSVGDocumentValue() const { return m_data->isSVGDocumentValue(); };
295 bool isContentDistributionValue() const { return m_data->isContentDistributi onValue(); };
296 bool isUnicodeRangeValue() const { return m_data->isUnicodeRangeValue(); };
297 bool isGridLineNamesValue() const { return m_data->isGridLineNamesValue(); } ;
298
Timothy Loh 2015/06/02 04:54:04 Unused? Should call these in the above functions i
sashab 2015/06/05 06:16:30 ref() is used in: ImmutableStylePropertySet::Immut
299 #if !ENABLE(OILPAN)
300 void ref()
301 {
302 m_data->ref();
303 }
304 void deref()
305 {
306 m_data->deref();
307 }
308 #endif
309
310 DECLARE_TRACE();
311
312 private:
313 // To ensure these are never called. Without this, the compiler may accident ally call
314 // CSSValue(nullptr) with the CSSValueObject* constructor to store an interm ediate value.
315 // e.g. NullableCSSValue n = x ? CSSValue(foo) : nullptr;
316 CSSValue() { ASSERT_NOT_REACHED(); }
317 CSSValue(std::nullptr_t null) { ASSERT_NOT_REACHED(); }
Timothy Loh 2015/06/02 04:54:03 drop null argument name
sashab 2015/06/05 06:16:28 Didn't know you could do that. Done.
318
319 CSSValueObject* m_data;
320 };
321
322 // A nullable container for CSSValueObject. Contents are the same as CSSValue.
323 // Behavior is similar to a CSSValue*.
324 class CORE_EXPORT NullableCSSValue : public NoBaseWillBeGarbageCollectedFinalize d<NullableCSSValue> {
325 public:
326 // Not explicit to allow for casting.
327 NullableCSSValue()
328 : m_data(nullptr)
329 {
330 };
Timothy Loh 2015/06/02 04:54:04 drop semicolon
sashab 2015/06/05 06:16:30 Done.
331
332 NullableCSSValue(std::nullptr_t null)
Timothy Loh 2015/06/02 04:54:03 Is this ctor needed?
sashab 2015/06/05 06:16:30 Not anymore. Removed.
333 : m_data(nullptr)
334 {
335 };
336
337 NullableCSSValue(const CSSValueObject* cssValueObject)
338 : m_data(const_cast<CSSValueObject*>(cssValueObject))
339 {
340 if (m_data)
Timothy Loh 2015/06/02 04:54:03 should have (inline) ref/deref functions which do
sashab 2015/06/05 06:16:29 Done.
341 m_data->ref();
342 }
343
344 template <class T>
345 NullableCSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject)
346 : m_data(cssValueObject.leakRef())
347 {
348 if (m_data)
349 m_data->ref();
350 }
351
352 template <class T>
353 NullableCSSValue(RefPtrWillBeRawPtr<T> cssValueObject)
354 : m_data(cssValueObject.release().leakRef())
355 {
356 if (m_data)
357 m_data->ref();
358 }
359
360 NullableCSSValue(const NullableCSSValue& cssValue)
361 : m_data(cssValue.m_data)
362 {
363 if (m_data)
364 m_data->ref();
365 }
366
367 // CSSValues can be 'auto-cast' to NullableCSSValues, but not the other way around.
Timothy Loh 2015/06/02 04:54:04 don't think this comment helps (it should be obvio
sashab 2015/06/05 06:16:29 Removed.
368 NullableCSSValue(const CSSValue& cssValue)
369 : m_data(cssValue.m_data)
370 {
371 m_data->ref();
372 }
373
374 ~NullableCSSValue()
375 {
376 if (m_data)
377 m_data->deref();
378 };
379
380 operator bool() const
381 {
382 return m_data;
383 }
384
385 NullableCSSValue& operator=(const NullableCSSValue& rhs)
386 {
387 if (m_data)
Timothy Loh 2015/06/02 04:54:04 swap order of deref/ref
sashab 2015/06/05 06:16:29 Done, as before.
388 m_data->deref();
389 if (rhs.m_data)
390 rhs.m_data->ref();
391 m_data = rhs.m_data;
392 return *this;
393 }
394
395 bool operator==(const NullableCSSValue& rhs)
396 {
397 return m_data ? rhs.m_data && m_data->equals(*rhs.m_data) : bool(rhs.m_d ata);
398 }
399
400 CSSValue& operator*()
401 {
402 return *reinterpret_cast<CSSValue*>(this);
Timothy Loh 2015/06/02 04:54:03 Is the reinterpret_cast to avoid ref-churn? If so,
sashab 2015/06/05 06:16:29 Done.
403 }
404
405 const CSSValue& operator*() const
406 {
407 return *reinterpret_cast<const CSSValue*>(this);
408 }
409
410 CSSValue* operator->()
411 {
412 return reinterpret_cast<CSSValue*>(this);
413 }
414
415 const CSSValue* operator->() const
416 {
417 return reinterpret_cast<const CSSValue*>(this);
418 }
419
420 void swap(NullableCSSValue& rhs)
421 {
422 std::swap(this->m_data, rhs.m_data);
423 }
424
425 DECLARE_TRACE();
426
427 private:
428 CSSValueObject* m_data;
429 };
430
431 static_assert(sizeof(CSSValue) == sizeof(CSSValueObject*), "CSSValue must only c ontain a CSSValueObject*, and no vtable");
Timothy Loh 2015/06/02 04:54:03 maybe: == sizeof(void*), "CSSValue should be poin
sashab 2015/06/05 06:16:28 Done.
432 static_assert(sizeof(NullableCSSValue) == sizeof(CSSValueObject*), "NullableCSSV alue must only contain a CSSValueObject*, and no vtable");
433 static_assert(sizeof(CSSValue) == sizeof(NullableCSSValue), "Both CSSValue conta iners must contain the same data members");
434
435 template<size_t inlineCapacity>
436 inline bool compareCSSValueVector(const WillBeHeapVector<CSSValue, inlineCapacit y>& firstVector, const WillBeHeapVector<CSSValue, inlineCapacity>& secondVector)
202 { 437 {
203 size_t size = firstVector.size(); 438 size_t size = firstVector.size();
204 if (size != secondVector.size()) 439 if (size != secondVector.size())
205 return false; 440 return false;
206 441
207 for (size_t i = 0; i < size; i++) { 442 for (size_t i = 0; i < size; i++) {
208 const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i]; 443 const CSSValue& firstPtr = firstVector[i];
209 const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i]; 444 const CSSValue& secondPtr = secondVector[i];
445 if (firstPtr.ptrEquals(secondPtr) || firstPtr.equals(secondPtr))
446 continue;
447 return false;
448 }
449 return true;
450 }
451
452 // TODO: Rename these to CompareCSSValueObjectPtr or make them take a CSSValue
453 template<typename CSSValueObjectType, size_t inlineCapacity>
454 inline bool compareCSSValueObjectVector(const WillBeHeapVector<RefPtrWillBeMembe r<CSSValueObjectType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefP trWillBeMember<CSSValueObjectType>, inlineCapacity>& secondVector)
455 {
456 size_t size = firstVector.size();
457 if (size != secondVector.size())
458 return false;
459
460 for (size_t i = 0; i < size; i++) {
461 const RefPtrWillBeMember<CSSValueObjectType>& firstPtr = firstVector[i];
462 const RefPtrWillBeMember<CSSValueObjectType>& secondPtr = secondVector[i ];
210 if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals( *secondPtr))) 463 if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals( *secondPtr)))
211 continue; 464 continue;
212 return false; 465 return false;
213 } 466 }
214 return true; 467 return true;
215 } 468 }
216 469
217 template<typename CSSValueType> 470 template<typename CSSValueType>
218 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<C SSValueType>& second) 471 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<C SSValueType>& second)
219 { 472 {
220 return first ? second && first->equals(*second) : !second; 473 return first ? second && first->equals(*second) : !second;
221 } 474 }
222 475
223 template<typename CSSValueType> 476 template<typename CSSValueType>
224 inline bool compareCSSValuePtr(const RawPtr<CSSValueType>& first, const RawPtr<C SSValueType>& second) 477 inline bool compareCSSValuePtr(const RawPtr<CSSValueType>& first, const RawPtr<C SSValueType>& second)
225 { 478 {
226 return first ? second && first->equals(*second) : !second; 479 return first ? second && first->equals(*second) : !second;
227 } 480 }
228 481
229 template<typename CSSValueType> 482 template<typename CSSValueType>
230 inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<C SSValueType>& second) 483 inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<C SSValueType>& second)
231 { 484 {
232 return first ? second && first->equals(*second) : !second; 485 return first ? second && first->equals(*second) : !second;
233 } 486 }
234 487
235 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \ 488 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \
236 DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predica te) 489 DEFINE_TYPE_CASTS(thisType, CSSValueObject, value, value->predicate, value.p redicate); \
490 inline thisType& to##thisType(CSSValue value) \
491 { \
492 ASSERT_WITH_SECURITY_IMPLICATION(value.predicate); \
493 return **reinterpret_cast<thisType**>(&value); \
494 } \
495 inline thisType* to##thisType(NullableCSSValue value) \
496 { \
497 if (!value) \
498 return nullptr; \
499 ASSERT_WITH_SECURITY_IMPLICATION(value->predicate); \
500 return *reinterpret_cast<thisType**>(&value); \
501 }
237 502
238 } // namespace blink 503 } // namespace blink
239 504
240 #endif // CSSValue_h 505 #endif // CSSValue_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698