mirror of
https://github.com/atom/atom.git
synced 2026-01-23 05:48:10 -05:00
remove webkit frameworks
This commit is contained in:
@@ -1 +0,0 @@
|
||||
Versions/Current/Headers
|
||||
@@ -1 +0,0 @@
|
||||
Versions/Current/JavaScriptCore
|
||||
@@ -1 +0,0 @@
|
||||
Versions/Current/PrivateHeaders
|
||||
@@ -1 +0,0 @@
|
||||
Versions/Current/Resources
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JSBase_h
|
||||
#define JSBase_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
/* JavaScript engine interface */
|
||||
|
||||
/*! @typedef JSContextGroupRef A group that associates JavaScript contexts with one another. Contexts in the same group may share and exchange JavaScript objects. */
|
||||
typedef const struct OpaqueJSContextGroup* JSContextGroupRef;
|
||||
|
||||
/*! @typedef JSContextRef A JavaScript execution context. Holds the global object and other execution state. */
|
||||
typedef const struct OpaqueJSContext* JSContextRef;
|
||||
|
||||
/*! @typedef JSGlobalContextRef A global JavaScript execution context. A JSGlobalContext is a JSContext. */
|
||||
typedef struct OpaqueJSContext* JSGlobalContextRef;
|
||||
|
||||
/*! @typedef JSStringRef A UTF16 character buffer. The fundamental string representation in JavaScript. */
|
||||
typedef struct OpaqueJSString* JSStringRef;
|
||||
|
||||
/*! @typedef JSClassRef A JavaScript class. Used with JSObjectMake to construct objects with custom behavior. */
|
||||
typedef struct OpaqueJSClass* JSClassRef;
|
||||
|
||||
/*! @typedef JSPropertyNameArrayRef An array of JavaScript property names. */
|
||||
typedef struct OpaqueJSPropertyNameArray* JSPropertyNameArrayRef;
|
||||
|
||||
/*! @typedef JSPropertyNameAccumulatorRef An ordered set used to collect the names of a JavaScript object's properties. */
|
||||
typedef struct OpaqueJSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
|
||||
|
||||
|
||||
/* JavaScript data types */
|
||||
|
||||
/*! @typedef JSValueRef A JavaScript value. The base type for all JavaScript values, and polymorphic functions on them. */
|
||||
typedef const struct OpaqueJSValue* JSValueRef;
|
||||
|
||||
/*! @typedef JSObjectRef A JavaScript object. A JSObject is a JSValue. */
|
||||
typedef struct OpaqueJSValue* JSObjectRef;
|
||||
|
||||
/* JavaScript symbol exports */
|
||||
/* These rules should stay the same as in WebKit2/Shared/API/c/WKBase.h */
|
||||
|
||||
#undef JS_EXPORT
|
||||
#if defined(JS_NO_EXPORT)
|
||||
#define JS_EXPORT
|
||||
#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__)
|
||||
#define JS_EXPORT __attribute__((visibility("default")))
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__CC_ARM) || defined(__ARMCC__)
|
||||
#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
|
||||
#define JS_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define JS_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else /* !defined(JS_NO_EXPORT) */
|
||||
#define JS_EXPORT
|
||||
#endif /* defined(JS_NO_EXPORT) */
|
||||
|
||||
/* JS tests uses WTF but has no config.h, so we need to set the export defines here. */
|
||||
#ifndef WTF_EXPORT_PRIVATE
|
||||
#define WTF_EXPORT_PRIVATE JS_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Script Evaluation */
|
||||
|
||||
/*!
|
||||
@function JSEvaluateScript
|
||||
@abstract Evaluates a string of JavaScript.
|
||||
@param ctx The execution context to use.
|
||||
@param script A JSString containing the script to evaluate.
|
||||
@param thisObject The object to use as "this," or NULL to use the global object as "this."
|
||||
@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
|
||||
@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The JSValue that results from evaluating script, or NULL if an exception is thrown.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function JSCheckScriptSyntax
|
||||
@abstract Checks for syntax errors in a string of JavaScript.
|
||||
@param ctx The execution context to use.
|
||||
@param script A JSString containing the script to check for syntax errors.
|
||||
@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
|
||||
@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
|
||||
@param exception A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception.
|
||||
@result true if the script is syntactically correct, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function JSGarbageCollect
|
||||
@abstract Performs a JavaScript garbage collection.
|
||||
@param ctx The execution context to use.
|
||||
@discussion JavaScript values that are on the machine stack, in a register,
|
||||
protected by JSValueProtect, set as the global object of an execution context,
|
||||
or reachable from any such value will not be collected.
|
||||
|
||||
During JavaScript execution, you are not required to call this function; the
|
||||
JavaScript engine will garbage collect as needed. JavaScript values created
|
||||
within a context group are automatically destroyed when the last reference
|
||||
to the context group is released.
|
||||
*/
|
||||
JS_EXPORT void JSGarbageCollect(JSContextRef ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JSBase_h */
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JSContextRef_h
|
||||
#define JSContextRef_h
|
||||
|
||||
#include <JavaScriptCore/JSObjectRef.h>
|
||||
#include <JavaScriptCore/JSValueRef.h>
|
||||
#include <JavaScriptCore/WebKitAvailability.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript context group.
|
||||
@discussion A JSContextGroup associates JavaScript contexts with one another.
|
||||
Contexts in the same group may share and exchange JavaScript objects. Sharing and/or exchanging
|
||||
JavaScript objects between contexts in different groups will produce undefined behavior.
|
||||
When objects from the same context group are used in multiple threads, explicit
|
||||
synchronization is required.
|
||||
@result The created JSContextGroup.
|
||||
*/
|
||||
JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Retains a JavaScript context group.
|
||||
@param group The JSContextGroup to retain.
|
||||
@result A JSContextGroup that is the same as group.
|
||||
*/
|
||||
JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Releases a JavaScript context group.
|
||||
@param group The JSContextGroup to release.
|
||||
*/
|
||||
JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a global JavaScript execution context.
|
||||
@discussion JSGlobalContextCreate allocates a global object and populates it with all the
|
||||
built-in JavaScript objects, such as Object, Function, String, and Array.
|
||||
|
||||
In WebKit version 4.0 and later, the context is created in a unique context group.
|
||||
Therefore, scripts may execute in it concurrently with scripts executing in other contexts.
|
||||
However, you may not use values created in the context in other contexts.
|
||||
@param globalObjectClass The class to use when creating the global object. Pass
|
||||
NULL to use the default object class.
|
||||
@result A JSGlobalContext with a global object of class globalObjectClass.
|
||||
*/
|
||||
JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a global JavaScript execution context in the context group provided.
|
||||
@discussion JSGlobalContextCreateInGroup allocates a global object and populates it with
|
||||
all the built-in JavaScript objects, such as Object, Function, String, and Array.
|
||||
@param globalObjectClass The class to use when creating the global object. Pass
|
||||
NULL to use the default object class.
|
||||
@param group The context group to use. The created global context retains the group.
|
||||
Pass NULL to create a unique group for the context.
|
||||
@result A JSGlobalContext with a global object of class globalObjectClass and a context
|
||||
group equal to group.
|
||||
*/
|
||||
JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Retains a global JavaScript execution context.
|
||||
@param ctx The JSGlobalContext to retain.
|
||||
@result A JSGlobalContext that is the same as ctx.
|
||||
*/
|
||||
JS_EXPORT JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Releases a global JavaScript execution context.
|
||||
@param ctx The JSGlobalContext to release.
|
||||
*/
|
||||
JS_EXPORT void JSGlobalContextRelease(JSGlobalContextRef ctx);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets the global object of a JavaScript execution context.
|
||||
@param ctx The JSContext whose global object you want to get.
|
||||
@result ctx's global object.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets the context group to which a JavaScript execution context belongs.
|
||||
@param ctx The JSContext whose group you want to get.
|
||||
@result ctx's group.
|
||||
*/
|
||||
JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JSContextRef_h */
|
||||
@@ -1,694 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com)
|
||||
*
|
||||
* 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JSObjectRef_h
|
||||
#define JSObjectRef_h
|
||||
|
||||
#include <JavaScriptCore/JSBase.h>
|
||||
#include <JavaScriptCore/JSValueRef.h>
|
||||
#include <JavaScriptCore/WebKitAvailability.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stddef.h> /* for size_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@enum JSPropertyAttribute
|
||||
@constant kJSPropertyAttributeNone Specifies that a property has no special attributes.
|
||||
@constant kJSPropertyAttributeReadOnly Specifies that a property is read-only.
|
||||
@constant kJSPropertyAttributeDontEnum Specifies that a property should not be enumerated by JSPropertyEnumerators and JavaScript for...in loops.
|
||||
@constant kJSPropertyAttributeDontDelete Specifies that the delete operation should fail on a property.
|
||||
*/
|
||||
enum {
|
||||
kJSPropertyAttributeNone = 0,
|
||||
kJSPropertyAttributeReadOnly = 1 << 1,
|
||||
kJSPropertyAttributeDontEnum = 1 << 2,
|
||||
kJSPropertyAttributeDontDelete = 1 << 3
|
||||
};
|
||||
|
||||
/*!
|
||||
@typedef JSPropertyAttributes
|
||||
@abstract A set of JSPropertyAttributes. Combine multiple attributes by logically ORing them together.
|
||||
*/
|
||||
typedef unsigned JSPropertyAttributes;
|
||||
|
||||
/*!
|
||||
@enum JSClassAttribute
|
||||
@constant kJSClassAttributeNone Specifies that a class has no special attributes.
|
||||
@constant kJSClassAttributeNoAutomaticPrototype Specifies that a class should not automatically generate a shared prototype for its instance objects. Use kJSClassAttributeNoAutomaticPrototype in combination with JSObjectSetPrototype to manage prototypes manually.
|
||||
*/
|
||||
enum {
|
||||
kJSClassAttributeNone = 0,
|
||||
kJSClassAttributeNoAutomaticPrototype = 1 << 1
|
||||
};
|
||||
|
||||
/*!
|
||||
@typedef JSClassAttributes
|
||||
@abstract A set of JSClassAttributes. Combine multiple attributes by logically ORing them together.
|
||||
*/
|
||||
typedef unsigned JSClassAttributes;
|
||||
|
||||
/*!
|
||||
@typedef JSObjectInitializeCallback
|
||||
@abstract The callback invoked when an object is first created.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject being created.
|
||||
@discussion If you named your function Initialize, you would declare it like this:
|
||||
|
||||
void Initialize(JSContextRef ctx, JSObjectRef object);
|
||||
|
||||
Unlike the other object callbacks, the initialize callback is called on the least
|
||||
derived class (the parent class) first, and the most derived class last.
|
||||
*/
|
||||
typedef void
|
||||
(*JSObjectInitializeCallback) (JSContextRef ctx, JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectFinalizeCallback
|
||||
@abstract The callback invoked when an object is finalized (prepared for garbage collection). An object may be finalized on any thread.
|
||||
@param object The JSObject being finalized.
|
||||
@discussion If you named your function Finalize, you would declare it like this:
|
||||
|
||||
void Finalize(JSObjectRef object);
|
||||
|
||||
The finalize callback is called on the most derived class first, and the least
|
||||
derived class (the parent class) last.
|
||||
|
||||
You must not call any function that may cause a garbage collection or an allocation
|
||||
of a garbage collected object from within a JSObjectFinalizeCallback. This includes
|
||||
all functions that have a JSContextRef parameter.
|
||||
*/
|
||||
typedef void
|
||||
(*JSObjectFinalizeCallback) (JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectHasPropertyCallback
|
||||
@abstract The callback invoked when determining whether an object has a property.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to search for the property.
|
||||
@param propertyName A JSString containing the name of the property look up.
|
||||
@result true if object has the property, otherwise false.
|
||||
@discussion If you named your function HasProperty, you would declare it like this:
|
||||
|
||||
bool HasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);
|
||||
|
||||
If this function returns false, the hasProperty request forwards to object's statically declared properties, then its parent class chain (which includes the default object class), then its prototype chain.
|
||||
|
||||
This callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value would be expensive.
|
||||
|
||||
If this callback is NULL, the getProperty callback will be used to service hasProperty requests.
|
||||
*/
|
||||
typedef bool
|
||||
(*JSObjectHasPropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectGetPropertyCallback
|
||||
@abstract The callback invoked when getting a property's value.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to search for the property.
|
||||
@param propertyName A JSString containing the name of the property to get.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result The property's value if object has the property, otherwise NULL.
|
||||
@discussion If you named your function GetProperty, you would declare it like this:
|
||||
|
||||
JSValueRef GetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
|
||||
|
||||
If this function returns NULL, the get request forwards to object's statically declared properties, then its parent class chain (which includes the default object class), then its prototype chain.
|
||||
*/
|
||||
typedef JSValueRef
|
||||
(*JSObjectGetPropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectSetPropertyCallback
|
||||
@abstract The callback invoked when setting a property's value.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject on which to set the property's value.
|
||||
@param propertyName A JSString containing the name of the property to set.
|
||||
@param value A JSValue to use as the property's value.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result true if the property was set, otherwise false.
|
||||
@discussion If you named your function SetProperty, you would declare it like this:
|
||||
|
||||
bool SetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
If this function returns false, the set request forwards to object's statically declared properties, then its parent class chain (which includes the default object class).
|
||||
*/
|
||||
typedef bool
|
||||
(*JSObjectSetPropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectDeletePropertyCallback
|
||||
@abstract The callback invoked when deleting a property.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject in which to delete the property.
|
||||
@param propertyName A JSString containing the name of the property to delete.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result true if propertyName was successfully deleted, otherwise false.
|
||||
@discussion If you named your function DeleteProperty, you would declare it like this:
|
||||
|
||||
bool DeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
|
||||
|
||||
If this function returns false, the delete request forwards to object's statically declared properties, then its parent class chain (which includes the default object class).
|
||||
*/
|
||||
typedef bool
|
||||
(*JSObjectDeletePropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectGetPropertyNamesCallback
|
||||
@abstract The callback invoked when collecting the names of an object's properties.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose property names are being collected.
|
||||
@param accumulator A JavaScript property name accumulator in which to accumulate the names of object's properties.
|
||||
@discussion If you named your function GetPropertyNames, you would declare it like this:
|
||||
|
||||
void GetPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames);
|
||||
|
||||
Property name accumulators are used by JSObjectCopyPropertyNames and JavaScript for...in loops.
|
||||
|
||||
Use JSPropertyNameAccumulatorAddName to add property names to accumulator. A class's getPropertyNames callback only needs to provide the names of properties that the class vends through a custom getProperty or setProperty callback. Other properties, including statically declared properties, properties vended by other classes, and properties belonging to object's prototype, are added independently.
|
||||
*/
|
||||
typedef void
|
||||
(*JSObjectGetPropertyNamesCallback) (JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectCallAsFunctionCallback
|
||||
@abstract The callback invoked when an object is called as a function.
|
||||
@param ctx The execution context to use.
|
||||
@param function A JSObject that is the function being called.
|
||||
@param thisObject A JSObject that is the 'this' variable in the function's scope.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of the arguments passed to the function.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result A JSValue that is the function's return value.
|
||||
@discussion If you named your function CallAsFunction, you would declare it like this:
|
||||
|
||||
JSValueRef CallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
|
||||
|
||||
If your callback were invoked by the JavaScript expression 'myObject.myFunction()', function would be set to myFunction, and thisObject would be set to myObject.
|
||||
|
||||
If this callback is NULL, calling your object as a function will throw an exception.
|
||||
*/
|
||||
typedef JSValueRef
|
||||
(*JSObjectCallAsFunctionCallback) (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectCallAsConstructorCallback
|
||||
@abstract The callback invoked when an object is used as a constructor in a 'new' expression.
|
||||
@param ctx The execution context to use.
|
||||
@param constructor A JSObject that is the constructor being called.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of the arguments passed to the function.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result A JSObject that is the constructor's return value.
|
||||
@discussion If you named your function CallAsConstructor, you would declare it like this:
|
||||
|
||||
JSObjectRef CallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
|
||||
|
||||
If your callback were invoked by the JavaScript expression 'new myConstructor()', constructor would be set to myConstructor.
|
||||
|
||||
If this callback is NULL, using your object as a constructor in a 'new' expression will throw an exception.
|
||||
*/
|
||||
typedef JSObjectRef
|
||||
(*JSObjectCallAsConstructorCallback) (JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectHasInstanceCallback
|
||||
@abstract hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression.
|
||||
@param ctx The execution context to use.
|
||||
@param constructor The JSObject that is the target of the 'instanceof' expression.
|
||||
@param possibleInstance The JSValue being tested to determine if it is an instance of constructor.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result true if possibleInstance is an instance of constructor, otherwise false.
|
||||
@discussion If you named your function HasInstance, you would declare it like this:
|
||||
|
||||
bool HasInstance(JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception);
|
||||
|
||||
If your callback were invoked by the JavaScript expression 'someValue instanceof myObject', constructor would be set to myObject and possibleInstance would be set to someValue.
|
||||
|
||||
If this callback is NULL, 'instanceof' expressions that target your object will return false.
|
||||
|
||||
Standard JavaScript practice calls for objects that implement the callAsConstructor callback to implement the hasInstance callback as well.
|
||||
*/
|
||||
typedef bool
|
||||
(*JSObjectHasInstanceCallback) (JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@typedef JSObjectConvertToTypeCallback
|
||||
@abstract The callback invoked when converting an object to a particular JavaScript type.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to convert.
|
||||
@param type A JSType specifying the JavaScript type to convert to.
|
||||
@param exception A pointer to a JSValueRef in which to return an exception, if any.
|
||||
@result The objects's converted value, or NULL if the object was not converted.
|
||||
@discussion If you named your function ConvertToType, you would declare it like this:
|
||||
|
||||
JSValueRef ConvertToType(JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception);
|
||||
|
||||
If this function returns false, the conversion request forwards to object's parent class chain (which includes the default object class).
|
||||
|
||||
This function is only invoked when converting an object to number or string. An object converted to boolean is 'true.' An object converted to object is itself.
|
||||
*/
|
||||
typedef JSValueRef
|
||||
(*JSObjectConvertToTypeCallback) (JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@struct JSStaticValue
|
||||
@abstract This structure describes a statically declared value property.
|
||||
@field name A null-terminated UTF8 string containing the property's name.
|
||||
@field getProperty A JSObjectGetPropertyCallback to invoke when getting the property's value.
|
||||
@field setProperty A JSObjectSetPropertyCallback to invoke when setting the property's value. May be NULL if the ReadOnly attribute is set.
|
||||
@field attributes A logically ORed set of JSPropertyAttributes to give to the property.
|
||||
*/
|
||||
typedef struct {
|
||||
const char* name;
|
||||
JSObjectGetPropertyCallback getProperty;
|
||||
JSObjectSetPropertyCallback setProperty;
|
||||
JSPropertyAttributes attributes;
|
||||
} JSStaticValue;
|
||||
|
||||
/*!
|
||||
@struct JSStaticFunction
|
||||
@abstract This structure describes a statically declared function property.
|
||||
@field name A null-terminated UTF8 string containing the property's name.
|
||||
@field callAsFunction A JSObjectCallAsFunctionCallback to invoke when the property is called as a function.
|
||||
@field attributes A logically ORed set of JSPropertyAttributes to give to the property.
|
||||
*/
|
||||
typedef struct {
|
||||
const char* name;
|
||||
JSObjectCallAsFunctionCallback callAsFunction;
|
||||
JSPropertyAttributes attributes;
|
||||
} JSStaticFunction;
|
||||
|
||||
/*!
|
||||
@struct JSClassDefinition
|
||||
@abstract This structure contains properties and callbacks that define a type of object. All fields other than the version field are optional. Any pointer may be NULL.
|
||||
@field version The version number of this structure. The current version is 0.
|
||||
@field attributes A logically ORed set of JSClassAttributes to give to the class.
|
||||
@field className A null-terminated UTF8 string containing the class's name.
|
||||
@field parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class.
|
||||
@field staticValues A JSStaticValue array containing the class's statically declared value properties. Pass NULL to specify no statically declared value properties. The array must be terminated by a JSStaticValue whose name field is NULL.
|
||||
@field staticFunctions A JSStaticFunction array containing the class's statically declared function properties. Pass NULL to specify no statically declared function properties. The array must be terminated by a JSStaticFunction whose name field is NULL.
|
||||
@field initialize The callback invoked when an object is first created. Use this callback to initialize the object.
|
||||
@field finalize The callback invoked when an object is finalized (prepared for garbage collection). Use this callback to release resources allocated for the object, and perform other cleanup.
|
||||
@field hasProperty The callback invoked when determining whether an object has a property. If this field is NULL, getProperty is called instead. The hasProperty callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value is expensive.
|
||||
@field getProperty The callback invoked when getting a property's value.
|
||||
@field setProperty The callback invoked when setting a property's value.
|
||||
@field deleteProperty The callback invoked when deleting a property.
|
||||
@field getPropertyNames The callback invoked when collecting the names of an object's properties.
|
||||
@field callAsFunction The callback invoked when an object is called as a function.
|
||||
@field hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression.
|
||||
@field callAsConstructor The callback invoked when an object is used as a constructor in a 'new' expression.
|
||||
@field convertToType The callback invoked when converting an object to a particular JavaScript type.
|
||||
@discussion The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties. Statically declared properties autmatically service requests like getProperty, setProperty, and getPropertyNames. Property access callbacks are required only to implement unusual properties, like array indexes, whose names are not known at compile-time.
|
||||
|
||||
If you named your getter function "GetX" and your setter function "SetX", you would declare a JSStaticValue array containing "X" like this:
|
||||
|
||||
JSStaticValue StaticValueArray[] = {
|
||||
{ "X", GetX, SetX, kJSPropertyAttributeNone },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
Standard JavaScript practice calls for storing function objects in prototypes, so they can be shared. The default JSClass created by JSClassCreate follows this idiom, instantiating objects with a shared, automatically generating prototype containing the class's function objects. The kJSClassAttributeNoAutomaticPrototype attribute specifies that a JSClass should not automatically generate such a prototype. The resulting JSClass instantiates objects with the default object prototype, and gives each instance object its own copy of the class's function objects.
|
||||
|
||||
A NULL callback specifies that the default object callback should substitute, except in the case of hasProperty, where it specifies that getProperty should substitute.
|
||||
*/
|
||||
typedef struct {
|
||||
int version; /* current (and only) version is 0 */
|
||||
JSClassAttributes attributes;
|
||||
|
||||
const char* className;
|
||||
JSClassRef parentClass;
|
||||
|
||||
const JSStaticValue* staticValues;
|
||||
const JSStaticFunction* staticFunctions;
|
||||
|
||||
JSObjectInitializeCallback initialize;
|
||||
JSObjectFinalizeCallback finalize;
|
||||
JSObjectHasPropertyCallback hasProperty;
|
||||
JSObjectGetPropertyCallback getProperty;
|
||||
JSObjectSetPropertyCallback setProperty;
|
||||
JSObjectDeletePropertyCallback deleteProperty;
|
||||
JSObjectGetPropertyNamesCallback getPropertyNames;
|
||||
JSObjectCallAsFunctionCallback callAsFunction;
|
||||
JSObjectCallAsConstructorCallback callAsConstructor;
|
||||
JSObjectHasInstanceCallback hasInstance;
|
||||
JSObjectConvertToTypeCallback convertToType;
|
||||
} JSClassDefinition;
|
||||
|
||||
/*!
|
||||
@const kJSClassDefinitionEmpty
|
||||
@abstract A JSClassDefinition structure of the current version, filled with NULL pointers and having no attributes.
|
||||
@discussion Use this constant as a convenience when creating class definitions. For example, to create a class definition with only a finalize method:
|
||||
|
||||
JSClassDefinition definition = kJSClassDefinitionEmpty;
|
||||
definition.finalize = Finalize;
|
||||
*/
|
||||
JS_EXPORT extern const JSClassDefinition kJSClassDefinitionEmpty;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript class suitable for use with JSObjectMake.
|
||||
@param definition A JSClassDefinition that defines the class.
|
||||
@result A JSClass with the given definition. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT JSClassRef JSClassCreate(const JSClassDefinition* definition);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Retains a JavaScript class.
|
||||
@param jsClass The JSClass to retain.
|
||||
@result A JSClass that is the same as jsClass.
|
||||
*/
|
||||
JS_EXPORT JSClassRef JSClassRetain(JSClassRef jsClass);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Releases a JavaScript class.
|
||||
@param jsClass The JSClass to release.
|
||||
*/
|
||||
JS_EXPORT void JSClassRelease(JSClassRef jsClass);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript object.
|
||||
@param ctx The execution context to use.
|
||||
@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
|
||||
@param data A void* to set as the object's private data. Pass NULL to specify no private data.
|
||||
@result A JSObject with the given class and private data.
|
||||
@discussion The default object class does not allocate storage for private data, so you must provide a non-NULL jsClass to JSObjectMake if you want your object to be able to store private data.
|
||||
|
||||
data is set on the created object before the intialize methods in its class chain are called. This enables the initialize methods to retrieve and manipulate data through JSObjectGetPrivate.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Convenience method for creating a JavaScript function with a given callback as its implementation.
|
||||
@param ctx The execution context to use.
|
||||
@param name A JSString containing the function's name. This will be used when converting the function to string. Pass NULL to create an anonymous function.
|
||||
@param callAsFunction The JSObjectCallAsFunctionCallback to invoke when the function is called.
|
||||
@result A JSObject that is a function. The object's prototype will be the default function prototype.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Convenience method for creating a JavaScript constructor.
|
||||
@param ctx The execution context to use.
|
||||
@param jsClass A JSClass that is the class your constructor will assign to the objects its constructs. jsClass will be used to set the constructor's .prototype property, and to evaluate 'instanceof' expressions. Pass NULL to use the default object class.
|
||||
@param callAsConstructor A JSObjectCallAsConstructorCallback to invoke when your constructor is used in a 'new' expression. Pass NULL to use the default object constructor.
|
||||
@result A JSObject that is a constructor. The object's prototype will be the default object prototype.
|
||||
@discussion The default object constructor takes no arguments and constructs an object of class jsClass with no private data.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript Array object.
|
||||
@param ctx The execution context to use.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of data to populate the Array with. Pass NULL if argumentCount is 0.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result A JSObject that is an Array.
|
||||
@discussion The behavior of this function does not exactly match the behavior of the built-in Array constructor. Specifically, if one argument
|
||||
is supplied, this function returns an array with one element.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript Date object, as if by invoking the built-in Date constructor.
|
||||
@param ctx The execution context to use.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of arguments to pass to the Date Constructor. Pass NULL if argumentCount is 0.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result A JSObject that is a Date.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript Error object, as if by invoking the built-in Error constructor.
|
||||
@param ctx The execution context to use.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of arguments to pass to the Error Constructor. Pass NULL if argumentCount is 0.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result A JSObject that is a Error.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript RegExp object, as if by invoking the built-in RegExp constructor.
|
||||
@param ctx The execution context to use.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of arguments to pass to the RegExp Constructor. Pass NULL if argumentCount is 0.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result A JSObject that is a RegExp.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a function with a given script as its body.
|
||||
@param ctx The execution context to use.
|
||||
@param name A JSString containing the function's name. This will be used when converting the function to string. Pass NULL to create an anonymous function.
|
||||
@param parameterCount An integer count of the number of parameter names in parameterNames.
|
||||
@param parameterNames A JSString array containing the names of the function's parameters. Pass NULL if parameterCount is 0.
|
||||
@param body A JSString containing the script to use as the function's body.
|
||||
@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
|
||||
@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
|
||||
@param exception A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception.
|
||||
@result A JSObject that is a function, or NULL if either body or parameterNames contains a syntax error. The object's prototype will be the default function prototype.
|
||||
@discussion Use this method when you want to execute a script repeatedly, to avoid the cost of re-parsing the script before each execution.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets an object's prototype.
|
||||
@param ctx The execution context to use.
|
||||
@param object A JSObject whose prototype you want to get.
|
||||
@result A JSValue that is the object's prototype.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Sets an object's prototype.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose prototype you want to set.
|
||||
@param value A JSValue to set as the object's prototype.
|
||||
*/
|
||||
JS_EXPORT void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether an object has a given property.
|
||||
@param object The JSObject to test.
|
||||
@param propertyName A JSString containing the property's name.
|
||||
@result true if the object has a property whose name matches propertyName, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets a property from an object.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose property you want to get.
|
||||
@param propertyName A JSString containing the property's name.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The property's value if object has the property, otherwise the undefined value.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Sets a property on an object.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose property you want to set.
|
||||
@param propertyName A JSString containing the property's name.
|
||||
@param value A JSValue to use as the property's value.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
|
||||
*/
|
||||
JS_EXPORT void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Deletes a property from an object.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose property you want to delete.
|
||||
@param propertyName A JSString containing the property's name.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result true if the delete operation succeeds, otherwise false (for example, if the property has the kJSPropertyAttributeDontDelete attribute set).
|
||||
*/
|
||||
JS_EXPORT bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets a property from an object by numeric index.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose property you want to get.
|
||||
@param propertyIndex An integer value that is the property's name.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The property's value if object has the property, otherwise the undefined value.
|
||||
@discussion Calling JSObjectGetPropertyAtIndex is equivalent to calling JSObjectGetProperty with a string containing propertyIndex, but JSObjectGetPropertyAtIndex provides optimized access to numeric properties.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Sets a property on an object by numeric index.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject whose property you want to set.
|
||||
@param propertyIndex The property's name as a number.
|
||||
@param value A JSValue to use as the property's value.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@discussion Calling JSObjectSetPropertyAtIndex is equivalent to calling JSObjectSetProperty with a string containing propertyIndex, but JSObjectSetPropertyAtIndex provides optimized access to numeric properties.
|
||||
*/
|
||||
JS_EXPORT void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets an object's private data.
|
||||
@param object A JSObject whose private data you want to get.
|
||||
@result A void* that is the object's private data, if the object has private data, otherwise NULL.
|
||||
*/
|
||||
JS_EXPORT void* JSObjectGetPrivate(JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Sets a pointer to private data on an object.
|
||||
@param object The JSObject whose private data you want to set.
|
||||
@param data A void* to set as the object's private data.
|
||||
@result true if object can store private data, otherwise false.
|
||||
@discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data.
|
||||
*/
|
||||
JS_EXPORT bool JSObjectSetPrivate(JSObjectRef object, void* data);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether an object can be called as a function.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to test.
|
||||
@result true if the object can be called as a function, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSObjectIsFunction(JSContextRef ctx, JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Calls an object as a function.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to call as a function.
|
||||
@param thisObject The object to use as "this," or NULL to use the global object as "this."
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of arguments to pass to the function. Pass NULL if argumentCount is 0.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The JSValue that results from calling object as a function, or NULL if an exception is thrown or object is not a function.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether an object can be called as a constructor.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to test.
|
||||
@result true if the object can be called as a constructor, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSObjectIsConstructor(JSContextRef ctx, JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Calls an object as a constructor.
|
||||
@param ctx The execution context to use.
|
||||
@param object The JSObject to call as a constructor.
|
||||
@param argumentCount An integer count of the number of arguments in arguments.
|
||||
@param arguments A JSValue array of arguments to pass to the constructor. Pass NULL if argumentCount is 0.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The JSObject that results from calling object as a constructor, or NULL if an exception is thrown or object is not a constructor.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets the names of an object's enumerable properties.
|
||||
@param ctx The execution context to use.
|
||||
@param object The object whose property names you want to get.
|
||||
@result A JSPropertyNameArray containing the names object's enumerable properties. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Retains a JavaScript property name array.
|
||||
@param array The JSPropertyNameArray to retain.
|
||||
@result A JSPropertyNameArray that is the same as array.
|
||||
*/
|
||||
JS_EXPORT JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Releases a JavaScript property name array.
|
||||
@param array The JSPropetyNameArray to release.
|
||||
*/
|
||||
JS_EXPORT void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets a count of the number of items in a JavaScript property name array.
|
||||
@param array The array from which to retrieve the count.
|
||||
@result An integer count of the number of names in array.
|
||||
*/
|
||||
JS_EXPORT size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Gets a property name at a given index in a JavaScript property name array.
|
||||
@param array The array from which to retrieve the property name.
|
||||
@param index The index of the property name to retrieve.
|
||||
@result A JSStringRef containing the property name.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Adds a property name to a JavaScript property name accumulator.
|
||||
@param accumulator The accumulator object to which to add the property name.
|
||||
@param propertyName The property name to add.
|
||||
*/
|
||||
JS_EXPORT void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JSObjectRef_h */
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JSStringRef_h
|
||||
#define JSStringRef_h
|
||||
|
||||
#include <JavaScriptCore/JSValueRef.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stddef.h> /* for size_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(WIN32) && !defined(_WIN32) \
|
||||
&& !((defined(__CC_ARM) || defined(__ARMCC__)) && !defined(__linux__)) /* RVCT */
|
||||
/*!
|
||||
@typedef JSChar
|
||||
@abstract A Unicode character.
|
||||
*/
|
||||
typedef unsigned short JSChar;
|
||||
#else
|
||||
typedef wchar_t JSChar;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript string from a buffer of Unicode characters.
|
||||
@param chars The buffer of Unicode characters to copy into the new JSString.
|
||||
@param numChars The number of characters to copy from the buffer pointed to by chars.
|
||||
@result A JSString containing chars. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars);
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript string from a null-terminated UTF8 string.
|
||||
@param string The null-terminated UTF8 string to copy into the new JSString.
|
||||
@result A JSString containing string. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSStringCreateWithUTF8CString(const char* string);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Retains a JavaScript string.
|
||||
@param string The JSString to retain.
|
||||
@result A JSString that is the same as string.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSStringRetain(JSStringRef string);
|
||||
/*!
|
||||
@function
|
||||
@abstract Releases a JavaScript string.
|
||||
@param string The JSString to release.
|
||||
*/
|
||||
JS_EXPORT void JSStringRelease(JSStringRef string);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Returns the number of Unicode characters in a JavaScript string.
|
||||
@param string The JSString whose length (in Unicode characters) you want to know.
|
||||
@result The number of Unicode characters stored in string.
|
||||
*/
|
||||
JS_EXPORT size_t JSStringGetLength(JSStringRef string);
|
||||
/*!
|
||||
@function
|
||||
@abstract Returns a pointer to the Unicode character buffer that
|
||||
serves as the backing store for a JavaScript string.
|
||||
@param string The JSString whose backing store you want to access.
|
||||
@result A pointer to the Unicode character buffer that serves as string's
|
||||
backing store, which will be deallocated when string is deallocated.
|
||||
*/
|
||||
JS_EXPORT const JSChar* JSStringGetCharactersPtr(JSStringRef string);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Returns the maximum number of bytes a JavaScript string will
|
||||
take up if converted into a null-terminated UTF8 string.
|
||||
@param string The JSString whose maximum converted size (in bytes) you
|
||||
want to know.
|
||||
@result The maximum number of bytes that could be required to convert string into a
|
||||
null-terminated UTF8 string. The number of bytes that the conversion actually ends
|
||||
up requiring could be less than this, but never more.
|
||||
*/
|
||||
JS_EXPORT size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string);
|
||||
/*!
|
||||
@function
|
||||
@abstract Converts a JavaScript string into a null-terminated UTF8 string,
|
||||
and copies the result into an external byte buffer.
|
||||
@param string The source JSString.
|
||||
@param buffer The destination byte buffer into which to copy a null-terminated
|
||||
UTF8 representation of string. On return, buffer contains a UTF8 string
|
||||
representation of string. If bufferSize is too small, buffer will contain only
|
||||
partial results. If buffer is not at least bufferSize bytes in size,
|
||||
behavior is undefined.
|
||||
@param bufferSize The size of the external buffer in bytes.
|
||||
@result The number of bytes written into buffer (including the null-terminator byte).
|
||||
*/
|
||||
JS_EXPORT size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether two JavaScript strings match.
|
||||
@param a The first JSString to test.
|
||||
@param b The second JSString to test.
|
||||
@result true if the two strings match, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSStringIsEqual(JSStringRef a, JSStringRef b);
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript string matches a null-terminated UTF8 string.
|
||||
@param a The JSString to test.
|
||||
@param b The null-terminated UTF8 string to test.
|
||||
@result true if the two strings match, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSStringIsEqualToUTF8CString(JSStringRef a, const char* b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JSStringRef_h */
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006, 2007 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JSStringRefCF_h
|
||||
#define JSStringRefCF_h
|
||||
|
||||
#include "JSBase.h"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* CFString convenience methods */
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript string from a CFString.
|
||||
@discussion This function is optimized to take advantage of cases when
|
||||
CFStringGetCharactersPtr returns a valid pointer.
|
||||
@param string The CFString to copy into the new JSString.
|
||||
@result A JSString containing string. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSStringCreateWithCFString(CFStringRef string);
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a CFString from a JavaScript string.
|
||||
@param alloc The alloc parameter to pass to CFStringCreate.
|
||||
@param string The JSString to copy into the new CFString.
|
||||
@result A CFString containing string. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JSStringRefCF_h */
|
||||
@@ -1,301 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JSValueRef_h
|
||||
#define JSValueRef_h
|
||||
|
||||
#include <JavaScriptCore/JSBase.h>
|
||||
#include <JavaScriptCore/WebKitAvailability.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@enum JSType
|
||||
@abstract A constant identifying the type of a JSValue.
|
||||
@constant kJSTypeUndefined The unique undefined value.
|
||||
@constant kJSTypeNull The unique null value.
|
||||
@constant kJSTypeBoolean A primitive boolean value, one of true or false.
|
||||
@constant kJSTypeNumber A primitive number value.
|
||||
@constant kJSTypeString A primitive string value.
|
||||
@constant kJSTypeObject An object value (meaning that this JSValueRef is a JSObjectRef).
|
||||
*/
|
||||
typedef enum {
|
||||
kJSTypeUndefined,
|
||||
kJSTypeNull,
|
||||
kJSTypeBoolean,
|
||||
kJSTypeNumber,
|
||||
kJSTypeString,
|
||||
kJSTypeObject
|
||||
} JSType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Returns a JavaScript value's type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue whose type you want to obtain.
|
||||
@result A value of type JSType that identifies value's type.
|
||||
*/
|
||||
JS_EXPORT JSType JSValueGetType(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value's type is the undefined type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@result true if value's type is the undefined type, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value's type is the null type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@result true if value's type is the null type, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsNull(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value's type is the boolean type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@result true if value's type is the boolean type, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value's type is the number type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@result true if value's type is the number type, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsNumber(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value's type is the string type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@result true if value's type is the string type, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsString(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value's type is the object type.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@result true if value's type is the object type, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsObject(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value is an object with a given class in its class chain.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@param jsClass The JSClass to test against.
|
||||
@result true if value is an object and has jsClass in its class chain, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass);
|
||||
|
||||
/* Comparing values */
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether two JavaScript values are equal, as compared by the JS == operator.
|
||||
@param ctx The execution context to use.
|
||||
@param a The first value to test.
|
||||
@param b The second value to test.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result true if the two values are equal, false if they are not equal or an exception is thrown.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether two JavaScript values are strict equal, as compared by the JS === operator.
|
||||
@param ctx The execution context to use.
|
||||
@param a The first value to test.
|
||||
@param b The second value to test.
|
||||
@result true if the two values are strict equal, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Tests whether a JavaScript value is an object constructed by a given constructor, as compared by the JS instanceof operator.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to test.
|
||||
@param constructor The constructor to test against.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result true if value is an object constructed by constructor, as compared by the JS instanceof operator, otherwise false.
|
||||
*/
|
||||
JS_EXPORT bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception);
|
||||
|
||||
/* Creating values */
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript value of the undefined type.
|
||||
@param ctx The execution context to use.
|
||||
@result The unique undefined value.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSValueMakeUndefined(JSContextRef ctx);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript value of the null type.
|
||||
@param ctx The execution context to use.
|
||||
@result The unique null value.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSValueMakeNull(JSContextRef ctx);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript value of the boolean type.
|
||||
@param ctx The execution context to use.
|
||||
@param boolean The bool to assign to the newly created JSValue.
|
||||
@result A JSValue of the boolean type, representing the value of boolean.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool boolean);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript value of the number type.
|
||||
@param ctx The execution context to use.
|
||||
@param number The double to assign to the newly created JSValue.
|
||||
@result A JSValue of the number type, representing the value of number.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSValueMakeNumber(JSContextRef ctx, double number);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript value of the string type.
|
||||
@param ctx The execution context to use.
|
||||
@param string The JSString to assign to the newly created JSValue. The
|
||||
newly created JSValue retains string, and releases it upon garbage collection.
|
||||
@result A JSValue of the string type, representing the value of string.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string);
|
||||
|
||||
/* Converting to and from JSON formatted strings */
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript value from a JSON formatted string.
|
||||
@param ctx The execution context to use.
|
||||
@param string The JSString containing the JSON string to be parsed.
|
||||
@result A JSValue containing the parsed value, or NULL if the input is invalid.
|
||||
*/
|
||||
JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) AVAILABLE_AFTER_WEBKIT_VERSION_4_0;
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Creates a JavaScript string containing the JSON serialized representation of a JS value.
|
||||
@param ctx The execution context to use.
|
||||
@param value The value to serialize.
|
||||
@param indent The number of spaces to indent when nesting. If 0, the resulting JSON will not contains newlines. The size of the indent is clamped to 10 spaces.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result A JSString with the result of serialization, or NULL if an exception is thrown.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_4_0;
|
||||
|
||||
/* Converting to primitive values */
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Converts a JavaScript value to boolean and returns the resulting boolean.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to convert.
|
||||
@result The boolean result of conversion.
|
||||
*/
|
||||
JS_EXPORT bool JSValueToBoolean(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Converts a JavaScript value to number and returns the resulting number.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to convert.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The numeric result of conversion, or NaN if an exception is thrown.
|
||||
*/
|
||||
JS_EXPORT double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Converts a JavaScript value to string and copies the result into a JavaScript string.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to convert.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result A JSString with the result of conversion, or NULL if an exception is thrown. Ownership follows the Create Rule.
|
||||
*/
|
||||
JS_EXPORT JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Converts a JavaScript value to object and returns the resulting object.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to convert.
|
||||
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
|
||||
@result The JSObject result of conversion, or NULL if an exception is thrown.
|
||||
*/
|
||||
JS_EXPORT JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
/* Garbage collection */
|
||||
/*!
|
||||
@function
|
||||
@abstract Protects a JavaScript value from garbage collection.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to protect.
|
||||
@discussion Use this method when you want to store a JSValue in a global or on the heap, where the garbage collector will not be able to discover your reference to it.
|
||||
|
||||
A value may be protected multiple times and must be unprotected an equal number of times before becoming eligible for garbage collection.
|
||||
*/
|
||||
JS_EXPORT void JSValueProtect(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Unprotects a JavaScript value from garbage collection.
|
||||
@param ctx The execution context to use.
|
||||
@param value The JSValue to unprotect.
|
||||
@discussion A value may be protected multiple times and must be unprotected an
|
||||
equal number of times before becoming eligible for garbage collection.
|
||||
*/
|
||||
JS_EXPORT void JSValueUnprotect(JSContextRef ctx, JSValueRef value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JSValueRef_h */
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
|
||||
*
|
||||
* 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JavaScript_h
|
||||
#define JavaScript_h
|
||||
|
||||
#include <JavaScriptCore/JSBase.h>
|
||||
#include <JavaScriptCore/JSContextRef.h>
|
||||
#include <JavaScriptCore/JSStringRef.h>
|
||||
#include <JavaScriptCore/JSObjectRef.h>
|
||||
#include <JavaScriptCore/JSValueRef.h>
|
||||
|
||||
#endif /* JavaScript_h */
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006, 2008 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef JavaScriptCore_h
|
||||
#define JavaScriptCore_h
|
||||
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
#include <JavaScriptCore/JSStringRefCF.h>
|
||||
|
||||
#endif /* JavaScriptCore_h */
|
||||
@@ -1,904 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008, 2009, 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef __WebKitAvailability__
|
||||
#define __WebKitAvailability__
|
||||
|
||||
/* The structure of this header is based on AvailabilityMacros.h. The major difference is that the availability
|
||||
macros are defined in terms of WebKit version numbers rather than Mac OS X system version numbers, as WebKit
|
||||
releases span multiple versions of Mac OS X.
|
||||
*/
|
||||
|
||||
#define WEBKIT_VERSION_1_0 0x0100
|
||||
#define WEBKIT_VERSION_1_1 0x0110
|
||||
#define WEBKIT_VERSION_1_2 0x0120
|
||||
#define WEBKIT_VERSION_1_3 0x0130
|
||||
#define WEBKIT_VERSION_2_0 0x0200
|
||||
#define WEBKIT_VERSION_3_0 0x0300
|
||||
#define WEBKIT_VERSION_3_1 0x0310
|
||||
#define WEBKIT_VERSION_4_0 0x0400
|
||||
#define WEBKIT_VERSION_LATEST 0x9999
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#else
|
||||
/*
|
||||
* For non-Mac platforms, require the newest version.
|
||||
*/
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST
|
||||
/*
|
||||
* only certain compilers support __attribute__((deprecated))
|
||||
*/
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
|
||||
#define DEPRECATED_ATTRIBUTE __attribute__((deprecated))
|
||||
#else
|
||||
#define DEPRECATED_ATTRIBUTE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The versions of GCC that shipped with Xcode prior to 3.0 (GCC build number < 5400) did not support attributes on methods.
|
||||
If we are building with one of these versions, we need to omit the attribute. We achieve this by wrapping the annotation
|
||||
in WEBKIT_OBJC_METHOD_ANNOTATION, which will remove the annotation when an old version of GCC is in use and will otherwise
|
||||
expand to the annotation. The same is needed for protocol methods.
|
||||
*/
|
||||
#if defined(__APPLE_CC__) && __APPLE_CC__ < 5400
|
||||
#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION)
|
||||
#else
|
||||
#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION
|
||||
#endif
|
||||
|
||||
|
||||
/* If minimum WebKit version is not specified, assume the version that shipped with the target Mac OS X version */
|
||||
#ifndef WEBKIT_VERSION_MIN_REQUIRED
|
||||
#if !defined(MAC_OS_X_VERSION_10_2) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2
|
||||
#error WebKit was not available prior to Mac OS X 10.2
|
||||
#elif !defined(MAC_OS_X_VERSION_10_3) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
|
||||
/* WebKit 1.0 is the only version available on Mac OS X 10.2. */
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_1_0
|
||||
#elif !defined(MAC_OS_X_VERSION_10_4) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
|
||||
/* WebKit 1.1 is the version that shipped on Mac OS X 10.3. */
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_1_1
|
||||
#elif !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
|
||||
/* WebKit 2.0 is the version that shipped on Mac OS X 10.4. */
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_2_0
|
||||
#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
|
||||
/* WebKit 3.0 is the version that shipped on Mac OS X 10.5. */
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_3_0
|
||||
#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
||||
/* WebKit 4.0 is the version that shipped on Mac OS X 10.6. */
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_4_0
|
||||
#else
|
||||
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* If maximum WebKit version is not specified, assume largerof(latest, minimum) */
|
||||
#ifndef WEBKIT_VERSION_MAX_ALLOWED
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED > WEBKIT_VERSION_LATEST
|
||||
#define WEBKIT_VERSION_MAX_ALLOWED WEBKIT_VERSION_MIN_REQUIRED
|
||||
#else
|
||||
#define WEBKIT_VERSION_MAX_ALLOWED WEBKIT_VERSION_LATEST
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Sanity check the configured values */
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_MIN_REQUIRED
|
||||
#error WEBKIT_VERSION_MAX_ALLOWED must be >= WEBKIT_VERSION_MIN_REQUIRED
|
||||
#endif
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_0
|
||||
#error WEBKIT_VERSION_MIN_REQUIRED must be >= WEBKIT_VERSION_1_0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
*
|
||||
* Used on functions introduced in WebKit 1.0
|
||||
*/
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on functions introduced in WebKit 1.0,
|
||||
* and deprecated in WebKit 1.0
|
||||
*/
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_1_0_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 1.0
|
||||
*/
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_0_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_1_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* and deprecated in WebKit 1.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 1.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_1 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_1_1_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 1.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_1
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_1_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_1_2
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_2
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* and deprecated in WebKit 1.2
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 1.2
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated in WebKit 1.2
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_1_2_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 1.2
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_2_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_1_3
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_3
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3,
|
||||
* and deprecated in WebKit 1.3
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 1.3
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated in WebKit 1.3
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* but later deprecated in WebKit 1.3
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_1_3_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 1.3
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_3_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
*
|
||||
* Used on declarations introduced in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 2.0,
|
||||
* and deprecated in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* but later deprecated in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3,
|
||||
* but later deprecated in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_2_0_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 2.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_2_0_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.0,
|
||||
* and deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* but later deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3,
|
||||
* but later deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 2.0,
|
||||
* but later deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_3_0_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 3.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_3_0_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_3_0_AND_LATER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.1,
|
||||
* and deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* but later deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3,
|
||||
* but later deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 2.0,
|
||||
* but later deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.0,
|
||||
* but later deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_3_1_AND_LATER
|
||||
*
|
||||
* Used on types deprecated in WebKit 3.1
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_3_1_AND_LATER DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_3_1_AND_LATER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_IN_WEBKIT_VERSION_4_0 UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_IN_WEBKIT_VERSION_4_0 WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_IN_WEBKIT_VERSION_4_0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced in WebKit 4.0,
|
||||
* and deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED AVAILABLE_IN_WEBKIT_VERSION_4_0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 2.0,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.0,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.1,
|
||||
* but later deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on types deprecated in WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_IN_WEBKIT_VERSION_4_0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AVAILABLE_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_AFTER_WEBKIT_VERSION_4_0 UNAVAILABLE_ATTRIBUTE
|
||||
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_AFTER_WEBKIT_VERSION_4_0 WEAK_IMPORT_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_AFTER_WEBKIT_VERSION_4_0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED
|
||||
*
|
||||
* Used on declarations introduced after WebKit 4.0,
|
||||
* and deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED AVAILABLE_AFTER_WEBKIT_VERSION_4_0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.0,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.1,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.2,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 1.3,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 2.0,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.0,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 3.1,
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on declarations introduced in WebKit 4.0
|
||||
* but later deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
*
|
||||
* Used on types deprecated after WebKit 4.0
|
||||
*/
|
||||
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
|
||||
#define DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
|
||||
#else
|
||||
#define DEPRECATED_AFTER_WEBKIT_VERSION_4_0
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __WebKitAvailability__ */
|
||||
Binary file not shown.
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef APICast_h
|
||||
#define APICast_h
|
||||
|
||||
#include "JSAPIValueWrapper.h"
|
||||
#include "JSGlobalObject.h"
|
||||
#include "JSValue.h"
|
||||
#include <wtf/UnusedParam.h>
|
||||
|
||||
namespace JSC {
|
||||
class ExecState;
|
||||
class PropertyNameArray;
|
||||
class JSGlobalData;
|
||||
class JSObject;
|
||||
class JSValue;
|
||||
}
|
||||
|
||||
typedef const struct OpaqueJSContextGroup* JSContextGroupRef;
|
||||
typedef const struct OpaqueJSContext* JSContextRef;
|
||||
typedef struct OpaqueJSContext* JSGlobalContextRef;
|
||||
typedef struct OpaqueJSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
|
||||
typedef const struct OpaqueJSValue* JSValueRef;
|
||||
typedef struct OpaqueJSValue* JSObjectRef;
|
||||
|
||||
/* Opaque typing convenience methods */
|
||||
|
||||
inline JSC::ExecState* toJS(JSContextRef c)
|
||||
{
|
||||
ASSERT(c);
|
||||
return reinterpret_cast<JSC::ExecState*>(const_cast<OpaqueJSContext*>(c));
|
||||
}
|
||||
|
||||
inline JSC::ExecState* toJS(JSGlobalContextRef c)
|
||||
{
|
||||
ASSERT(c);
|
||||
return reinterpret_cast<JSC::ExecState*>(c);
|
||||
}
|
||||
|
||||
inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v)
|
||||
{
|
||||
ASSERT_UNUSED(exec, exec);
|
||||
ASSERT(v);
|
||||
#if USE(JSVALUE32_64)
|
||||
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
|
||||
if (!jsCell)
|
||||
return JSC::JSValue();
|
||||
if (jsCell->isAPIValueWrapper())
|
||||
return static_cast<JSC::JSAPIValueWrapper*>(jsCell)->value();
|
||||
return jsCell;
|
||||
#else
|
||||
return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline JSC::JSValue toJSForGC(JSC::ExecState* exec, JSValueRef v)
|
||||
{
|
||||
ASSERT_UNUSED(exec, exec);
|
||||
ASSERT(v);
|
||||
#if USE(JSVALUE32_64)
|
||||
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
|
||||
if (!jsCell)
|
||||
return JSC::JSValue();
|
||||
return jsCell;
|
||||
#else
|
||||
return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline JSC::JSObject* toJS(JSObjectRef o)
|
||||
{
|
||||
return reinterpret_cast<JSC::JSObject*>(o);
|
||||
}
|
||||
|
||||
inline JSC::PropertyNameArray* toJS(JSPropertyNameAccumulatorRef a)
|
||||
{
|
||||
return reinterpret_cast<JSC::PropertyNameArray*>(a);
|
||||
}
|
||||
|
||||
inline JSC::JSGlobalData* toJS(JSContextGroupRef g)
|
||||
{
|
||||
return reinterpret_cast<JSC::JSGlobalData*>(const_cast<OpaqueJSContextGroup*>(g));
|
||||
}
|
||||
|
||||
inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v)
|
||||
{
|
||||
#if USE(JSVALUE32_64)
|
||||
if (!v)
|
||||
return 0;
|
||||
if (!v.isCell())
|
||||
return reinterpret_cast<JSValueRef>(JSC::jsAPIValueWrapper(exec, v).asCell());
|
||||
return reinterpret_cast<JSValueRef>(v.asCell());
|
||||
#else
|
||||
UNUSED_PARAM(exec);
|
||||
return reinterpret_cast<JSValueRef>(JSC::JSValue::encode(v));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline JSObjectRef toRef(JSC::JSObject* o)
|
||||
{
|
||||
return reinterpret_cast<JSObjectRef>(o);
|
||||
}
|
||||
|
||||
inline JSObjectRef toRef(const JSC::JSObject* o)
|
||||
{
|
||||
return reinterpret_cast<JSObjectRef>(const_cast<JSC::JSObject*>(o));
|
||||
}
|
||||
|
||||
inline JSContextRef toRef(JSC::ExecState* e)
|
||||
{
|
||||
return reinterpret_cast<JSContextRef>(e);
|
||||
}
|
||||
|
||||
inline JSGlobalContextRef toGlobalRef(JSC::ExecState* e)
|
||||
{
|
||||
ASSERT(e == e->lexicalGlobalObject()->globalExec());
|
||||
return reinterpret_cast<JSGlobalContextRef>(e);
|
||||
}
|
||||
|
||||
inline JSPropertyNameAccumulatorRef toRef(JSC::PropertyNameArray* l)
|
||||
{
|
||||
return reinterpret_cast<JSPropertyNameAccumulatorRef>(l);
|
||||
}
|
||||
|
||||
inline JSContextGroupRef toRef(JSC::JSGlobalData* g)
|
||||
{
|
||||
return reinterpret_cast<JSContextGroupRef>(g);
|
||||
}
|
||||
|
||||
#endif // APICast_h
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef APIShims_h
|
||||
#define APIShims_h
|
||||
|
||||
#include "CallFrame.h"
|
||||
#include "GCActivityCallback.h"
|
||||
#include "JSLock.h"
|
||||
#include <wtf/WTFThreadData.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class APIEntryShimWithoutLock {
|
||||
protected:
|
||||
APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread)
|
||||
: m_globalData(globalData)
|
||||
, m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
|
||||
{
|
||||
UNUSED_PARAM(registerThread);
|
||||
if (registerThread)
|
||||
globalData->heap.machineThreads().addCurrentThread();
|
||||
m_globalData->heap.activityCallback()->synchronize();
|
||||
m_globalData->timeoutChecker.start();
|
||||
}
|
||||
|
||||
~APIEntryShimWithoutLock()
|
||||
{
|
||||
m_globalData->timeoutChecker.stop();
|
||||
wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
|
||||
}
|
||||
|
||||
private:
|
||||
JSGlobalData* m_globalData;
|
||||
IdentifierTable* m_entryIdentifierTable;
|
||||
};
|
||||
|
||||
class APIEntryShim : public APIEntryShimWithoutLock {
|
||||
public:
|
||||
// Normal API entry
|
||||
APIEntryShim(ExecState* exec, bool registerThread = true)
|
||||
: APIEntryShimWithoutLock(&exec->globalData(), registerThread)
|
||||
, m_lock(exec)
|
||||
{
|
||||
}
|
||||
|
||||
// JSPropertyNameAccumulator only has a globalData.
|
||||
APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
|
||||
: APIEntryShimWithoutLock(globalData, registerThread)
|
||||
, m_lock(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
JSLock m_lock;
|
||||
};
|
||||
|
||||
class APICallbackShim {
|
||||
public:
|
||||
APICallbackShim(ExecState* exec)
|
||||
: m_dropAllLocks(exec)
|
||||
, m_globalData(&exec->globalData())
|
||||
{
|
||||
wtfThreadData().resetCurrentIdentifierTable();
|
||||
}
|
||||
|
||||
~APICallbackShim()
|
||||
{
|
||||
m_globalData->heap.activityCallback()->synchronize();
|
||||
wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
|
||||
}
|
||||
|
||||
private:
|
||||
JSLock::DropAllLocks m_dropAllLocks;
|
||||
JSGlobalData* m_globalData;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007, 2008, 2009, 2011 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_ASCIICType_h
|
||||
#define WTF_ASCIICType_h
|
||||
|
||||
#include <wtf/Assertions.h>
|
||||
|
||||
// The behavior of many of the functions in the <ctype.h> header is dependent
|
||||
// on the current locale. But in the WebKit project, all uses of those functions
|
||||
// are in code processing something that's not locale-specific. These equivalents
|
||||
// for some of the <ctype.h> functions are named more explicitly, not dependent
|
||||
// on the C library locale, and we should also optimize them as needed.
|
||||
|
||||
// All functions return false or leave the character unchanged if passed a character
|
||||
// that is outside the range 0-7F. So they can be used on Unicode strings or
|
||||
// characters if the intent is to do processing only if the character is ASCII.
|
||||
|
||||
namespace WTF {
|
||||
|
||||
template<typename CharType> inline bool isASCII(CharType c)
|
||||
{
|
||||
return !(c & ~0x7F);
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIAlpha(CharType c)
|
||||
{
|
||||
return (c | 0x20) >= 'a' && (c | 0x20) <= 'z';
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIDigit(CharType c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIAlphanumeric(CharType c)
|
||||
{
|
||||
return isASCIIDigit(c) || isASCIIAlpha(c);
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIHexDigit(CharType c)
|
||||
{
|
||||
return isASCIIDigit(c) || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f');
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIILower(CharType c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z';
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIOctalDigit(CharType c)
|
||||
{
|
||||
return (c >= '0') & (c <= '7');
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIPrintable(CharType c)
|
||||
{
|
||||
return c >= ' ' && c <= '~';
|
||||
}
|
||||
|
||||
/*
|
||||
Statistics from a run of Apple's page load test for callers of isASCIISpace:
|
||||
|
||||
character count
|
||||
--------- -----
|
||||
non-spaces 689383
|
||||
20 space 294720
|
||||
0A \n 89059
|
||||
09 \t 28320
|
||||
0D \r 0
|
||||
0C \f 0
|
||||
0B \v 0
|
||||
*/
|
||||
template<typename CharType> inline bool isASCIISpace(CharType c)
|
||||
{
|
||||
return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
|
||||
}
|
||||
|
||||
template<typename CharType> inline bool isASCIIUpper(CharType c)
|
||||
{
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
|
||||
template<typename CharType> inline CharType toASCIILower(CharType c)
|
||||
{
|
||||
return c | ((c >= 'A' && c <= 'Z') << 5);
|
||||
}
|
||||
|
||||
template<typename CharType> inline CharType toASCIIUpper(CharType c)
|
||||
{
|
||||
return c & ~((c >= 'a' && c <= 'z') << 5);
|
||||
}
|
||||
|
||||
template<typename CharType> inline int toASCIIHexValue(CharType c)
|
||||
{
|
||||
ASSERT(isASCIIHexDigit(c));
|
||||
return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF;
|
||||
}
|
||||
|
||||
template<typename CharType> inline int toASCIIHexValue(CharType upperValue, CharType lowerValue)
|
||||
{
|
||||
ASSERT(isASCIIHexDigit(upperValue) && isASCIIHexDigit(lowerValue));
|
||||
return ((toASCIIHexValue(upperValue) << 4) & 0xF0) | toASCIIHexValue(lowerValue);
|
||||
}
|
||||
|
||||
inline char lowerNibbleToASCIIHexDigit(char c)
|
||||
{
|
||||
char nibble = c & 0xF;
|
||||
return nibble < 10 ? '0' + nibble : 'A' + nibble - 10;
|
||||
}
|
||||
|
||||
inline char upperNibbleToASCIIHexDigit(char c)
|
||||
{
|
||||
char nibble = (c >> 4) & 0xF;
|
||||
return nibble < 10 ? '0' + nibble : 'A' + nibble - 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using WTF::isASCII;
|
||||
using WTF::isASCIIAlpha;
|
||||
using WTF::isASCIIAlphanumeric;
|
||||
using WTF::isASCIIDigit;
|
||||
using WTF::isASCIIHexDigit;
|
||||
using WTF::isASCIILower;
|
||||
using WTF::isASCIIOctalDigit;
|
||||
using WTF::isASCIIPrintable;
|
||||
using WTF::isASCIISpace;
|
||||
using WTF::isASCIIUpper;
|
||||
using WTF::toASCIIHexValue;
|
||||
using WTF::toASCIILower;
|
||||
using WTF::toASCIIUpper;
|
||||
using WTF::lowerNibbleToASCIIHexDigit;
|
||||
using WTF::upperNibbleToASCIIHexDigit;
|
||||
|
||||
#endif
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ASCIIFastPath_h
|
||||
#define ASCIIFastPath_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wtf/unicode/Unicode.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// Assuming that a pointer is the size of a "machine word", then
|
||||
// uintptr_t is an integer type that is also a machine word.
|
||||
typedef uintptr_t MachineWord;
|
||||
const uintptr_t machineWordAlignmentMask = sizeof(MachineWord) - 1;
|
||||
|
||||
inline bool isAlignedToMachineWord(const void* pointer)
|
||||
{
|
||||
return !(reinterpret_cast<uintptr_t>(pointer) & machineWordAlignmentMask);
|
||||
}
|
||||
|
||||
template<typename T> inline T* alignToMachineWord(T* pointer)
|
||||
{
|
||||
return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(pointer) & ~machineWordAlignmentMask);
|
||||
}
|
||||
|
||||
template<size_t size, typename CharacterType> struct NonASCIIMask;
|
||||
template<> struct NonASCIIMask<4, UChar> {
|
||||
static inline uint32_t value() { return 0xFF80FF80U; }
|
||||
};
|
||||
template<> struct NonASCIIMask<4, LChar> {
|
||||
static inline uint32_t value() { return 0x80808080U; }
|
||||
};
|
||||
template<> struct NonASCIIMask<8, UChar> {
|
||||
static inline uint64_t value() { return 0xFF80FF80FF80FF80ULL; }
|
||||
};
|
||||
template<> struct NonASCIIMask<8, LChar> {
|
||||
static inline uint64_t value() { return 0x8080808080808080ULL; }
|
||||
};
|
||||
|
||||
|
||||
template<typename CharacterType>
|
||||
inline bool isAllASCII(MachineWord word)
|
||||
{
|
||||
return !(word & NonASCIIMask<sizeof(MachineWord), CharacterType>::value());
|
||||
}
|
||||
|
||||
// Note: This function assume the input is likely all ASCII, and
|
||||
// does not leave early if it is not the case.
|
||||
template<typename CharacterType>
|
||||
inline bool charactersAreAllASCII(const CharacterType* characters, size_t length)
|
||||
{
|
||||
MachineWord allCharBits = 0;
|
||||
const CharacterType* end = characters + length;
|
||||
|
||||
// Prologue: align the input.
|
||||
while (!isAlignedToMachineWord(characters) && characters != end) {
|
||||
allCharBits |= *characters;
|
||||
++characters;
|
||||
}
|
||||
|
||||
// Compare the values of CPU word size.
|
||||
const CharacterType* wordEnd = alignToMachineWord(end);
|
||||
const size_t loopIncrement = sizeof(MachineWord) / sizeof(CharacterType);
|
||||
while (characters < wordEnd) {
|
||||
allCharBits |= *(reinterpret_cast<const MachineWord*>(characters));
|
||||
characters += loopIncrement;
|
||||
}
|
||||
|
||||
// Process the remaining bytes.
|
||||
while (characters != end) {
|
||||
allCharBits |= *characters;
|
||||
++characters;
|
||||
}
|
||||
|
||||
MachineWord nonASCIIBitMask = NonASCIIMask<sizeof(MachineWord), CharacterType>::value();
|
||||
return !(allCharBits & nonASCIIBitMask);
|
||||
}
|
||||
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
#endif // ASCIIFastPath_h
|
||||
@@ -1,960 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Based on Abstract AVL Tree Template v1.5 by Walt Karas
|
||||
* <http://geocities.com/wkaras/gen_cpp/avl_tree.html>.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef AVL_TREE_H_
|
||||
#define AVL_TREE_H_
|
||||
|
||||
#include "Assertions.h"
|
||||
#include <wtf/FixedArray.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// Here is the reference class for BSet.
|
||||
//
|
||||
// class BSet
|
||||
// {
|
||||
// public:
|
||||
//
|
||||
// class ANY_bitref
|
||||
// {
|
||||
// public:
|
||||
// operator bool ();
|
||||
// void operator = (bool b);
|
||||
// };
|
||||
//
|
||||
// // Does not have to initialize bits.
|
||||
// BSet();
|
||||
//
|
||||
// // Must return a valid value for index when 0 <= index < maxDepth
|
||||
// ANY_bitref operator [] (unsigned index);
|
||||
//
|
||||
// // Set all bits to 1.
|
||||
// void set();
|
||||
//
|
||||
// // Set all bits to 0.
|
||||
// void reset();
|
||||
// };
|
||||
|
||||
template<unsigned maxDepth>
|
||||
class AVLTreeDefaultBSet {
|
||||
public:
|
||||
bool& operator[](unsigned i) { ASSERT(i < maxDepth); return m_data[i]; }
|
||||
void set() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = true; }
|
||||
void reset() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = false; }
|
||||
|
||||
private:
|
||||
FixedArray<bool, maxDepth> m_data;
|
||||
};
|
||||
|
||||
// How to determine maxDepth:
|
||||
// d Minimum number of nodes
|
||||
// 2 2
|
||||
// 3 4
|
||||
// 4 7
|
||||
// 5 12
|
||||
// 6 20
|
||||
// 7 33
|
||||
// 8 54
|
||||
// 9 88
|
||||
// 10 143
|
||||
// 11 232
|
||||
// 12 376
|
||||
// 13 609
|
||||
// 14 986
|
||||
// 15 1,596
|
||||
// 16 2,583
|
||||
// 17 4,180
|
||||
// 18 6,764
|
||||
// 19 10,945
|
||||
// 20 17,710
|
||||
// 21 28,656
|
||||
// 22 46,367
|
||||
// 23 75,024
|
||||
// 24 121,392
|
||||
// 25 196,417
|
||||
// 26 317,810
|
||||
// 27 514,228
|
||||
// 28 832,039
|
||||
// 29 1,346,268
|
||||
// 30 2,178,308
|
||||
// 31 3,524,577
|
||||
// 32 5,702,886
|
||||
// 33 9,227,464
|
||||
// 34 14,930,351
|
||||
// 35 24,157,816
|
||||
// 36 39,088,168
|
||||
// 37 63,245,985
|
||||
// 38 102,334,154
|
||||
// 39 165,580,140
|
||||
// 40 267,914,295
|
||||
// 41 433,494,436
|
||||
// 42 701,408,732
|
||||
// 43 1,134,903,169
|
||||
// 44 1,836,311,902
|
||||
// 45 2,971,215,072
|
||||
//
|
||||
// E.g., if, in a particular instantiation, the maximum number of nodes in a tree instance is 1,000,000, the maximum depth should be 28.
|
||||
// You pick 28 because MN(28) is 832,039, which is less than or equal to 1,000,000, and MN(29) is 1,346,268, which is strictly greater than 1,000,000.
|
||||
|
||||
template <class Abstractor, unsigned maxDepth = 32, class BSet = AVLTreeDefaultBSet<maxDepth> >
|
||||
class AVLTree {
|
||||
public:
|
||||
|
||||
typedef typename Abstractor::key key;
|
||||
typedef typename Abstractor::handle handle;
|
||||
typedef typename Abstractor::size size;
|
||||
|
||||
enum SearchType {
|
||||
EQUAL = 1,
|
||||
LESS = 2,
|
||||
GREATER = 4,
|
||||
LESS_EQUAL = EQUAL | LESS,
|
||||
GREATER_EQUAL = EQUAL | GREATER
|
||||
};
|
||||
|
||||
|
||||
Abstractor& abstractor() { return abs; }
|
||||
|
||||
inline handle insert(handle h);
|
||||
|
||||
inline handle search(key k, SearchType st = EQUAL);
|
||||
inline handle search_least();
|
||||
inline handle search_greatest();
|
||||
|
||||
inline handle remove(key k);
|
||||
|
||||
inline handle subst(handle new_node);
|
||||
|
||||
void purge() { abs.root = null(); }
|
||||
|
||||
bool is_empty() { return abs.root == null(); }
|
||||
|
||||
AVLTree() { abs.root = null(); }
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
|
||||
// Initialize depth to invalid value, to indicate iterator is
|
||||
// invalid. (Depth is zero-base.)
|
||||
Iterator() { depth = ~0U; }
|
||||
|
||||
void start_iter(AVLTree &tree, key k, SearchType st = EQUAL)
|
||||
{
|
||||
// Mask of high bit in an int.
|
||||
const int MASK_HIGH_BIT = (int) ~ ((~ (unsigned) 0) >> 1);
|
||||
|
||||
// Save the tree that we're going to iterate through in a
|
||||
// member variable.
|
||||
tree_ = &tree;
|
||||
|
||||
int cmp, target_cmp;
|
||||
handle h = tree_->abs.root;
|
||||
unsigned d = 0;
|
||||
|
||||
depth = ~0U;
|
||||
|
||||
if (h == null())
|
||||
// Tree is empty.
|
||||
return;
|
||||
|
||||
if (st & LESS)
|
||||
// Key can be greater than key of starting node.
|
||||
target_cmp = 1;
|
||||
else if (st & GREATER)
|
||||
// Key can be less than key of starting node.
|
||||
target_cmp = -1;
|
||||
else
|
||||
// Key must be same as key of starting node.
|
||||
target_cmp = 0;
|
||||
|
||||
for (;;) {
|
||||
cmp = cmp_k_n(k, h);
|
||||
if (cmp == 0) {
|
||||
if (st & EQUAL) {
|
||||
// Equal node was sought and found as starting node.
|
||||
depth = d;
|
||||
break;
|
||||
}
|
||||
cmp = -target_cmp;
|
||||
} else if (target_cmp != 0) {
|
||||
if (!((cmp ^ target_cmp) & MASK_HIGH_BIT)) {
|
||||
// cmp and target_cmp are both negative or both positive.
|
||||
depth = d;
|
||||
}
|
||||
}
|
||||
h = cmp < 0 ? get_lt(h) : get_gt(h);
|
||||
if (h == null())
|
||||
break;
|
||||
branch[d] = cmp > 0;
|
||||
path_h[d++] = h;
|
||||
}
|
||||
}
|
||||
|
||||
void start_iter_least(AVLTree &tree)
|
||||
{
|
||||
tree_ = &tree;
|
||||
|
||||
handle h = tree_->abs.root;
|
||||
|
||||
depth = ~0U;
|
||||
|
||||
branch.reset();
|
||||
|
||||
while (h != null()) {
|
||||
if (depth != ~0U)
|
||||
path_h[depth] = h;
|
||||
depth++;
|
||||
h = get_lt(h);
|
||||
}
|
||||
}
|
||||
|
||||
void start_iter_greatest(AVLTree &tree)
|
||||
{
|
||||
tree_ = &tree;
|
||||
|
||||
handle h = tree_->abs.root;
|
||||
|
||||
depth = ~0U;
|
||||
|
||||
branch.set();
|
||||
|
||||
while (h != null()) {
|
||||
if (depth != ~0U)
|
||||
path_h[depth] = h;
|
||||
depth++;
|
||||
h = get_gt(h);
|
||||
}
|
||||
}
|
||||
|
||||
handle operator*()
|
||||
{
|
||||
if (depth == ~0U)
|
||||
return null();
|
||||
|
||||
return depth == 0 ? tree_->abs.root : path_h[depth - 1];
|
||||
}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
if (depth != ~0U) {
|
||||
handle h = get_gt(**this);
|
||||
if (h == null()) {
|
||||
do {
|
||||
if (depth == 0) {
|
||||
depth = ~0U;
|
||||
break;
|
||||
}
|
||||
depth--;
|
||||
} while (branch[depth]);
|
||||
} else {
|
||||
branch[depth] = true;
|
||||
path_h[depth++] = h;
|
||||
for (;;) {
|
||||
h = get_lt(h);
|
||||
if (h == null())
|
||||
break;
|
||||
branch[depth] = false;
|
||||
path_h[depth++] = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void operator--()
|
||||
{
|
||||
if (depth != ~0U) {
|
||||
handle h = get_lt(**this);
|
||||
if (h == null())
|
||||
do {
|
||||
if (depth == 0) {
|
||||
depth = ~0U;
|
||||
break;
|
||||
}
|
||||
depth--;
|
||||
} while (!branch[depth]);
|
||||
else {
|
||||
branch[depth] = false;
|
||||
path_h[depth++] = h;
|
||||
for (;;) {
|
||||
h = get_gt(h);
|
||||
if (h == null())
|
||||
break;
|
||||
branch[depth] = true;
|
||||
path_h[depth++] = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void operator++(int) { ++(*this); }
|
||||
void operator--(int) { --(*this); }
|
||||
|
||||
protected:
|
||||
|
||||
// Tree being iterated over.
|
||||
AVLTree *tree_;
|
||||
|
||||
// Records a path into the tree. If branch[n] is true, indicates
|
||||
// take greater branch from the nth node in the path, otherwise
|
||||
// take the less branch. branch[0] gives branch from root, and
|
||||
// so on.
|
||||
BSet branch;
|
||||
|
||||
// Zero-based depth of path into tree.
|
||||
unsigned depth;
|
||||
|
||||
// Handles of nodes in path from root to current node (returned by *).
|
||||
handle path_h[maxDepth - 1];
|
||||
|
||||
int cmp_k_n(key k, handle h) { return tree_->abs.compare_key_node(k, h); }
|
||||
int cmp_n_n(handle h1, handle h2) { return tree_->abs.compare_node_node(h1, h2); }
|
||||
handle get_lt(handle h) { return tree_->abs.get_less(h); }
|
||||
handle get_gt(handle h) { return tree_->abs.get_greater(h); }
|
||||
handle null() { return tree_->abs.null(); }
|
||||
};
|
||||
|
||||
template<typename fwd_iter>
|
||||
bool build(fwd_iter p, size num_nodes)
|
||||
{
|
||||
if (num_nodes == 0) {
|
||||
abs.root = null();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gives path to subtree being built. If branch[N] is false, branch
|
||||
// less from the node at depth N, if true branch greater.
|
||||
BSet branch;
|
||||
|
||||
// If rem[N] is true, then for the current subtree at depth N, it's
|
||||
// greater subtree has one more node than it's less subtree.
|
||||
BSet rem;
|
||||
|
||||
// Depth of root node of current subtree.
|
||||
unsigned depth = 0;
|
||||
|
||||
// Number of nodes in current subtree.
|
||||
size num_sub = num_nodes;
|
||||
|
||||
// The algorithm relies on a stack of nodes whose less subtree has
|
||||
// been built, but whose right subtree has not yet been built. The
|
||||
// stack is implemented as linked list. The nodes are linked
|
||||
// together by having the "greater" handle of a node set to the
|
||||
// next node in the list. "less_parent" is the handle of the first
|
||||
// node in the list.
|
||||
handle less_parent = null();
|
||||
|
||||
// h is root of current subtree, child is one of its children.
|
||||
handle h, child;
|
||||
|
||||
for (;;) {
|
||||
while (num_sub > 2) {
|
||||
// Subtract one for root of subtree.
|
||||
num_sub--;
|
||||
rem[depth] = !!(num_sub & 1);
|
||||
branch[depth++] = false;
|
||||
num_sub >>= 1;
|
||||
}
|
||||
|
||||
if (num_sub == 2) {
|
||||
// Build a subtree with two nodes, slanting to greater.
|
||||
// I arbitrarily chose to always have the extra node in the
|
||||
// greater subtree when there is an odd number of nodes to
|
||||
// split between the two subtrees.
|
||||
|
||||
h = *p;
|
||||
p++;
|
||||
child = *p;
|
||||
p++;
|
||||
set_lt(child, null());
|
||||
set_gt(child, null());
|
||||
set_bf(child, 0);
|
||||
set_gt(h, child);
|
||||
set_lt(h, null());
|
||||
set_bf(h, 1);
|
||||
} else { // num_sub == 1
|
||||
// Build a subtree with one node.
|
||||
|
||||
h = *p;
|
||||
p++;
|
||||
set_lt(h, null());
|
||||
set_gt(h, null());
|
||||
set_bf(h, 0);
|
||||
}
|
||||
|
||||
while (depth) {
|
||||
depth--;
|
||||
if (!branch[depth])
|
||||
// We've completed a less subtree.
|
||||
break;
|
||||
|
||||
// We've completed a greater subtree, so attach it to
|
||||
// its parent (that is less than it). We pop the parent
|
||||
// off the stack of less parents.
|
||||
child = h;
|
||||
h = less_parent;
|
||||
less_parent = get_gt(h);
|
||||
set_gt(h, child);
|
||||
// num_sub = 2 * (num_sub - rem[depth]) + rem[depth] + 1
|
||||
num_sub <<= 1;
|
||||
num_sub += 1 - rem[depth];
|
||||
if (num_sub & (num_sub - 1))
|
||||
// num_sub is not a power of 2
|
||||
set_bf(h, 0);
|
||||
else
|
||||
// num_sub is a power of 2
|
||||
set_bf(h, 1);
|
||||
}
|
||||
|
||||
if (num_sub == num_nodes)
|
||||
// We've completed the full tree.
|
||||
break;
|
||||
|
||||
// The subtree we've completed is the less subtree of the
|
||||
// next node in the sequence.
|
||||
|
||||
child = h;
|
||||
h = *p;
|
||||
p++;
|
||||
set_lt(h, child);
|
||||
|
||||
// Put h into stack of less parents.
|
||||
set_gt(h, less_parent);
|
||||
less_parent = h;
|
||||
|
||||
// Proceed to creating greater than subtree of h.
|
||||
branch[depth] = true;
|
||||
num_sub += rem[depth++];
|
||||
|
||||
} // end for (;;)
|
||||
|
||||
abs.root = h;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class Iterator;
|
||||
|
||||
// Create a class whose sole purpose is to take advantage of
|
||||
// the "empty member" optimization.
|
||||
struct abs_plus_root : public Abstractor {
|
||||
// The handle of the root element in the AVL tree.
|
||||
handle root;
|
||||
};
|
||||
|
||||
abs_plus_root abs;
|
||||
|
||||
|
||||
handle get_lt(handle h) { return abs.get_less(h); }
|
||||
void set_lt(handle h, handle lh) { abs.set_less(h, lh); }
|
||||
|
||||
handle get_gt(handle h) { return abs.get_greater(h); }
|
||||
void set_gt(handle h, handle gh) { abs.set_greater(h, gh); }
|
||||
|
||||
int get_bf(handle h) { return abs.get_balance_factor(h); }
|
||||
void set_bf(handle h, int bf) { abs.set_balance_factor(h, bf); }
|
||||
|
||||
int cmp_k_n(key k, handle h) { return abs.compare_key_node(k, h); }
|
||||
int cmp_n_n(handle h1, handle h2) { return abs.compare_node_node(h1, h2); }
|
||||
|
||||
handle null() { return abs.null(); }
|
||||
|
||||
private:
|
||||
|
||||
// Balances subtree, returns handle of root node of subtree
|
||||
// after balancing.
|
||||
handle balance(handle bal_h)
|
||||
{
|
||||
handle deep_h;
|
||||
|
||||
// Either the "greater than" or the "less than" subtree of
|
||||
// this node has to be 2 levels deeper (or else it wouldn't
|
||||
// need balancing).
|
||||
|
||||
if (get_bf(bal_h) > 0) {
|
||||
// "Greater than" subtree is deeper.
|
||||
|
||||
deep_h = get_gt(bal_h);
|
||||
|
||||
if (get_bf(deep_h) < 0) {
|
||||
handle old_h = bal_h;
|
||||
bal_h = get_lt(deep_h);
|
||||
|
||||
set_gt(old_h, get_lt(bal_h));
|
||||
set_lt(deep_h, get_gt(bal_h));
|
||||
set_lt(bal_h, old_h);
|
||||
set_gt(bal_h, deep_h);
|
||||
|
||||
int bf = get_bf(bal_h);
|
||||
if (bf != 0) {
|
||||
if (bf > 0) {
|
||||
set_bf(old_h, -1);
|
||||
set_bf(deep_h, 0);
|
||||
} else {
|
||||
set_bf(deep_h, 1);
|
||||
set_bf(old_h, 0);
|
||||
}
|
||||
set_bf(bal_h, 0);
|
||||
} else {
|
||||
set_bf(old_h, 0);
|
||||
set_bf(deep_h, 0);
|
||||
}
|
||||
} else {
|
||||
set_gt(bal_h, get_lt(deep_h));
|
||||
set_lt(deep_h, bal_h);
|
||||
if (get_bf(deep_h) == 0) {
|
||||
set_bf(deep_h, -1);
|
||||
set_bf(bal_h, 1);
|
||||
} else {
|
||||
set_bf(deep_h, 0);
|
||||
set_bf(bal_h, 0);
|
||||
}
|
||||
bal_h = deep_h;
|
||||
}
|
||||
} else {
|
||||
// "Less than" subtree is deeper.
|
||||
|
||||
deep_h = get_lt(bal_h);
|
||||
|
||||
if (get_bf(deep_h) > 0) {
|
||||
handle old_h = bal_h;
|
||||
bal_h = get_gt(deep_h);
|
||||
set_lt(old_h, get_gt(bal_h));
|
||||
set_gt(deep_h, get_lt(bal_h));
|
||||
set_gt(bal_h, old_h);
|
||||
set_lt(bal_h, deep_h);
|
||||
|
||||
int bf = get_bf(bal_h);
|
||||
if (bf != 0) {
|
||||
if (bf < 0) {
|
||||
set_bf(old_h, 1);
|
||||
set_bf(deep_h, 0);
|
||||
} else {
|
||||
set_bf(deep_h, -1);
|
||||
set_bf(old_h, 0);
|
||||
}
|
||||
set_bf(bal_h, 0);
|
||||
} else {
|
||||
set_bf(old_h, 0);
|
||||
set_bf(deep_h, 0);
|
||||
}
|
||||
} else {
|
||||
set_lt(bal_h, get_gt(deep_h));
|
||||
set_gt(deep_h, bal_h);
|
||||
if (get_bf(deep_h) == 0) {
|
||||
set_bf(deep_h, 1);
|
||||
set_bf(bal_h, -1);
|
||||
} else {
|
||||
set_bf(deep_h, 0);
|
||||
set_bf(bal_h, 0);
|
||||
}
|
||||
bal_h = deep_h;
|
||||
}
|
||||
}
|
||||
|
||||
return bal_h;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class Abstractor, unsigned maxDepth, class BSet>
|
||||
inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
|
||||
AVLTree<Abstractor, maxDepth, BSet>::insert(handle h)
|
||||
{
|
||||
set_lt(h, null());
|
||||
set_gt(h, null());
|
||||
set_bf(h, 0);
|
||||
|
||||
if (abs.root == null())
|
||||
abs.root = h;
|
||||
else {
|
||||
// Last unbalanced node encountered in search for insertion point.
|
||||
handle unbal = null();
|
||||
// Parent of last unbalanced node.
|
||||
handle parent_unbal = null();
|
||||
// Balance factor of last unbalanced node.
|
||||
int unbal_bf;
|
||||
|
||||
// Zero-based depth in tree.
|
||||
unsigned depth = 0, unbal_depth = 0;
|
||||
|
||||
// Records a path into the tree. If branch[n] is true, indicates
|
||||
// take greater branch from the nth node in the path, otherwise
|
||||
// take the less branch. branch[0] gives branch from root, and
|
||||
// so on.
|
||||
BSet branch;
|
||||
|
||||
handle hh = abs.root;
|
||||
handle parent = null();
|
||||
int cmp;
|
||||
|
||||
do {
|
||||
if (get_bf(hh) != 0) {
|
||||
unbal = hh;
|
||||
parent_unbal = parent;
|
||||
unbal_depth = depth;
|
||||
}
|
||||
cmp = cmp_n_n(h, hh);
|
||||
if (cmp == 0)
|
||||
// Duplicate key.
|
||||
return hh;
|
||||
parent = hh;
|
||||
hh = cmp < 0 ? get_lt(hh) : get_gt(hh);
|
||||
branch[depth++] = cmp > 0;
|
||||
} while (hh != null());
|
||||
|
||||
// Add node to insert as leaf of tree.
|
||||
if (cmp < 0)
|
||||
set_lt(parent, h);
|
||||
else
|
||||
set_gt(parent, h);
|
||||
|
||||
depth = unbal_depth;
|
||||
|
||||
if (unbal == null())
|
||||
hh = abs.root;
|
||||
else {
|
||||
cmp = branch[depth++] ? 1 : -1;
|
||||
unbal_bf = get_bf(unbal);
|
||||
if (cmp < 0)
|
||||
unbal_bf--;
|
||||
else // cmp > 0
|
||||
unbal_bf++;
|
||||
hh = cmp < 0 ? get_lt(unbal) : get_gt(unbal);
|
||||
if ((unbal_bf != -2) && (unbal_bf != 2)) {
|
||||
// No rebalancing of tree is necessary.
|
||||
set_bf(unbal, unbal_bf);
|
||||
unbal = null();
|
||||
}
|
||||
}
|
||||
|
||||
if (hh != null())
|
||||
while (h != hh) {
|
||||
cmp = branch[depth++] ? 1 : -1;
|
||||
if (cmp < 0) {
|
||||
set_bf(hh, -1);
|
||||
hh = get_lt(hh);
|
||||
} else { // cmp > 0
|
||||
set_bf(hh, 1);
|
||||
hh = get_gt(hh);
|
||||
}
|
||||
}
|
||||
|
||||
if (unbal != null()) {
|
||||
unbal = balance(unbal);
|
||||
if (parent_unbal == null())
|
||||
abs.root = unbal;
|
||||
else {
|
||||
depth = unbal_depth - 1;
|
||||
cmp = branch[depth] ? 1 : -1;
|
||||
if (cmp < 0)
|
||||
set_lt(parent_unbal, unbal);
|
||||
else // cmp > 0
|
||||
set_gt(parent_unbal, unbal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
template <class Abstractor, unsigned maxDepth, class BSet>
|
||||
inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
|
||||
AVLTree<Abstractor, maxDepth, BSet>::search(key k, typename AVLTree<Abstractor, maxDepth, BSet>::SearchType st)
|
||||
{
|
||||
const int MASK_HIGH_BIT = (int) ~ ((~ (unsigned) 0) >> 1);
|
||||
|
||||
int cmp, target_cmp;
|
||||
handle match_h = null();
|
||||
handle h = abs.root;
|
||||
|
||||
if (st & LESS)
|
||||
target_cmp = 1;
|
||||
else if (st & GREATER)
|
||||
target_cmp = -1;
|
||||
else
|
||||
target_cmp = 0;
|
||||
|
||||
while (h != null()) {
|
||||
cmp = cmp_k_n(k, h);
|
||||
if (cmp == 0) {
|
||||
if (st & EQUAL) {
|
||||
match_h = h;
|
||||
break;
|
||||
}
|
||||
cmp = -target_cmp;
|
||||
} else if (target_cmp != 0)
|
||||
if (!((cmp ^ target_cmp) & MASK_HIGH_BIT))
|
||||
// cmp and target_cmp are both positive or both negative.
|
||||
match_h = h;
|
||||
h = cmp < 0 ? get_lt(h) : get_gt(h);
|
||||
}
|
||||
|
||||
return match_h;
|
||||
}
|
||||
|
||||
template <class Abstractor, unsigned maxDepth, class BSet>
|
||||
inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
|
||||
AVLTree<Abstractor, maxDepth, BSet>::search_least()
|
||||
{
|
||||
handle h = abs.root, parent = null();
|
||||
|
||||
while (h != null()) {
|
||||
parent = h;
|
||||
h = get_lt(h);
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
template <class Abstractor, unsigned maxDepth, class BSet>
|
||||
inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
|
||||
AVLTree<Abstractor, maxDepth, BSet>::search_greatest()
|
||||
{
|
||||
handle h = abs.root, parent = null();
|
||||
|
||||
while (h != null()) {
|
||||
parent = h;
|
||||
h = get_gt(h);
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
template <class Abstractor, unsigned maxDepth, class BSet>
|
||||
inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
|
||||
AVLTree<Abstractor, maxDepth, BSet>::remove(key k)
|
||||
{
|
||||
// Zero-based depth in tree.
|
||||
unsigned depth = 0, rm_depth;
|
||||
|
||||
// Records a path into the tree. If branch[n] is true, indicates
|
||||
// take greater branch from the nth node in the path, otherwise
|
||||
// take the less branch. branch[0] gives branch from root, and
|
||||
// so on.
|
||||
BSet branch;
|
||||
|
||||
handle h = abs.root;
|
||||
handle parent = null(), child;
|
||||
int cmp, cmp_shortened_sub_with_path = 0;
|
||||
|
||||
for (;;) {
|
||||
if (h == null())
|
||||
// No node in tree with given key.
|
||||
return null();
|
||||
cmp = cmp_k_n(k, h);
|
||||
if (cmp == 0)
|
||||
// Found node to remove.
|
||||
break;
|
||||
parent = h;
|
||||
h = cmp < 0 ? get_lt(h) : get_gt(h);
|
||||
branch[depth++] = cmp > 0;
|
||||
cmp_shortened_sub_with_path = cmp;
|
||||
}
|
||||
handle rm = h;
|
||||
handle parent_rm = parent;
|
||||
rm_depth = depth;
|
||||
|
||||
// If the node to remove is not a leaf node, we need to get a
|
||||
// leaf node, or a node with a single leaf as its child, to put
|
||||
// in the place of the node to remove. We will get the greatest
|
||||
// node in the less subtree (of the node to remove), or the least
|
||||
// node in the greater subtree. We take the leaf node from the
|
||||
// deeper subtree, if there is one.
|
||||
|
||||
if (get_bf(h) < 0) {
|
||||
child = get_lt(h);
|
||||
branch[depth] = false;
|
||||
cmp = -1;
|
||||
} else {
|
||||
child = get_gt(h);
|
||||
branch[depth] = true;
|
||||
cmp = 1;
|
||||
}
|
||||
depth++;
|
||||
|
||||
if (child != null()) {
|
||||
cmp = -cmp;
|
||||
do {
|
||||
parent = h;
|
||||
h = child;
|
||||
if (cmp < 0) {
|
||||
child = get_lt(h);
|
||||
branch[depth] = false;
|
||||
} else {
|
||||
child = get_gt(h);
|
||||
branch[depth] = true;
|
||||
}
|
||||
depth++;
|
||||
} while (child != null());
|
||||
|
||||
if (parent == rm)
|
||||
// Only went through do loop once. Deleted node will be replaced
|
||||
// in the tree structure by one of its immediate children.
|
||||
cmp_shortened_sub_with_path = -cmp;
|
||||
else
|
||||
cmp_shortened_sub_with_path = cmp;
|
||||
|
||||
// Get the handle of the opposite child, which may not be null.
|
||||
child = cmp > 0 ? get_lt(h) : get_gt(h);
|
||||
}
|
||||
|
||||
if (parent == null())
|
||||
// There were only 1 or 2 nodes in this tree.
|
||||
abs.root = child;
|
||||
else if (cmp_shortened_sub_with_path < 0)
|
||||
set_lt(parent, child);
|
||||
else
|
||||
set_gt(parent, child);
|
||||
|
||||
// "path" is the parent of the subtree being eliminated or reduced
|
||||
// from a depth of 2 to 1. If "path" is the node to be removed, we
|
||||
// set path to the node we're about to poke into the position of the
|
||||
// node to be removed.
|
||||
handle path = parent == rm ? h : parent;
|
||||
|
||||
if (h != rm) {
|
||||
// Poke in the replacement for the node to be removed.
|
||||
set_lt(h, get_lt(rm));
|
||||
set_gt(h, get_gt(rm));
|
||||
set_bf(h, get_bf(rm));
|
||||
if (parent_rm == null())
|
||||
abs.root = h;
|
||||
else {
|
||||
depth = rm_depth - 1;
|
||||
if (branch[depth])
|
||||
set_gt(parent_rm, h);
|
||||
else
|
||||
set_lt(parent_rm, h);
|
||||
}
|
||||
}
|
||||
|
||||
if (path != null()) {
|
||||
// Create a temporary linked list from the parent of the path node
|
||||
// to the root node.
|
||||
h = abs.root;
|
||||
parent = null();
|
||||
depth = 0;
|
||||
while (h != path) {
|
||||
if (branch[depth++]) {
|
||||
child = get_gt(h);
|
||||
set_gt(h, parent);
|
||||
} else {
|
||||
child = get_lt(h);
|
||||
set_lt(h, parent);
|
||||
}
|
||||
parent = h;
|
||||
h = child;
|
||||
}
|
||||
|
||||
// Climb from the path node to the root node using the linked
|
||||
// list, restoring the tree structure and rebalancing as necessary.
|
||||
bool reduced_depth = true;
|
||||
int bf;
|
||||
cmp = cmp_shortened_sub_with_path;
|
||||
for (;;) {
|
||||
if (reduced_depth) {
|
||||
bf = get_bf(h);
|
||||
if (cmp < 0)
|
||||
bf++;
|
||||
else // cmp > 0
|
||||
bf--;
|
||||
if ((bf == -2) || (bf == 2)) {
|
||||
h = balance(h);
|
||||
bf = get_bf(h);
|
||||
} else
|
||||
set_bf(h, bf);
|
||||
reduced_depth = (bf == 0);
|
||||
}
|
||||
if (parent == null())
|
||||
break;
|
||||
child = h;
|
||||
h = parent;
|
||||
cmp = branch[--depth] ? 1 : -1;
|
||||
if (cmp < 0) {
|
||||
parent = get_lt(h);
|
||||
set_lt(h, child);
|
||||
} else {
|
||||
parent = get_gt(h);
|
||||
set_gt(h, child);
|
||||
}
|
||||
}
|
||||
abs.root = h;
|
||||
}
|
||||
|
||||
return rm;
|
||||
}
|
||||
|
||||
template <class Abstractor, unsigned maxDepth, class BSet>
|
||||
inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
|
||||
AVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node)
|
||||
{
|
||||
handle h = abs.root;
|
||||
handle parent = null();
|
||||
int cmp, last_cmp;
|
||||
|
||||
/* Search for node already in tree with same key. */
|
||||
for (;;) {
|
||||
if (h == null())
|
||||
/* No node in tree with same key as new node. */
|
||||
return null();
|
||||
cmp = cmp_n_n(new_node, h);
|
||||
if (cmp == 0)
|
||||
/* Found the node to substitute new one for. */
|
||||
break;
|
||||
last_cmp = cmp;
|
||||
parent = h;
|
||||
h = cmp < 0 ? get_lt(h) : get_gt(h);
|
||||
}
|
||||
|
||||
/* Copy tree housekeeping fields from node in tree to new node. */
|
||||
set_lt(new_node, get_lt(h));
|
||||
set_gt(new_node, get_gt(h));
|
||||
set_bf(new_node, get_bf(h));
|
||||
|
||||
if (parent == null())
|
||||
/* New node is also new root. */
|
||||
abs.root = new_node;
|
||||
else {
|
||||
/* Make parent point to new node. */
|
||||
if (last_cmp < 0)
|
||||
set_lt(parent, new_node);
|
||||
else
|
||||
set_gt(parent, new_node);
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WTF_Alignment_h
|
||||
#define WTF_Alignment_h
|
||||
|
||||
#include "Platform.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
#if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(GCCE) || (COMPILER(SUNCC) && __SUNPRO_CC > 0x590)
|
||||
#define WTF_ALIGN_OF(type) __alignof__(type)
|
||||
#define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n)))
|
||||
#elif COMPILER(MSVC)
|
||||
#define WTF_ALIGN_OF(type) __alignof(type)
|
||||
#define WTF_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable
|
||||
#else
|
||||
#error WTF_ALIGN macros need alignment control.
|
||||
#endif
|
||||
|
||||
#if COMPILER(GCC) && !COMPILER(INTEL) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
|
||||
typedef char __attribute__((__may_alias__)) AlignedBufferChar;
|
||||
#else
|
||||
typedef char AlignedBufferChar;
|
||||
#endif
|
||||
|
||||
template<size_t size, size_t alignment> struct AlignedBuffer;
|
||||
template<size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; };
|
||||
template<size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2); };
|
||||
template<size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4); };
|
||||
template<size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8); };
|
||||
template<size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); };
|
||||
template<size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
|
||||
template<size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
|
||||
|
||||
template <size_t size, size_t alignment>
|
||||
void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
std::swap(a.buffer[i], b.buffer[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // WTF_Alignment_h
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef AllocationSpace_h
|
||||
#define AllocationSpace_h
|
||||
|
||||
#include "MarkedBlockSet.h"
|
||||
#include "MarkedSpace.h"
|
||||
|
||||
#include <wtf/HashSet.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class Heap;
|
||||
class MarkedBlock;
|
||||
|
||||
class AllocationSpace {
|
||||
public:
|
||||
AllocationSpace(Heap* heap)
|
||||
: m_heap(heap)
|
||||
, m_markedSpace(heap)
|
||||
{
|
||||
}
|
||||
|
||||
typedef HashSet<MarkedBlock*>::iterator BlockIterator;
|
||||
|
||||
MarkedBlockSet& blocks() { return m_blocks; }
|
||||
MarkedSpace::SizeClass& sizeClassFor(size_t bytes) { return m_markedSpace.sizeClassFor(bytes); }
|
||||
size_t waterMark() { return m_markedSpace.waterMark(); }
|
||||
|
||||
#if ENABLE(GGC)
|
||||
void gatherDirtyCells(MarkedBlock::DirtyCellVector&);
|
||||
#endif
|
||||
|
||||
template<typename Functor> typename Functor::ReturnType forEachCell(Functor&);
|
||||
template<typename Functor> typename Functor::ReturnType forEachCell();
|
||||
template<typename Functor> typename Functor::ReturnType forEachBlock(Functor&);
|
||||
template<typename Functor> typename Functor::ReturnType forEachBlock();
|
||||
|
||||
void canonicalizeCellLivenessData() { m_markedSpace.canonicalizeCellLivenessData(); }
|
||||
void resetAllocator() { m_markedSpace.resetAllocator(); }
|
||||
|
||||
void* allocate(size_t);
|
||||
void freeBlocks(MarkedBlock*);
|
||||
void shrink();
|
||||
|
||||
private:
|
||||
enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
|
||||
|
||||
void* allocate(MarkedSpace::SizeClass&);
|
||||
void* tryAllocate(MarkedSpace::SizeClass&);
|
||||
JS_EXPORT_PRIVATE void* allocateSlowCase(MarkedSpace::SizeClass&);
|
||||
MarkedBlock* allocateBlock(size_t cellSize, AllocationEffort);
|
||||
|
||||
Heap* m_heap;
|
||||
MarkedSpace m_markedSpace;
|
||||
MarkedBlockSet m_blocks;
|
||||
};
|
||||
|
||||
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachCell(Functor& functor)
|
||||
{
|
||||
canonicalizeCellLivenessData();
|
||||
|
||||
BlockIterator end = m_blocks.set().end();
|
||||
for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
|
||||
(*it)->forEachCell(functor);
|
||||
return functor.returnValue();
|
||||
}
|
||||
|
||||
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachCell()
|
||||
{
|
||||
Functor functor;
|
||||
return forEachCell(functor);
|
||||
}
|
||||
|
||||
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachBlock(Functor& functor)
|
||||
{
|
||||
BlockIterator end = m_blocks.set().end();
|
||||
for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
|
||||
functor(*it);
|
||||
return functor.returnValue();
|
||||
}
|
||||
|
||||
template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachBlock()
|
||||
{
|
||||
Functor functor;
|
||||
return forEachBlock(functor);
|
||||
}
|
||||
|
||||
inline void* AllocationSpace::allocate(MarkedSpace::SizeClass& sizeClass)
|
||||
{
|
||||
// This is a light-weight fast path to cover the most common case.
|
||||
MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
|
||||
if (UNLIKELY(!firstFreeCell))
|
||||
return allocateSlowCase(sizeClass);
|
||||
|
||||
sizeClass.firstFreeCell = firstFreeCell->next;
|
||||
return firstFreeCell;
|
||||
}
|
||||
|
||||
inline void* AllocationSpace::allocate(size_t bytes)
|
||||
{
|
||||
MarkedSpace::SizeClass& sizeClass = sizeClassFor(bytes);
|
||||
return allocate(sizeClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This file is no longer necessary, since all the functionality has been moved to Compiler.h. */
|
||||
|
||||
#include "Platform.h"
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ArgList_h
|
||||
#define ArgList_h
|
||||
|
||||
#include "CallFrame.h"
|
||||
#include "Register.h"
|
||||
#include "WriteBarrier.h"
|
||||
#include <wtf/HashSet.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class SlotVisitor;
|
||||
|
||||
class MarkedArgumentBuffer {
|
||||
WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
|
||||
friend class JSGlobalData;
|
||||
friend class ArgList;
|
||||
|
||||
private:
|
||||
static const size_t inlineCapacity = 8;
|
||||
typedef Vector<Register, inlineCapacity> VectorType;
|
||||
typedef HashSet<MarkedArgumentBuffer*> ListSet;
|
||||
|
||||
public:
|
||||
// Constructor for a read-write list, to which you may append values.
|
||||
// FIXME: Remove all clients of this API, then remove this API.
|
||||
MarkedArgumentBuffer()
|
||||
: m_size(0)
|
||||
, m_capacity(inlineCapacity)
|
||||
, m_buffer(&m_inlineBuffer[m_capacity - 1])
|
||||
, m_markSet(0)
|
||||
{
|
||||
}
|
||||
|
||||
~MarkedArgumentBuffer()
|
||||
{
|
||||
if (m_markSet)
|
||||
m_markSet->remove(this);
|
||||
|
||||
if (EncodedJSValue* base = mallocBase())
|
||||
delete [] base;
|
||||
}
|
||||
|
||||
size_t size() const { return m_size; }
|
||||
bool isEmpty() const { return !m_size; }
|
||||
|
||||
JSValue at(int i) const
|
||||
{
|
||||
if (i >= m_size)
|
||||
return jsUndefined();
|
||||
|
||||
return JSValue::decode(slotFor(i));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void append(JSValue v)
|
||||
{
|
||||
if (m_size >= m_capacity)
|
||||
return slowAppend(v);
|
||||
|
||||
slotFor(m_size) = JSValue::encode(v);
|
||||
++m_size;
|
||||
}
|
||||
|
||||
void removeLast()
|
||||
{
|
||||
ASSERT(m_size);
|
||||
m_size--;
|
||||
}
|
||||
|
||||
JSValue last()
|
||||
{
|
||||
ASSERT(m_size);
|
||||
return JSValue::decode(slotFor(m_size - 1));
|
||||
}
|
||||
|
||||
static void markLists(HeapRootVisitor&, ListSet&);
|
||||
|
||||
private:
|
||||
JS_EXPORT_PRIVATE void slowAppend(JSValue);
|
||||
|
||||
EncodedJSValue& slotFor(int item) const
|
||||
{
|
||||
return m_buffer[-item];
|
||||
}
|
||||
|
||||
EncodedJSValue* mallocBase()
|
||||
{
|
||||
if (m_capacity == static_cast<int>(inlineCapacity))
|
||||
return 0;
|
||||
return &slotFor(m_capacity - 1);
|
||||
}
|
||||
|
||||
int m_size;
|
||||
int m_capacity;
|
||||
EncodedJSValue m_inlineBuffer[inlineCapacity];
|
||||
EncodedJSValue* m_buffer;
|
||||
ListSet* m_markSet;
|
||||
|
||||
private:
|
||||
// Prohibits new / delete, which would break GC.
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return fastMalloc(size);
|
||||
}
|
||||
void operator delete(void* p)
|
||||
{
|
||||
fastFree(p);
|
||||
}
|
||||
|
||||
void* operator new[](size_t);
|
||||
void operator delete[](void*);
|
||||
|
||||
void* operator new(size_t, void*);
|
||||
void operator delete(void*, size_t);
|
||||
};
|
||||
|
||||
class ArgList {
|
||||
friend class JIT;
|
||||
public:
|
||||
ArgList()
|
||||
: m_args(0)
|
||||
, m_argCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
ArgList(ExecState* exec)
|
||||
: m_args(reinterpret_cast<JSValue*>(&exec[CallFrame::argumentOffset(0)]))
|
||||
, m_argCount(exec->argumentCount())
|
||||
{
|
||||
}
|
||||
|
||||
ArgList(const MarkedArgumentBuffer& args)
|
||||
: m_args(reinterpret_cast<JSValue*>(args.m_buffer))
|
||||
, m_argCount(args.size())
|
||||
{
|
||||
}
|
||||
|
||||
JSValue at(int i) const
|
||||
{
|
||||
if (i >= m_argCount)
|
||||
return jsUndefined();
|
||||
return m_args[-i];
|
||||
}
|
||||
|
||||
bool isEmpty() const { return !m_argCount; }
|
||||
size_t size() const { return m_argCount; }
|
||||
|
||||
JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const;
|
||||
|
||||
private:
|
||||
JSValue* m_args;
|
||||
int m_argCount;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // ArgList_h
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef ArrayBuffer_h
|
||||
#define ArrayBuffer_h
|
||||
|
||||
#include <wtf/HashSet.h>
|
||||
#include <wtf/PassRefPtr.h>
|
||||
#include <wtf/RefCounted.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class ArrayBuffer;
|
||||
class ArrayBufferView;
|
||||
|
||||
class ArrayBufferContents {
|
||||
WTF_MAKE_NONCOPYABLE(ArrayBufferContents);
|
||||
public:
|
||||
ArrayBufferContents()
|
||||
: m_data(0)
|
||||
, m_sizeInBytes(0)
|
||||
{ }
|
||||
|
||||
inline ~ArrayBufferContents();
|
||||
|
||||
void* data() { return m_data; }
|
||||
unsigned sizeInBytes() { return m_sizeInBytes; }
|
||||
|
||||
private:
|
||||
ArrayBufferContents(void* data, unsigned sizeInBytes)
|
||||
: m_data(data)
|
||||
, m_sizeInBytes(sizeInBytes)
|
||||
{ }
|
||||
|
||||
friend class ArrayBuffer;
|
||||
|
||||
static inline void tryAllocate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents&);
|
||||
void transfer(ArrayBufferContents& other)
|
||||
{
|
||||
ASSERT(!other.m_data);
|
||||
other.m_data = m_data;
|
||||
other.m_sizeInBytes = m_sizeInBytes;
|
||||
m_data = 0;
|
||||
m_sizeInBytes = 0;
|
||||
}
|
||||
|
||||
void* m_data;
|
||||
unsigned m_sizeInBytes;
|
||||
};
|
||||
|
||||
class ArrayBuffer : public RefCounted<ArrayBuffer> {
|
||||
public:
|
||||
static inline PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned elementByteSize);
|
||||
static inline PassRefPtr<ArrayBuffer> create(ArrayBuffer*);
|
||||
static inline PassRefPtr<ArrayBuffer> create(const void* source, unsigned byteLength);
|
||||
static inline PassRefPtr<ArrayBuffer> create(ArrayBufferContents&);
|
||||
|
||||
inline void* data();
|
||||
inline const void* data() const;
|
||||
inline unsigned byteLength() const;
|
||||
|
||||
inline PassRefPtr<ArrayBuffer> slice(int begin, int end) const;
|
||||
inline PassRefPtr<ArrayBuffer> slice(int begin) const;
|
||||
|
||||
void addView(ArrayBufferView*);
|
||||
void removeView(ArrayBufferView*);
|
||||
|
||||
bool transfer(ArrayBufferContents&, Vector<RefPtr<ArrayBufferView> >& neuteredViews);
|
||||
bool isNeutered() { return !m_contents.m_data; }
|
||||
|
||||
~ArrayBuffer() { }
|
||||
|
||||
private:
|
||||
inline ArrayBuffer(ArrayBufferContents&);
|
||||
inline PassRefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const;
|
||||
inline unsigned clampIndex(int index) const;
|
||||
static inline int clampValue(int x, int left, int right);
|
||||
|
||||
ArrayBufferContents m_contents;
|
||||
ArrayBufferView* m_firstView;
|
||||
};
|
||||
|
||||
int ArrayBuffer::clampValue(int x, int left, int right)
|
||||
{
|
||||
ASSERT(left <= right);
|
||||
if (x < left)
|
||||
x = left;
|
||||
if (right < x)
|
||||
x = right;
|
||||
return x;
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned elementByteSize)
|
||||
{
|
||||
ArrayBufferContents contents;
|
||||
ArrayBufferContents::tryAllocate(numElements, elementByteSize, contents);
|
||||
if (!contents.m_data)
|
||||
return 0;
|
||||
return adoptRef(new ArrayBuffer(contents));
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBuffer* other)
|
||||
{
|
||||
return ArrayBuffer::create(other->data(), other->byteLength());
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::create(const void* source, unsigned byteLength)
|
||||
{
|
||||
ArrayBufferContents contents;
|
||||
ArrayBufferContents::tryAllocate(byteLength, 1, contents);
|
||||
if (!contents.m_data)
|
||||
return 0;
|
||||
RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents));
|
||||
memcpy(buffer->data(), source, byteLength);
|
||||
return buffer.release();
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBufferContents& contents)
|
||||
{
|
||||
return adoptRef(new ArrayBuffer(contents));
|
||||
}
|
||||
|
||||
ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents)
|
||||
: m_firstView(0)
|
||||
{
|
||||
contents.transfer(m_contents);
|
||||
}
|
||||
|
||||
void* ArrayBuffer::data()
|
||||
{
|
||||
return m_contents.m_data;
|
||||
}
|
||||
|
||||
const void* ArrayBuffer::data() const
|
||||
{
|
||||
return m_contents.m_data;
|
||||
}
|
||||
|
||||
unsigned ArrayBuffer::byteLength() const
|
||||
{
|
||||
return m_contents.m_sizeInBytes;
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin, int end) const
|
||||
{
|
||||
return sliceImpl(clampIndex(begin), clampIndex(end));
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin) const
|
||||
{
|
||||
return sliceImpl(clampIndex(begin), byteLength());
|
||||
}
|
||||
|
||||
PassRefPtr<ArrayBuffer> ArrayBuffer::sliceImpl(unsigned begin, unsigned end) const
|
||||
{
|
||||
unsigned size = begin <= end ? end - begin : 0;
|
||||
return ArrayBuffer::create(static_cast<const char*>(data()) + begin, size);
|
||||
}
|
||||
|
||||
unsigned ArrayBuffer::clampIndex(int index) const
|
||||
{
|
||||
unsigned currentLength = byteLength();
|
||||
if (index < 0)
|
||||
index = currentLength + index;
|
||||
return clampValue(index, 0, currentLength);
|
||||
}
|
||||
|
||||
void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents& result)
|
||||
{
|
||||
// Do not allow 32-bit overflow of the total size.
|
||||
// FIXME: Why not? The tryFastCalloc function already checks its arguments,
|
||||
// and will fail if there is any overflow, so why should we include a
|
||||
// redudant unnecessarily restrictive check here?
|
||||
if (numElements) {
|
||||
unsigned totalSize = numElements * elementByteSize;
|
||||
if (totalSize / numElements != elementByteSize) {
|
||||
result.m_data = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (WTF::tryFastCalloc(numElements, elementByteSize).getValue(result.m_data)) {
|
||||
result.m_sizeInBytes = numElements * elementByteSize;
|
||||
return;
|
||||
}
|
||||
result.m_data = 0;
|
||||
}
|
||||
|
||||
ArrayBufferContents::~ArrayBufferContents()
|
||||
{
|
||||
WTF::fastFree(m_data);
|
||||
}
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::ArrayBuffer;
|
||||
|
||||
#endif // ArrayBuffer_h
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef ArrayBufferView_h
|
||||
#define ArrayBufferView_h
|
||||
|
||||
#include "ArrayBuffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
#include <wtf/PassRefPtr.h>
|
||||
#include <wtf/RefCounted.h>
|
||||
#include <wtf/RefPtr.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class ArrayBufferView : public RefCounted<ArrayBufferView> {
|
||||
public:
|
||||
virtual bool isByteArray() const { return false; }
|
||||
virtual bool isUnsignedByteArray() const { return false; }
|
||||
virtual bool isUnsignedByteClampedArray() const { return false; }
|
||||
virtual bool isShortArray() const { return false; }
|
||||
virtual bool isUnsignedShortArray() const { return false; }
|
||||
virtual bool isIntArray() const { return false; }
|
||||
virtual bool isUnsignedIntArray() const { return false; }
|
||||
virtual bool isFloatArray() const { return false; }
|
||||
virtual bool isDoubleArray() const { return false; }
|
||||
virtual bool isDataView() const { return false; }
|
||||
|
||||
PassRefPtr<ArrayBuffer> buffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
void* baseAddress() const
|
||||
{
|
||||
return m_baseAddress;
|
||||
}
|
||||
|
||||
unsigned byteOffset() const
|
||||
{
|
||||
return m_byteOffset;
|
||||
}
|
||||
|
||||
virtual unsigned byteLength() const = 0;
|
||||
|
||||
WTF_EXPORT_PRIVATE virtual ~ArrayBufferView();
|
||||
|
||||
protected:
|
||||
WTF_EXPORT_PRIVATE ArrayBufferView(PassRefPtr<ArrayBuffer>, unsigned byteOffset);
|
||||
|
||||
inline bool setImpl(ArrayBufferView*, unsigned byteOffset);
|
||||
|
||||
inline bool setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset);
|
||||
|
||||
inline bool zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength);
|
||||
|
||||
static inline void calculateOffsetAndLength(int start, int end, unsigned arraySize,
|
||||
unsigned* offset, unsigned* length);
|
||||
|
||||
// Helper to verify that a given sub-range of an ArrayBuffer is
|
||||
// within range.
|
||||
template <typename T>
|
||||
static bool verifySubRange(PassRefPtr<ArrayBuffer> buffer,
|
||||
unsigned byteOffset,
|
||||
unsigned numElements)
|
||||
{
|
||||
if (!buffer)
|
||||
return false;
|
||||
if (sizeof(T) > 1 && byteOffset % sizeof(T))
|
||||
return false;
|
||||
if (byteOffset > buffer->byteLength())
|
||||
return false;
|
||||
unsigned remainingElements = (buffer->byteLength() - byteOffset) / sizeof(T);
|
||||
if (numElements > remainingElements)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Input offset is in number of elements from this array's view;
|
||||
// output offset is in number of bytes from the underlying buffer's view.
|
||||
template <typename T>
|
||||
static void clampOffsetAndNumElements(PassRefPtr<ArrayBuffer> buffer,
|
||||
unsigned arrayByteOffset,
|
||||
unsigned *offset,
|
||||
unsigned *numElements)
|
||||
{
|
||||
unsigned maxOffset = (UINT_MAX - arrayByteOffset) / sizeof(T);
|
||||
if (*offset > maxOffset) {
|
||||
*offset = buffer->byteLength();
|
||||
*numElements = 0;
|
||||
return;
|
||||
}
|
||||
*offset = arrayByteOffset + *offset * sizeof(T);
|
||||
*offset = std::min(buffer->byteLength(), *offset);
|
||||
unsigned remainingElements = (buffer->byteLength() - *offset) / sizeof(T);
|
||||
*numElements = std::min(remainingElements, *numElements);
|
||||
}
|
||||
|
||||
WTF_EXPORT_PRIVATE virtual void neuter();
|
||||
|
||||
// This is the address of the ArrayBuffer's storage, plus the byte offset.
|
||||
void* m_baseAddress;
|
||||
|
||||
unsigned m_byteOffset;
|
||||
|
||||
private:
|
||||
friend class ArrayBuffer;
|
||||
RefPtr<ArrayBuffer> m_buffer;
|
||||
ArrayBufferView* m_prevView;
|
||||
ArrayBufferView* m_nextView;
|
||||
};
|
||||
|
||||
bool ArrayBufferView::setImpl(ArrayBufferView* array, unsigned byteOffset)
|
||||
{
|
||||
if (byteOffset > byteLength()
|
||||
|| byteOffset + array->byteLength() > byteLength()
|
||||
|| byteOffset + array->byteLength() < byteOffset) {
|
||||
// Out of range offset or overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
char* base = static_cast<char*>(baseAddress());
|
||||
memmove(base + byteOffset, array->baseAddress(), array->byteLength());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArrayBufferView::setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset)
|
||||
{
|
||||
if (byteOffset > byteLength()
|
||||
|| byteOffset + dataByteLength > byteLength()
|
||||
|| byteOffset + dataByteLength < byteOffset) {
|
||||
// Out of range offset or overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
char* base = static_cast<char*>(baseAddress());
|
||||
memmove(base + byteOffset, data, dataByteLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArrayBufferView::zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength)
|
||||
{
|
||||
if (byteOffset > byteLength()
|
||||
|| byteOffset + rangeByteLength > byteLength()
|
||||
|| byteOffset + rangeByteLength < byteOffset) {
|
||||
// Out of range offset or overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
char* base = static_cast<char*>(baseAddress());
|
||||
memset(base + byteOffset, 0, rangeByteLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArrayBufferView::calculateOffsetAndLength(int start, int end, unsigned arraySize,
|
||||
unsigned* offset, unsigned* length)
|
||||
{
|
||||
if (start < 0)
|
||||
start += arraySize;
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end += arraySize;
|
||||
if (end < 0)
|
||||
end = 0;
|
||||
if (end < start)
|
||||
end = start;
|
||||
*offset = static_cast<unsigned>(start);
|
||||
*length = static_cast<unsigned>(end - start);
|
||||
}
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::ArrayBufferView;
|
||||
|
||||
#endif // ArrayBufferView_h
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2007, 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ArrayPrototype_h
|
||||
#define ArrayPrototype_h
|
||||
|
||||
#include "JSArray.h"
|
||||
#include "Lookup.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ArrayPrototype : public JSArray {
|
||||
private:
|
||||
ArrayPrototype(JSGlobalObject*, Structure*);
|
||||
|
||||
public:
|
||||
typedef JSArray Base;
|
||||
|
||||
static ArrayPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
|
||||
{
|
||||
ArrayPrototype* prototype = new (NotNull, allocateCell<ArrayPrototype>(*exec->heap())) ArrayPrototype(globalObject, structure);
|
||||
prototype->finishCreation(globalObject);
|
||||
return prototype;
|
||||
}
|
||||
|
||||
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
|
||||
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
|
||||
|
||||
static const ClassInfo s_info;
|
||||
|
||||
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
|
||||
{
|
||||
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
|
||||
}
|
||||
|
||||
protected:
|
||||
void finishCreation(JSGlobalObject*);
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // ArrayPrototype_h
|
||||
@@ -1,398 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003, 2006, 2007 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_Assertions_h
|
||||
#define WTF_Assertions_h
|
||||
|
||||
/*
|
||||
no namespaces because this file has to be includable from C and Objective-C
|
||||
|
||||
Note, this file uses many GCC extensions, but it should be compatible with
|
||||
C, Objective C, C++, and Objective C++.
|
||||
|
||||
For non-debug builds, everything is disabled by default.
|
||||
Defining any of the symbols explicitly prevents this from having any effect.
|
||||
|
||||
MSVC7 note: variadic macro support was added in MSVC8, so for now we disable
|
||||
those macros in MSVC7. For more info, see the MSDN document on variadic
|
||||
macros here:
|
||||
|
||||
http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
|
||||
*/
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if !COMPILER(MSVC)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
/* Disable ASSERT* macros in release mode. */
|
||||
#define ASSERTIONS_DISABLED_DEFAULT 1
|
||||
#else
|
||||
#define ASSERTIONS_DISABLED_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define HAVE_VARIADIC_MACRO 0
|
||||
#else
|
||||
#define HAVE_VARIADIC_MACRO 1
|
||||
#endif
|
||||
|
||||
#ifndef BACKTRACE_DISABLED
|
||||
#define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef ASSERT_DISABLED
|
||||
#define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef ASSERT_MSG_DISABLED
|
||||
#if HAVE(VARIADIC_MACRO)
|
||||
#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#else
|
||||
#define ASSERT_MSG_DISABLED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ASSERT_ARG_DISABLED
|
||||
#define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef FATAL_DISABLED
|
||||
#if HAVE(VARIADIC_MACRO)
|
||||
#define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#else
|
||||
#define FATAL_DISABLED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ERROR_DISABLED
|
||||
#if HAVE(VARIADIC_MACRO)
|
||||
#define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#else
|
||||
#define ERROR_DISABLED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LOG_DISABLED
|
||||
#if HAVE(VARIADIC_MACRO)
|
||||
#define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
|
||||
#else
|
||||
#define LOG_DISABLED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if COMPILER(GCC)
|
||||
#define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
|
||||
#else
|
||||
#define WTF_PRETTY_FUNCTION __FUNCTION__
|
||||
#endif
|
||||
|
||||
/* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
|
||||
emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include
|
||||
the attribute when being used from Objective-C code in case it decides to use %@. */
|
||||
#if COMPILER(GCC) && !defined(__OBJC__)
|
||||
#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
|
||||
#else
|
||||
#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
|
||||
#endif
|
||||
|
||||
/* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
|
||||
|
||||
typedef struct {
|
||||
unsigned mask;
|
||||
const char *defaultName;
|
||||
WTFLogChannelState state;
|
||||
} WTFLogChannel;
|
||||
|
||||
WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
|
||||
WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
|
||||
WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
|
||||
WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
|
||||
WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
|
||||
WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
|
||||
WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
|
||||
|
||||
WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
|
||||
WTF_EXPORT_PRIVATE void WTFReportBacktrace();
|
||||
|
||||
typedef void (*WTFCrashHookFunction)();
|
||||
WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
|
||||
WTF_EXPORT_PRIVATE void WTFInvokeCrashHook();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
|
||||
|
||||
Use CRASH() in response to known, unrecoverable errors like out-of-memory.
|
||||
Macro is enabled in both debug and release mode.
|
||||
To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
|
||||
|
||||
Signals are ignored by the crash reporter on OS X so we must do better.
|
||||
*/
|
||||
#ifndef CRASH
|
||||
#if COMPILER(CLANG)
|
||||
#define CRASH() do { \
|
||||
WTFReportBacktrace(); \
|
||||
WTFInvokeCrashHook(); \
|
||||
*(int *)(uintptr_t)0xbbadbeef = 0; \
|
||||
__builtin_trap(); \
|
||||
} while (false)
|
||||
#else
|
||||
#define CRASH() do { \
|
||||
WTFReportBacktrace(); \
|
||||
WTFInvokeCrashHook(); \
|
||||
*(int *)(uintptr_t)0xbbadbeef = 0; \
|
||||
((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
|
||||
} while (false)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if COMPILER(CLANG)
|
||||
#define NO_RETURN_DUE_TO_CRASH NO_RETURN
|
||||
#else
|
||||
#define NO_RETURN_DUE_TO_CRASH
|
||||
#endif
|
||||
|
||||
|
||||
/* BACKTRACE
|
||||
|
||||
Print a backtrace to the same location as ASSERT messages.
|
||||
*/
|
||||
|
||||
#if BACKTRACE_DISABLED
|
||||
|
||||
#define BACKTRACE() ((void)0)
|
||||
|
||||
#else
|
||||
|
||||
#define BACKTRACE() do { \
|
||||
WTFReportBacktrace(); \
|
||||
} while(false)
|
||||
|
||||
#endif
|
||||
|
||||
/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
|
||||
|
||||
These macros are compiled out of release builds.
|
||||
Expressions inside them are evaluated in debug builds only.
|
||||
*/
|
||||
|
||||
#if OS(WINCE) && !PLATFORM(TORCHMOBILE)
|
||||
/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
|
||||
#include <windows.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
#if OS(WINDOWS)
|
||||
/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
|
||||
#undef ASSERT
|
||||
#endif
|
||||
|
||||
#if ASSERT_DISABLED
|
||||
|
||||
#define ASSERT(assertion) ((void)0)
|
||||
#define ASSERT_AT(assertion, file, line, function) ((void)0)
|
||||
#define ASSERT_NOT_REACHED() ((void)0)
|
||||
#define NO_RETURN_DUE_TO_ASSERT
|
||||
|
||||
#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
|
||||
template<typename T>
|
||||
inline void assertUnused(T& x) { (void)x; }
|
||||
#define ASSERT_UNUSED(variable, assertion) (assertUnused(variable))
|
||||
#else
|
||||
#define ASSERT_UNUSED(variable, assertion) ((void)variable)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define ASSERT(assertion) do \
|
||||
if (!(assertion)) { \
|
||||
WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
|
||||
CRASH(); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASSERT_AT(assertion, file, line, function) do \
|
||||
if (!(assertion)) { \
|
||||
WTFReportAssertionFailure(file, line, function, #assertion); \
|
||||
CRASH(); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASSERT_NOT_REACHED() do { \
|
||||
WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
|
||||
CRASH(); \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
|
||||
|
||||
#define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
|
||||
|
||||
#endif
|
||||
|
||||
/* ASSERT_WITH_MESSAGE */
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
|
||||
#elif ASSERT_MSG_DISABLED
|
||||
#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
|
||||
#else
|
||||
#define ASSERT_WITH_MESSAGE(assertion, ...) do \
|
||||
if (!(assertion)) { \
|
||||
WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
|
||||
CRASH(); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* ASSERT_WITH_MESSAGE_UNUSED */
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion) ((void)0)
|
||||
#elif ASSERT_MSG_DISABLED
|
||||
#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
|
||||
template<typename T>
|
||||
inline void assertWithMessageUnused(T& x) { (void)x; }
|
||||
#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) (assertWithMessageUnused(variable))
|
||||
#else
|
||||
#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
|
||||
#endif
|
||||
#else
|
||||
#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
|
||||
if (!(assertion)) { \
|
||||
WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
|
||||
CRASH(); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/* ASSERT_ARG */
|
||||
|
||||
#if ASSERT_ARG_DISABLED
|
||||
|
||||
#define ASSERT_ARG(argName, assertion) ((void)0)
|
||||
|
||||
#else
|
||||
|
||||
#define ASSERT_ARG(argName, assertion) do \
|
||||
if (!(assertion)) { \
|
||||
WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
|
||||
CRASH(); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* COMPILE_ASSERT */
|
||||
#ifndef COMPILE_ASSERT
|
||||
#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
|
||||
#endif
|
||||
|
||||
/* FATAL */
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define FATAL() ((void)0)
|
||||
#elif FATAL_DISABLED
|
||||
#define FATAL(...) ((void)0)
|
||||
#else
|
||||
#define FATAL(...) do { \
|
||||
WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
|
||||
CRASH(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* LOG_ERROR */
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define LOG_ERROR() ((void)0)
|
||||
#elif ERROR_DISABLED
|
||||
#define LOG_ERROR(...) ((void)0)
|
||||
#else
|
||||
#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/* LOG */
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define LOG() ((void)0)
|
||||
#elif LOG_DISABLED
|
||||
#define LOG(channel, ...) ((void)0)
|
||||
#else
|
||||
#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
|
||||
#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
|
||||
#define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
|
||||
#endif
|
||||
|
||||
/* LOG_VERBOSE */
|
||||
|
||||
#if COMPILER(MSVC7_OR_LOWER)
|
||||
#define LOG_VERBOSE(channel) ((void)0)
|
||||
#elif LOG_DISABLED
|
||||
#define LOG_VERBOSE(channel, ...) ((void)0)
|
||||
#else
|
||||
#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if ENABLE(GC_VALIDATION)
|
||||
#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { \
|
||||
if (!(cell))\
|
||||
CRASH();\
|
||||
if (cell->unvalidatedStructure()->unvalidatedStructure() != cell->unvalidatedStructure()->unvalidatedStructure()->unvalidatedStructure())\
|
||||
CRASH();\
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do {\
|
||||
ASSERT_GC_OBJECT_LOOKS_VALID(object); \
|
||||
if (!object->inherits(classInfo)) \
|
||||
CRASH();\
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { (void)cell; } while (0)
|
||||
#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do { (void)object; (void)classInfo; } while (0)
|
||||
#endif
|
||||
|
||||
#if COMPILER(CLANG)
|
||||
#define ASSERT_HAS_TRIVIAL_DESTRUCTOR(klass) COMPILE_ASSERT(__has_trivial_destructor(klass), klass##_has_trivial_destructor_check)
|
||||
#else
|
||||
#define ASSERT_HAS_TRIVIAL_DESTRUCTOR(klass)
|
||||
#endif
|
||||
|
||||
#endif /* WTF_Assertions_h */
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AtomicString_h
|
||||
#define AtomicString_h
|
||||
|
||||
#include "AtomicStringImpl.h"
|
||||
#include "WTFString.h"
|
||||
|
||||
// Define 'NO_IMPLICIT_ATOMICSTRING' before including this header,
|
||||
// to disallow (expensive) implicit String-->AtomicString conversions.
|
||||
#ifdef NO_IMPLICIT_ATOMICSTRING
|
||||
#define ATOMICSTRING_CONVERSION explicit
|
||||
#else
|
||||
#define ATOMICSTRING_CONVERSION
|
||||
#endif
|
||||
|
||||
namespace WTF {
|
||||
|
||||
struct AtomicStringHash;
|
||||
|
||||
class AtomicString {
|
||||
public:
|
||||
WTF_EXPORT_PRIVATE static void init();
|
||||
|
||||
AtomicString() { }
|
||||
AtomicString(const LChar* s) : m_string(add(s)) { }
|
||||
AtomicString(const char* s) : m_string(add(s)) { }
|
||||
AtomicString(const UChar* s, unsigned length) : m_string(add(s, length)) { }
|
||||
AtomicString(const UChar* s, unsigned length, unsigned existingHash) : m_string(add(s, length, existingHash)) { }
|
||||
AtomicString(const UChar* s) : m_string(add(s)) { }
|
||||
ATOMICSTRING_CONVERSION AtomicString(StringImpl* imp) : m_string(add(imp)) { }
|
||||
AtomicString(AtomicStringImpl* imp) : m_string(imp) { }
|
||||
ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { }
|
||||
AtomicString(StringImpl* baseString, unsigned start, unsigned length) : m_string(add(baseString, start, length)) { }
|
||||
|
||||
// Hash table deleted values, which are only constructed and never copied or destroyed.
|
||||
AtomicString(WTF::HashTableDeletedValueType) : m_string(WTF::HashTableDeletedValue) { }
|
||||
bool isHashTableDeletedValue() const { return m_string.isHashTableDeletedValue(); }
|
||||
|
||||
WTF_EXPORT_PRIVATE static AtomicStringImpl* find(const UChar* s, unsigned length, unsigned existingHash);
|
||||
|
||||
operator const String&() const { return m_string; }
|
||||
const String& string() const { return m_string; };
|
||||
|
||||
AtomicStringImpl* impl() const { return static_cast<AtomicStringImpl *>(m_string.impl()); }
|
||||
|
||||
const UChar* characters() const { return m_string.characters(); }
|
||||
unsigned length() const { return m_string.length(); }
|
||||
|
||||
UChar operator[](unsigned int i) const { return m_string[i]; }
|
||||
|
||||
bool contains(UChar c) const { return m_string.contains(c); }
|
||||
bool contains(const LChar* s, bool caseSensitive = true) const
|
||||
{ return m_string.contains(s, caseSensitive); }
|
||||
bool contains(const String& s, bool caseSensitive = true) const
|
||||
{ return m_string.contains(s, caseSensitive); }
|
||||
|
||||
size_t find(UChar c, size_t start = 0) const { return m_string.find(c, start); }
|
||||
size_t find(const LChar* s, size_t start = 0, bool caseSentitive = true) const
|
||||
{ return m_string.find(s, start, caseSentitive); }
|
||||
size_t find(const String& s, size_t start = 0, bool caseSentitive = true) const
|
||||
{ return m_string.find(s, start, caseSentitive); }
|
||||
|
||||
bool startsWith(const String& s, bool caseSensitive = true) const
|
||||
{ return m_string.startsWith(s, caseSensitive); }
|
||||
bool endsWith(const String& s, bool caseSensitive = true) const
|
||||
{ return m_string.endsWith(s, caseSensitive); }
|
||||
|
||||
WTF_EXPORT_PRIVATE AtomicString lower() const;
|
||||
AtomicString upper() const { return AtomicString(impl()->upper()); }
|
||||
|
||||
int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
|
||||
double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
|
||||
float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); }
|
||||
bool percentage(int& p) const { return m_string.percentage(p); }
|
||||
|
||||
bool isNull() const { return m_string.isNull(); }
|
||||
bool isEmpty() const { return m_string.isEmpty(); }
|
||||
|
||||
static void remove(StringImpl*);
|
||||
|
||||
#if USE(CF)
|
||||
AtomicString(CFStringRef s) : m_string(add(String(s).impl())) { }
|
||||
CFStringRef createCFString() const { return m_string.createCFString(); }
|
||||
#endif
|
||||
#ifdef __OBJC__
|
||||
AtomicString(NSString* s) : m_string(add(String(s).impl())) { }
|
||||
operator NSString*() const { return m_string; }
|
||||
#endif
|
||||
#if PLATFORM(QT)
|
||||
AtomicString(const QString& s) : m_string(add(String(s).impl())) { }
|
||||
operator QString() const { return m_string; }
|
||||
#endif
|
||||
|
||||
// AtomicString::fromUTF8 will return a null string if
|
||||
// the input data contains invalid UTF-8 sequences.
|
||||
static AtomicString fromUTF8(const char*, size_t);
|
||||
static AtomicString fromUTF8(const char*);
|
||||
|
||||
#ifndef NDEBUG
|
||||
void show() const;
|
||||
#endif
|
||||
private:
|
||||
String m_string;
|
||||
|
||||
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(const LChar*);
|
||||
ALWAYS_INLINE static PassRefPtr<StringImpl> add(const char* s) { return add(reinterpret_cast<const LChar*>(s)); };
|
||||
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(const UChar*, unsigned length);
|
||||
ALWAYS_INLINE static PassRefPtr<StringImpl> add(const char* s, unsigned length) { return add(reinterpret_cast<const char*>(s), length); };
|
||||
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(const UChar*, unsigned length, unsigned existingHash);
|
||||
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(const UChar*);
|
||||
static PassRefPtr<StringImpl> add(StringImpl*, unsigned offset, unsigned length);
|
||||
ALWAYS_INLINE static PassRefPtr<StringImpl> add(StringImpl* r)
|
||||
{
|
||||
if (!r || r->isAtomic())
|
||||
return r;
|
||||
return addSlowCase(r);
|
||||
}
|
||||
WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(StringImpl*);
|
||||
WTF_EXPORT_PRIVATE static AtomicString fromUTF8Internal(const char*, const char*);
|
||||
};
|
||||
|
||||
inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); }
|
||||
bool operator==(const AtomicString&, const LChar*);
|
||||
inline bool operator==(const AtomicString& a, const char* b) { return WTF::equal(a.impl(), reinterpret_cast<const LChar*>(b)); }
|
||||
inline bool operator==(const AtomicString& a, const Vector<UChar>& b) { return a.impl() && equal(a.impl(), b.data(), b.size()); }
|
||||
inline bool operator==(const AtomicString& a, const String& b) { return equal(a.impl(), b.impl()); }
|
||||
inline bool operator==(const LChar* a, const AtomicString& b) { return b == a; }
|
||||
inline bool operator==(const String& a, const AtomicString& b) { return equal(a.impl(), b.impl()); }
|
||||
inline bool operator==(const Vector<UChar>& a, const AtomicString& b) { return b == a; }
|
||||
|
||||
inline bool operator!=(const AtomicString& a, const AtomicString& b) { return a.impl() != b.impl(); }
|
||||
inline bool operator!=(const AtomicString& a, const LChar* b) { return !(a == b); }
|
||||
inline bool operator!=(const AtomicString& a, const char* b) { return !(a == b); }
|
||||
inline bool operator!=(const AtomicString& a, const String& b) { return !equal(a.impl(), b.impl()); }
|
||||
inline bool operator!=(const AtomicString& a, const Vector<UChar>& b) { return !(a == b); }
|
||||
inline bool operator!=(const LChar* a, const AtomicString& b) { return !(b == a); }
|
||||
inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); }
|
||||
inline bool operator!=(const Vector<UChar>& a, const AtomicString& b) { return !(a == b); }
|
||||
|
||||
inline bool equalIgnoringCase(const AtomicString& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); }
|
||||
inline bool equalIgnoringCase(const AtomicString& a, const LChar* b) { return equalIgnoringCase(a.impl(), b); }
|
||||
inline bool equalIgnoringCase(const AtomicString& a, const char* b) { return equalIgnoringCase(a.impl(), reinterpret_cast<const LChar*>(b)); }
|
||||
inline bool equalIgnoringCase(const AtomicString& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); }
|
||||
inline bool equalIgnoringCase(const LChar* a, const AtomicString& b) { return equalIgnoringCase(a, b.impl()); }
|
||||
inline bool equalIgnoringCase(const char* a, const AtomicString& b) { return equalIgnoringCase(reinterpret_cast<const LChar*>(a), b.impl()); }
|
||||
inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); }
|
||||
|
||||
// Define external global variables for the commonly used atomic strings.
|
||||
// These are only usable from the main thread.
|
||||
#ifndef ATOMICSTRING_HIDE_GLOBALS
|
||||
extern const WTF_EXPORTDATA AtomicString nullAtom;
|
||||
extern const WTF_EXPORTDATA AtomicString emptyAtom;
|
||||
extern const WTF_EXPORTDATA AtomicString textAtom;
|
||||
extern const WTF_EXPORTDATA AtomicString commentAtom;
|
||||
extern const WTF_EXPORTDATA AtomicString starAtom;
|
||||
extern const WTF_EXPORTDATA AtomicString xmlAtom;
|
||||
extern const WTF_EXPORTDATA AtomicString xmlnsAtom;
|
||||
|
||||
inline AtomicString AtomicString::fromUTF8(const char* characters, size_t length)
|
||||
{
|
||||
if (!characters)
|
||||
return nullAtom;
|
||||
if (!length)
|
||||
return emptyAtom;
|
||||
return fromUTF8Internal(characters, characters + length);
|
||||
}
|
||||
|
||||
inline AtomicString AtomicString::fromUTF8(const char* characters)
|
||||
{
|
||||
if (!characters)
|
||||
return nullAtom;
|
||||
if (!*characters)
|
||||
return emptyAtom;
|
||||
return fromUTF8Internal(characters, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// AtomicStringHash is the default hash for AtomicString
|
||||
template<typename T> struct DefaultHash;
|
||||
template<> struct DefaultHash<AtomicString> {
|
||||
typedef AtomicStringHash Hash;
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
#ifndef ATOMICSTRING_HIDE_GLOBALS
|
||||
using WTF::AtomicString;
|
||||
using WTF::nullAtom;
|
||||
using WTF::emptyAtom;
|
||||
using WTF::textAtom;
|
||||
using WTF::commentAtom;
|
||||
using WTF::starAtom;
|
||||
using WTF::xmlAtom;
|
||||
using WTF::xmlnsAtom;
|
||||
#endif
|
||||
|
||||
#include "StringConcatenate.h"
|
||||
#endif // AtomicString_h
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef AtomicStringHash_h
|
||||
#define AtomicStringHash_h
|
||||
|
||||
#include <wtf/text/AtomicString.h>
|
||||
#include <wtf/HashTraits.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
struct AtomicStringHash {
|
||||
static unsigned hash(const AtomicString& key)
|
||||
{
|
||||
return key.impl()->existingHash();
|
||||
}
|
||||
|
||||
static bool equal(const AtomicString& a, const AtomicString& b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static const bool safeToCompareToEmptyOrDeleted = false;
|
||||
};
|
||||
|
||||
// AtomicStringHash is the default hash for AtomicString
|
||||
template<> struct HashTraits<WTF::AtomicString> : GenericHashTraits<WTF::AtomicString> {
|
||||
static const bool emptyValueIsZero = true;
|
||||
static void constructDeletedValue(WTF::AtomicString& slot) { new (NotNull, &slot) WTF::AtomicString(HashTableDeletedValue); }
|
||||
static bool isDeletedValue(const WTF::AtomicString& slot) { return slot.isHashTableDeletedValue(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using WTF::AtomicStringHash;
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AtomicStringImpl_h
|
||||
#define AtomicStringImpl_h
|
||||
|
||||
#include "StringImpl.h"
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class AtomicStringImpl : public StringImpl
|
||||
{
|
||||
public:
|
||||
AtomicStringImpl() : StringImpl(0) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using WTF::AtomicStringImpl;
|
||||
|
||||
#endif
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*
|
||||
*
|
||||
* Note: The implementations of InterlockedIncrement and InterlockedDecrement are based
|
||||
* on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license
|
||||
* is virtually identical to the Apple license above but is included here for completeness.
|
||||
*
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer,
|
||||
* must be included in all copies of the Software, in whole or in part, and
|
||||
* all derivative works of the Software, unless such copies or derivative
|
||||
* works are solely in the form of machine-executable object code generated by
|
||||
* a source language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef Atomics_h
|
||||
#define Atomics_h
|
||||
|
||||
#include "Platform.h"
|
||||
#include "StdLibExtras.h"
|
||||
#include "UnusedParam.h"
|
||||
|
||||
#if OS(WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif OS(DARWIN)
|
||||
#include <libkern/OSAtomic.h>
|
||||
#elif OS(QNX)
|
||||
#include <atomic.h>
|
||||
#elif OS(ANDROID)
|
||||
#include <sys/atomics.h>
|
||||
#elif COMPILER(GCC)
|
||||
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
|
||||
#include <ext/atomicity.h>
|
||||
#else
|
||||
#include <bits/atomicity.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace WTF {
|
||||
|
||||
#if OS(WINDOWS)
|
||||
#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
|
||||
|
||||
#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
|
||||
inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
|
||||
inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
|
||||
#else
|
||||
inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }
|
||||
inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }
|
||||
#endif
|
||||
|
||||
#elif OS(DARWIN)
|
||||
#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
|
||||
|
||||
inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }
|
||||
inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }
|
||||
|
||||
#elif OS(QNX)
|
||||
#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
|
||||
|
||||
// Note, atomic_{add, sub}_value() return the previous value of addend's content.
|
||||
inline int atomicIncrement(int volatile* addend) { return static_cast<int>(atomic_add_value(reinterpret_cast<unsigned volatile*>(addend), 1)) + 1; }
|
||||
inline int atomicDecrement(int volatile* addend) { return static_cast<int>(atomic_sub_value(reinterpret_cast<unsigned volatile*>(addend), 1)) - 1; }
|
||||
|
||||
#elif OS(ANDROID)
|
||||
|
||||
inline int atomicIncrement(int volatile* addend) { return __atomic_inc(addend); }
|
||||
inline int atomicDecrement(int volatile* addend) { return __atomic_dec(addend); }
|
||||
|
||||
#elif COMPILER(GCC) && !CPU(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
|
||||
#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
|
||||
|
||||
inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }
|
||||
inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }
|
||||
|
||||
#endif
|
||||
|
||||
inline bool weakCompareAndSwap(unsigned* location, unsigned expected, unsigned newValue)
|
||||
{
|
||||
#if ENABLE(COMPARE_AND_SWAP)
|
||||
bool result;
|
||||
#if CPU(X86) || CPU(X86_64)
|
||||
asm volatile(
|
||||
"lock; cmpxchgl %3, %2\n\t"
|
||||
"sete %1"
|
||||
: "+a"(expected), "=q"(result), "+m"(*location)
|
||||
: "r"(newValue)
|
||||
: "memory"
|
||||
);
|
||||
#elif CPU(ARM_THUMB2)
|
||||
unsigned tmp;
|
||||
asm volatile(
|
||||
"movw %1, #1\n\t"
|
||||
"ldrex %2, %0\n\t"
|
||||
"cmp %3, %2\n\t"
|
||||
"bne.n 0f\n\t"
|
||||
"strex %1, %4, %0\n\t"
|
||||
"0:"
|
||||
: "+m"(*location), "=&r"(result), "=&r"(tmp)
|
||||
: "r"(expected), "r"(newValue)
|
||||
: "memory");
|
||||
result = !result;
|
||||
#else
|
||||
#error "Bad architecture for compare and swap."
|
||||
#endif
|
||||
return result;
|
||||
#else
|
||||
UNUSED_PARAM(location);
|
||||
UNUSED_PARAM(expected);
|
||||
UNUSED_PARAM(newValue);
|
||||
CRASH();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool weakCompareAndSwap(void*volatile* location, void* expected, void* newValue)
|
||||
{
|
||||
#if ENABLE(COMPARE_AND_SWAP)
|
||||
#if CPU(X86_64)
|
||||
bool result;
|
||||
asm volatile(
|
||||
"lock; cmpxchgq %3, %2\n\t"
|
||||
"sete %1"
|
||||
: "+a"(expected), "=q"(result), "+m"(*location)
|
||||
: "r"(newValue)
|
||||
: "memory"
|
||||
);
|
||||
return result;
|
||||
#else
|
||||
return weakCompareAndSwap(bitwise_cast<unsigned*>(location), bitwise_cast<unsigned>(expected), bitwise_cast<unsigned>(newValue));
|
||||
#endif
|
||||
#else // ENABLE(COMPARE_AND_SWAP)
|
||||
UNUSED_PARAM(location);
|
||||
UNUSED_PARAM(expected);
|
||||
UNUSED_PARAM(newValue);
|
||||
CRASH();
|
||||
return 0;
|
||||
#endif // ENABLE(COMPARE_AND_SWAP)
|
||||
}
|
||||
|
||||
inline bool weakCompareAndSwap(volatile uintptr_t* location, uintptr_t expected, uintptr_t newValue)
|
||||
{
|
||||
return weakCompareAndSwap(reinterpret_cast<void*volatile*>(location), reinterpret_cast<void*>(expected), reinterpret_cast<void*>(newValue));
|
||||
}
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
#if USE(LOCKFREE_THREADSAFEREFCOUNTED)
|
||||
using WTF::atomicDecrement;
|
||||
using WTF::atomicIncrement;
|
||||
#endif
|
||||
|
||||
#endif // Atomics_h
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef BitVector_h
|
||||
#define BitVector_h
|
||||
|
||||
#include <wtf/Assertions.h>
|
||||
#include <wtf/StdLibExtras.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// This is a space-efficient, resizeable bitvector class. In the common case it
|
||||
// occupies one word, but if necessary, it will inflate this one word to point
|
||||
// to a single chunk of out-of-line allocated storage to store an arbitrary number
|
||||
// of bits.
|
||||
//
|
||||
// - The bitvector remembers the bound of how many bits can be stored, but this
|
||||
// may be slightly greater (by as much as some platform-specific constant)
|
||||
// than the last argument passed to ensureSize().
|
||||
//
|
||||
// - The bitvector can resize itself automatically (set, clear, get) or can be used
|
||||
// in a manual mode, which is faster (quickSet, quickClear, quickGet, ensureSize).
|
||||
//
|
||||
// - Accesses ASSERT that you are within bounds.
|
||||
//
|
||||
// - Bits are automatically initialized to zero.
|
||||
//
|
||||
// On the other hand, this BitVector class may not be the fastest around, since
|
||||
// it does conditionals on every get/set/clear. But it is great if you need to
|
||||
// juggle a lot of variable-length BitVectors and you're worried about wasting
|
||||
// space.
|
||||
|
||||
class BitVector {
|
||||
public:
|
||||
BitVector()
|
||||
: m_bitsOrPointer(makeInlineBits(0))
|
||||
{
|
||||
}
|
||||
|
||||
explicit BitVector(size_t numBits)
|
||||
: m_bitsOrPointer(makeInlineBits(0))
|
||||
{
|
||||
ensureSize(numBits);
|
||||
}
|
||||
|
||||
BitVector(const BitVector& other)
|
||||
: m_bitsOrPointer(makeInlineBits(0))
|
||||
{
|
||||
(*this) = other;
|
||||
}
|
||||
|
||||
|
||||
~BitVector()
|
||||
{
|
||||
if (isInline())
|
||||
return;
|
||||
OutOfLineBits::destroy(outOfLineBits());
|
||||
}
|
||||
|
||||
BitVector& operator=(const BitVector& other)
|
||||
{
|
||||
if (isInline() && other.isInline())
|
||||
m_bitsOrPointer = other.m_bitsOrPointer;
|
||||
else
|
||||
setSlow(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
if (isInline())
|
||||
return maxInlineBits();
|
||||
return outOfLineBits()->numBits();
|
||||
}
|
||||
|
||||
void ensureSize(size_t numBits)
|
||||
{
|
||||
if (numBits <= size())
|
||||
return;
|
||||
resizeOutOfLine(numBits);
|
||||
}
|
||||
|
||||
// Like ensureSize(), but supports reducing the size of the bitvector.
|
||||
void resize(size_t numBits);
|
||||
|
||||
void clearAll();
|
||||
|
||||
bool quickGet(size_t bit) const
|
||||
{
|
||||
ASSERT(bit < size());
|
||||
return !!(bits()[bit / bitsInPointer()] & (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1))));
|
||||
}
|
||||
|
||||
void quickSet(size_t bit)
|
||||
{
|
||||
ASSERT(bit < size());
|
||||
bits()[bit / bitsInPointer()] |= (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
|
||||
}
|
||||
|
||||
void quickClear(size_t bit)
|
||||
{
|
||||
ASSERT(bit < size());
|
||||
bits()[bit / bitsInPointer()] &= ~(static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
|
||||
}
|
||||
|
||||
void quickSet(size_t bit, bool value)
|
||||
{
|
||||
if (value)
|
||||
quickSet(bit);
|
||||
else
|
||||
quickClear(bit);
|
||||
}
|
||||
|
||||
bool get(size_t bit) const
|
||||
{
|
||||
if (bit >= size())
|
||||
return false;
|
||||
return quickGet(bit);
|
||||
}
|
||||
|
||||
void set(size_t bit)
|
||||
{
|
||||
ensureSize(bit + 1);
|
||||
quickSet(bit);
|
||||
}
|
||||
|
||||
void clear(size_t bit)
|
||||
{
|
||||
if (bit >= size())
|
||||
return;
|
||||
quickClear(bit);
|
||||
}
|
||||
|
||||
void set(size_t bit, bool value)
|
||||
{
|
||||
if (value)
|
||||
set(bit);
|
||||
else
|
||||
clear(bit);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump(FILE* out);
|
||||
#endif
|
||||
|
||||
private:
|
||||
static unsigned bitsInPointer()
|
||||
{
|
||||
return sizeof(void*) << 3;
|
||||
}
|
||||
|
||||
static unsigned maxInlineBits()
|
||||
{
|
||||
return bitsInPointer() - 1;
|
||||
}
|
||||
|
||||
static size_t byteCount(size_t bitCount)
|
||||
{
|
||||
return (bitCount + 7) >> 3;
|
||||
}
|
||||
|
||||
static uintptr_t makeInlineBits(uintptr_t bits)
|
||||
{
|
||||
ASSERT(!(bits & (static_cast<uintptr_t>(1) << maxInlineBits())));
|
||||
return bits | (static_cast<uintptr_t>(1) << maxInlineBits());
|
||||
}
|
||||
|
||||
class OutOfLineBits {
|
||||
public:
|
||||
size_t numBits() const { return m_numBits; }
|
||||
size_t numWords() const { return (m_numBits + bitsInPointer() - 1) / bitsInPointer(); }
|
||||
uintptr_t* bits() { return bitwise_cast<uintptr_t*>(this + 1); }
|
||||
const uintptr_t* bits() const { return bitwise_cast<const uintptr_t*>(this + 1); }
|
||||
|
||||
static OutOfLineBits* create(size_t numBits);
|
||||
|
||||
static void destroy(OutOfLineBits*);
|
||||
|
||||
private:
|
||||
OutOfLineBits(size_t numBits)
|
||||
: m_numBits(numBits)
|
||||
{
|
||||
}
|
||||
|
||||
size_t m_numBits;
|
||||
};
|
||||
|
||||
bool isInline() const { return m_bitsOrPointer >> maxInlineBits(); }
|
||||
|
||||
const OutOfLineBits* outOfLineBits() const { return bitwise_cast<const OutOfLineBits*>(m_bitsOrPointer << 1); }
|
||||
OutOfLineBits* outOfLineBits() { return bitwise_cast<OutOfLineBits*>(m_bitsOrPointer << 1); }
|
||||
|
||||
void resizeOutOfLine(size_t numBits);
|
||||
void setSlow(const BitVector& other);
|
||||
|
||||
uintptr_t* bits()
|
||||
{
|
||||
if (isInline())
|
||||
return &m_bitsOrPointer;
|
||||
return outOfLineBits()->bits();
|
||||
}
|
||||
|
||||
const uintptr_t* bits() const
|
||||
{
|
||||
if (isInline())
|
||||
return &m_bitsOrPointer;
|
||||
return outOfLineBits()->bits();
|
||||
}
|
||||
|
||||
uintptr_t m_bitsOrPointer;
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::BitVector;
|
||||
|
||||
#endif // BitVector_h
|
||||
@@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
#ifndef Bitmap_h
|
||||
#define Bitmap_h
|
||||
|
||||
#include "Atomics.h"
|
||||
#include "FixedArray.h"
|
||||
#include "StdLibExtras.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
enum BitmapAtomicMode {
|
||||
// This makes concurrentTestAndSet behave just like testAndSet.
|
||||
BitmapNotAtomic,
|
||||
|
||||
// This makes concurrentTestAndSet use compareAndSwap, so that it's
|
||||
// atomic even when used concurrently.
|
||||
BitmapAtomic
|
||||
};
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode = BitmapNotAtomic>
|
||||
class Bitmap {
|
||||
private:
|
||||
typedef uint32_t WordType;
|
||||
|
||||
public:
|
||||
Bitmap();
|
||||
|
||||
bool get(size_t) const;
|
||||
void set(size_t);
|
||||
bool testAndSet(size_t);
|
||||
bool testAndClear(size_t);
|
||||
bool concurrentTestAndSet(size_t);
|
||||
bool concurrentTestAndClear(size_t);
|
||||
size_t nextPossiblyUnset(size_t) const;
|
||||
void clear(size_t);
|
||||
void clearAll();
|
||||
int64_t findRunOfZeros(size_t) const;
|
||||
size_t count(size_t = 0) const;
|
||||
size_t isEmpty() const;
|
||||
size_t isFull() const;
|
||||
|
||||
private:
|
||||
static const WordType wordSize = sizeof(WordType) * 8;
|
||||
static const WordType words = (size + wordSize - 1) / wordSize;
|
||||
|
||||
// the literal '1' is of type signed int. We want to use an unsigned
|
||||
// version of the correct size when doing the calculations because if
|
||||
// WordType is larger than int, '1 << 31' will first be sign extended
|
||||
// and then casted to unsigned, meaning that set(31) when WordType is
|
||||
// a 64 bit unsigned int would give 0xffff8000
|
||||
static const WordType one = 1;
|
||||
|
||||
FixedArray<WordType, words> bits;
|
||||
};
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline Bitmap<size, atomicMode>::Bitmap()
|
||||
{
|
||||
clearAll();
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline bool Bitmap<size, atomicMode>::get(size_t n) const
|
||||
{
|
||||
return !!(bits[n / wordSize] & (one << (n % wordSize)));
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline void Bitmap<size, atomicMode>::set(size_t n)
|
||||
{
|
||||
bits[n / wordSize] |= (one << (n % wordSize));
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline bool Bitmap<size, atomicMode>::testAndSet(size_t n)
|
||||
{
|
||||
WordType mask = one << (n % wordSize);
|
||||
size_t index = n / wordSize;
|
||||
bool result = bits[index] & mask;
|
||||
bits[index] |= mask;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline bool Bitmap<size, atomicMode>::testAndClear(size_t n)
|
||||
{
|
||||
WordType mask = one << (n % wordSize);
|
||||
size_t index = n / wordSize;
|
||||
bool result = bits[index] & mask;
|
||||
bits[index] &= ~mask;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline bool Bitmap<size, atomicMode>::concurrentTestAndSet(size_t n)
|
||||
{
|
||||
if (atomicMode == BitmapNotAtomic)
|
||||
return testAndSet(n);
|
||||
|
||||
ASSERT(atomicMode == BitmapAtomic);
|
||||
|
||||
WordType mask = one << (n % wordSize);
|
||||
size_t index = n / wordSize;
|
||||
WordType* wordPtr = bits.data() + index;
|
||||
WordType oldValue;
|
||||
do {
|
||||
oldValue = *wordPtr;
|
||||
if (oldValue & mask)
|
||||
return true;
|
||||
} while (!weakCompareAndSwap(wordPtr, oldValue, oldValue | mask));
|
||||
return false;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline bool Bitmap<size, atomicMode>::concurrentTestAndClear(size_t n)
|
||||
{
|
||||
if (atomicMode == BitmapNotAtomic)
|
||||
return testAndClear(n);
|
||||
|
||||
ASSERT(atomicMode == BitmapAtomic);
|
||||
|
||||
WordType mask = one << (n % wordSize);
|
||||
size_t index = n / wordSize;
|
||||
WordType* wordPtr = bits.data() + index;
|
||||
WordType oldValue;
|
||||
do {
|
||||
oldValue = *wordPtr;
|
||||
if (!(oldValue & mask))
|
||||
return false;
|
||||
} while (!weakCompareAndSwap(wordPtr, oldValue, oldValue & ~mask));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline void Bitmap<size, atomicMode>::clear(size_t n)
|
||||
{
|
||||
bits[n / wordSize] &= ~(one << (n % wordSize));
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline void Bitmap<size, atomicMode>::clearAll()
|
||||
{
|
||||
memset(bits.data(), 0, sizeof(bits));
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline size_t Bitmap<size, atomicMode>::nextPossiblyUnset(size_t start) const
|
||||
{
|
||||
if (!~bits[start / wordSize])
|
||||
return ((start / wordSize) + 1) * wordSize;
|
||||
return start + 1;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline int64_t Bitmap<size, atomicMode>::findRunOfZeros(size_t runLength) const
|
||||
{
|
||||
if (!runLength)
|
||||
runLength = 1;
|
||||
|
||||
for (size_t i = 0; i <= (size - runLength) ; i++) {
|
||||
bool found = true;
|
||||
for (size_t j = i; j <= (i + runLength - 1) ; j++) {
|
||||
if (get(j)) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline size_t Bitmap<size, atomicMode>::count(size_t start) const
|
||||
{
|
||||
size_t result = 0;
|
||||
for ( ; (start % wordSize); ++start) {
|
||||
if (get(start))
|
||||
++result;
|
||||
}
|
||||
for (size_t i = start / wordSize; i < words; ++i)
|
||||
result += WTF::bitCount(bits[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline size_t Bitmap<size, atomicMode>::isEmpty() const
|
||||
{
|
||||
for (size_t i = 0; i < words; ++i)
|
||||
if (bits[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t size, BitmapAtomicMode atomicMode>
|
||||
inline size_t Bitmap<size, atomicMode>::isFull() const
|
||||
{
|
||||
for (size_t i = 0; i < words; ++i)
|
||||
if (~bits[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef BlockStack_h
|
||||
#define BlockStack_h
|
||||
|
||||
#include <wtf/Assertions.h>
|
||||
#include <wtf/FastMalloc.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
template <typename T> class BlockStack {
|
||||
public:
|
||||
static const size_t blockSize = 4096;
|
||||
static const size_t blockLength = blockSize / sizeof(T);
|
||||
|
||||
BlockStack();
|
||||
~BlockStack();
|
||||
|
||||
T* grow();
|
||||
void shrink(T*);
|
||||
|
||||
const Vector<T*>& blocks();
|
||||
|
||||
private:
|
||||
Vector<T*> m_blocks;
|
||||
T* m_spareBlock; // Used to avoid thrash at block boundaries.
|
||||
};
|
||||
|
||||
template <typename T> BlockStack<T>::BlockStack()
|
||||
: m_spareBlock(0)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> BlockStack<T>::~BlockStack()
|
||||
{
|
||||
if (m_spareBlock)
|
||||
fastFree(m_spareBlock);
|
||||
for (size_t i = 0; i < m_blocks.size(); ++i)
|
||||
fastFree(m_blocks[i]);
|
||||
}
|
||||
|
||||
template <typename T> inline const Vector<T*>& BlockStack<T>::blocks()
|
||||
{
|
||||
return m_blocks;
|
||||
}
|
||||
|
||||
template <typename T> T* BlockStack<T>::grow()
|
||||
{
|
||||
T* block = m_spareBlock ? m_spareBlock : static_cast<T*>(fastMalloc(blockSize));
|
||||
m_spareBlock = 0;
|
||||
|
||||
m_blocks.append(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
template <typename T> void BlockStack<T>::shrink(T* newEnd)
|
||||
{
|
||||
ASSERT(newEnd != m_blocks.last() + blockLength);
|
||||
m_spareBlock = m_blocks.last();
|
||||
m_blocks.removeLast();
|
||||
|
||||
while (m_blocks.last() + blockLength != newEnd) {
|
||||
fastFree(m_blocks.last());
|
||||
m_blocks.removeLast();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using WTF::BlockStack;
|
||||
|
||||
#endif
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef BloomFilter_h
|
||||
#define BloomFilter_h
|
||||
|
||||
#include <wtf/AlwaysInline.h>
|
||||
#include <wtf/text/AtomicString.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// Counting bloom filter with k=2 and 8 bit counters. Uses 2^keyBits bytes of memory.
|
||||
// False positive rate is approximately (1-e^(-2n/m))^2, where n is the number of unique
|
||||
// keys and m is the table size (==2^keyBits).
|
||||
template <unsigned keyBits>
|
||||
class BloomFilter {
|
||||
public:
|
||||
COMPILE_ASSERT(keyBits <= 16, bloom_filter_key_size);
|
||||
|
||||
static const size_t tableSize = 1 << keyBits;
|
||||
static const unsigned keyMask = (1 << keyBits) - 1;
|
||||
static uint8_t maximumCount() { return std::numeric_limits<uint8_t>::max(); }
|
||||
|
||||
BloomFilter() { clear(); }
|
||||
|
||||
void add(unsigned hash);
|
||||
void remove(unsigned hash);
|
||||
|
||||
// The filter may give false positives (claim it may contain a key it doesn't)
|
||||
// but never false negatives (claim it doesn't contain a key it does).
|
||||
bool mayContain(unsigned hash) const { return firstSlot(hash) && secondSlot(hash); }
|
||||
|
||||
// The filter must be cleared before reuse even if all keys are removed.
|
||||
// Otherwise overflowed keys will stick around.
|
||||
void clear();
|
||||
|
||||
void add(const AtomicString& string) { add(string.impl()->existingHash()); }
|
||||
void add(const String& string) { add(string.impl()->hash()); }
|
||||
void remove(const AtomicString& string) { remove(string.impl()->existingHash()); }
|
||||
void remove(const String& string) { remove(string.impl()->hash()); }
|
||||
|
||||
bool mayContain(const AtomicString& string) const { return mayContain(string.impl()->existingHash()); }
|
||||
bool mayContain(const String& string) const { return mayContain(string.impl()->hash()); }
|
||||
|
||||
#if !ASSERT_DISABLED
|
||||
// Slow.
|
||||
bool likelyEmpty() const;
|
||||
bool isClear() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
uint8_t& firstSlot(unsigned hash) { return m_table[hash & keyMask]; }
|
||||
uint8_t& secondSlot(unsigned hash) { return m_table[(hash >> 16) & keyMask]; }
|
||||
const uint8_t& firstSlot(unsigned hash) const { return m_table[hash & keyMask]; }
|
||||
const uint8_t& secondSlot(unsigned hash) const { return m_table[(hash >> 16) & keyMask]; }
|
||||
|
||||
uint8_t m_table[tableSize];
|
||||
};
|
||||
|
||||
template <unsigned keyBits>
|
||||
inline void BloomFilter<keyBits>::add(unsigned hash)
|
||||
{
|
||||
uint8_t& first = firstSlot(hash);
|
||||
uint8_t& second = secondSlot(hash);
|
||||
if (LIKELY(first < maximumCount()))
|
||||
++first;
|
||||
if (LIKELY(second < maximumCount()))
|
||||
++second;
|
||||
}
|
||||
|
||||
template <unsigned keyBits>
|
||||
inline void BloomFilter<keyBits>::remove(unsigned hash)
|
||||
{
|
||||
uint8_t& first = firstSlot(hash);
|
||||
uint8_t& second = secondSlot(hash);
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
// In case of an overflow, the slot sticks in the table until clear().
|
||||
if (LIKELY(first < maximumCount()))
|
||||
--first;
|
||||
if (LIKELY(second < maximumCount()))
|
||||
--second;
|
||||
}
|
||||
|
||||
template <unsigned keyBits>
|
||||
inline void BloomFilter<keyBits>::clear()
|
||||
{
|
||||
memset(m_table, 0, tableSize);
|
||||
}
|
||||
|
||||
#if !ASSERT_DISABLED
|
||||
template <unsigned keyBits>
|
||||
bool BloomFilter<keyBits>::likelyEmpty() const
|
||||
{
|
||||
for (size_t n = 0; n < tableSize; ++n) {
|
||||
if (m_table[n] && m_table[n] != maximumCount())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <unsigned keyBits>
|
||||
bool BloomFilter<keyBits>::isClear() const
|
||||
{
|
||||
for (size_t n = 0; n < tableSize; ++n) {
|
||||
if (m_table[n])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
using WTF::BloomFilter;
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BooleanObject_h
|
||||
#define BooleanObject_h
|
||||
|
||||
#include "JSWrapperObject.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class BooleanObject : public JSWrapperObject {
|
||||
protected:
|
||||
BooleanObject(JSGlobalData&, Structure*);
|
||||
void finishCreation(JSGlobalData&);
|
||||
|
||||
public:
|
||||
typedef JSWrapperObject Base;
|
||||
|
||||
static BooleanObject* create(JSGlobalData& globalData, Structure* structure)
|
||||
{
|
||||
BooleanObject* boolean = new (NotNull, allocateCell<BooleanObject>(globalData.heap)) BooleanObject(globalData, structure);
|
||||
boolean->finishCreation(globalData);
|
||||
return boolean;
|
||||
}
|
||||
|
||||
static const ClassInfo s_info;
|
||||
|
||||
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
|
||||
{
|
||||
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
|
||||
}
|
||||
};
|
||||
|
||||
BooleanObject* asBooleanObject(JSValue);
|
||||
|
||||
inline BooleanObject* asBooleanObject(JSValue value)
|
||||
{
|
||||
ASSERT(asObject(value)->inherits(&BooleanObject::s_info));
|
||||
return static_cast<BooleanObject*>(asObject(value));
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // BooleanObject_h
|
||||
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_BoundsCheckedPointer_h
|
||||
#define WTF_BoundsCheckedPointer_h
|
||||
|
||||
#include "Assertions.h"
|
||||
#include "UnusedParam.h"
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// Useful for when you'd like to do pointer arithmetic on a buffer, but
|
||||
// you'd also like to get some ASSERT()'s that prevent you from overflowing.
|
||||
// This should be performance-neutral in release builds, while providing
|
||||
// you with strong assertions in debug builds. Note that all of the
|
||||
// asserting happens when you actually access the pointer. You are allowed
|
||||
// to overflow or underflow with arithmetic so long as no accesses are
|
||||
// performed.
|
||||
|
||||
template<typename T>
|
||||
class BoundsCheckedPointer {
|
||||
public:
|
||||
BoundsCheckedPointer()
|
||||
: m_pointer(0)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_begin(0)
|
||||
, m_end(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
BoundsCheckedPointer(T* pointer, size_t numElements)
|
||||
: m_pointer(pointer)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_begin(pointer)
|
||||
, m_end(pointer + numElements)
|
||||
#endif
|
||||
{
|
||||
UNUSED_PARAM(numElements);
|
||||
}
|
||||
|
||||
BoundsCheckedPointer(T* pointer, T* end)
|
||||
: m_pointer(pointer)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_begin(pointer)
|
||||
, m_end(end)
|
||||
#endif
|
||||
{
|
||||
UNUSED_PARAM(end);
|
||||
}
|
||||
|
||||
BoundsCheckedPointer(T* pointer, T* begin, size_t numElements)
|
||||
: m_pointer(pointer)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_begin(begin)
|
||||
, m_end(begin + numElements)
|
||||
#endif
|
||||
{
|
||||
UNUSED_PARAM(begin);
|
||||
UNUSED_PARAM(numElements);
|
||||
}
|
||||
|
||||
BoundsCheckedPointer(T* pointer, T* begin, T* end)
|
||||
: m_pointer(pointer)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_begin(begin)
|
||||
, m_end(end)
|
||||
#endif
|
||||
{
|
||||
UNUSED_PARAM(begin);
|
||||
UNUSED_PARAM(end);
|
||||
}
|
||||
|
||||
BoundsCheckedPointer& operator=(T* value)
|
||||
{
|
||||
m_pointer = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer& operator+=(ptrdiff_t amount)
|
||||
{
|
||||
m_pointer += amount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer& operator-=(ptrdiff_t amount)
|
||||
{
|
||||
m_pointer -= amount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator+(ptrdiff_t amount) const
|
||||
{
|
||||
BoundsCheckedPointer result = *this;
|
||||
result.m_pointer += amount;
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator-(ptrdiff_t amount) const
|
||||
{
|
||||
BoundsCheckedPointer result = *this;
|
||||
result.m_pointer -= amount;
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator++() // prefix
|
||||
{
|
||||
m_pointer++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator--() // prefix
|
||||
{
|
||||
m_pointer--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator++(int) // postfix
|
||||
{
|
||||
BoundsCheckedPointer result = *this;
|
||||
m_pointer++;
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator--(int) // postfix
|
||||
{
|
||||
BoundsCheckedPointer result = *this;
|
||||
m_pointer--;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator<(T* other) const
|
||||
{
|
||||
return m_pointer < other;
|
||||
}
|
||||
|
||||
bool operator<=(T* other) const
|
||||
{
|
||||
return m_pointer <= other;
|
||||
}
|
||||
|
||||
bool operator>(T* other) const
|
||||
{
|
||||
return m_pointer > other;
|
||||
}
|
||||
|
||||
bool operator>=(T* other) const
|
||||
{
|
||||
return m_pointer >= other;
|
||||
}
|
||||
|
||||
bool operator==(T* other) const
|
||||
{
|
||||
return m_pointer == other;
|
||||
}
|
||||
|
||||
bool operator!=(T* other) const
|
||||
{
|
||||
return m_pointer != other;
|
||||
}
|
||||
|
||||
bool operator<(BoundsCheckedPointer other) const
|
||||
{
|
||||
return m_pointer < other.m_pointer;
|
||||
}
|
||||
|
||||
bool operator<=(BoundsCheckedPointer other) const
|
||||
{
|
||||
return m_pointer <= other.m_pointer;
|
||||
}
|
||||
|
||||
bool operator>(BoundsCheckedPointer other) const
|
||||
{
|
||||
return m_pointer > other.m_pointer;
|
||||
}
|
||||
|
||||
bool operator>=(BoundsCheckedPointer other) const
|
||||
{
|
||||
return m_pointer >= other.m_pointer;
|
||||
}
|
||||
|
||||
bool operator==(BoundsCheckedPointer other) const
|
||||
{
|
||||
return m_pointer == other.m_pointer;
|
||||
}
|
||||
|
||||
bool operator!=(BoundsCheckedPointer other) const
|
||||
{
|
||||
return m_pointer != other.m_pointer;
|
||||
}
|
||||
|
||||
BoundsCheckedPointer operator!()
|
||||
{
|
||||
return !m_pointer;
|
||||
}
|
||||
|
||||
T* get()
|
||||
{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
T& operator*()
|
||||
{
|
||||
validate();
|
||||
return *m_pointer;
|
||||
}
|
||||
|
||||
const T& operator*() const
|
||||
{
|
||||
validate();
|
||||
return *m_pointer;
|
||||
}
|
||||
|
||||
T& operator[](ptrdiff_t index)
|
||||
{
|
||||
validate(m_pointer + index);
|
||||
return m_pointer[index];
|
||||
}
|
||||
|
||||
const T& operator[](ptrdiff_t index) const
|
||||
{
|
||||
validate(m_pointer + index);
|
||||
return m_pointer[index];
|
||||
}
|
||||
|
||||
// The only thing this has in common with strcat() is that it
|
||||
// keeps appending from the given pointer until reaching 0.
|
||||
BoundsCheckedPointer& strcat(const T* source)
|
||||
{
|
||||
while (*source)
|
||||
*(*this)++ = *source++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void validate(T* pointer) const
|
||||
{
|
||||
ASSERT_UNUSED(pointer, pointer >= m_begin);
|
||||
|
||||
// This guard is designed to protect against the misaligned case.
|
||||
// A simple pointer < m_end would miss the case if, for example,
|
||||
// T = int16_t and pointer is 1 byte less than m_end.
|
||||
ASSERT_UNUSED(pointer, pointer + 1 <= m_end);
|
||||
}
|
||||
|
||||
void validate() const
|
||||
{
|
||||
validate(m_pointer);
|
||||
}
|
||||
|
||||
T* m_pointer;
|
||||
#if !ASSERT_DISABLED
|
||||
T* m_begin;
|
||||
T* m_end;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::BoundsCheckedPointer;
|
||||
|
||||
#endif // WTF_BoundsCheckedPointer_h
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef BumpBlock_h
|
||||
#define BumpBlock_h
|
||||
|
||||
#include "HeapBlock.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class BumpSpace;
|
||||
|
||||
class BumpBlock : public HeapBlock {
|
||||
friend class BumpSpace;
|
||||
public:
|
||||
BumpBlock(PageAllocationAligned& allocation)
|
||||
: HeapBlock(allocation)
|
||||
, m_offset(m_payload)
|
||||
, m_isPinned(false)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_offset;
|
||||
uintptr_t m_isPinned;
|
||||
char m_payload[1];
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef BumpPointerAllocator_h
|
||||
#define BumpPointerAllocator_h
|
||||
|
||||
#include <wtf/PageAllocation.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
#define MINIMUM_BUMP_POOL_SIZE 0x1000
|
||||
|
||||
class BumpPointerPool {
|
||||
public:
|
||||
// ensureCapacity will check whether the current pool has capacity to
|
||||
// allocate 'size' bytes of memory If it does not, it will attempt to
|
||||
// allocate a new pool (which will be added to this one in a chain).
|
||||
//
|
||||
// If allocation fails (out of memory) this method will return null.
|
||||
// If the return value is non-null, then callers should update any
|
||||
// references they have to this current (possibly full) BumpPointerPool
|
||||
// to instead point to the newly returned BumpPointerPool.
|
||||
BumpPointerPool* ensureCapacity(size_t size)
|
||||
{
|
||||
void* allocationEnd = static_cast<char*>(m_current) + size;
|
||||
ASSERT(allocationEnd > m_current); // check for overflow
|
||||
if (allocationEnd <= static_cast<void*>(this))
|
||||
return this;
|
||||
return ensureCapacityCrossPool(this, size);
|
||||
}
|
||||
|
||||
// alloc should only be called after calling ensureCapacity; as such
|
||||
// alloc will never fail.
|
||||
void* alloc(size_t size)
|
||||
{
|
||||
void* current = m_current;
|
||||
void* allocationEnd = static_cast<char*>(current) + size;
|
||||
ASSERT(allocationEnd > current); // check for overflow
|
||||
ASSERT(allocationEnd <= static_cast<void*>(this));
|
||||
m_current = allocationEnd;
|
||||
return current;
|
||||
}
|
||||
|
||||
// The dealloc method releases memory allocated using alloc. Memory
|
||||
// must be released in a LIFO fashion, e.g. if the client calls alloc
|
||||
// four times, returning pointer A, B, C, D, then the only valid order
|
||||
// in which these may be deallocaed is D, C, B, A.
|
||||
//
|
||||
// The client may optionally skip some deallocations. In the example
|
||||
// above, it would be valid to only explicitly dealloc C, A (D being
|
||||
// dealloced along with C, B along with A).
|
||||
//
|
||||
// If pointer was not allocated from this pool (or pools) then dealloc
|
||||
// will CRASH(). Callers should update any references they have to
|
||||
// this current BumpPointerPool to instead point to the returned
|
||||
// BumpPointerPool.
|
||||
BumpPointerPool* dealloc(void* position)
|
||||
{
|
||||
if ((position >= m_start) && (position <= static_cast<void*>(this))) {
|
||||
ASSERT(position <= m_current);
|
||||
m_current = position;
|
||||
return this;
|
||||
}
|
||||
return deallocCrossPool(this, position);
|
||||
}
|
||||
|
||||
private:
|
||||
// Placement operator new, returns the last 'size' bytes of allocation for use as this.
|
||||
void* operator new(size_t size, const PageAllocation& allocation)
|
||||
{
|
||||
ASSERT(size < allocation.size());
|
||||
return reinterpret_cast<char*>(reinterpret_cast<intptr_t>(allocation.base()) + allocation.size()) - size;
|
||||
}
|
||||
|
||||
BumpPointerPool(const PageAllocation& allocation)
|
||||
: m_current(allocation.base())
|
||||
, m_start(allocation.base())
|
||||
, m_next(0)
|
||||
, m_previous(0)
|
||||
, m_allocation(allocation)
|
||||
{
|
||||
}
|
||||
|
||||
static BumpPointerPool* create(size_t minimumCapacity = 0)
|
||||
{
|
||||
// Add size of BumpPointerPool object, check for overflow.
|
||||
minimumCapacity += sizeof(BumpPointerPool);
|
||||
if (minimumCapacity < sizeof(BumpPointerPool))
|
||||
return 0;
|
||||
|
||||
size_t poolSize = MINIMUM_BUMP_POOL_SIZE;
|
||||
while (poolSize < minimumCapacity) {
|
||||
poolSize <<= 1;
|
||||
// The following if check relies on MINIMUM_BUMP_POOL_SIZE being a power of 2!
|
||||
ASSERT(!(MINIMUM_BUMP_POOL_SIZE & (MINIMUM_BUMP_POOL_SIZE - 1)));
|
||||
if (!poolSize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PageAllocation allocation = PageAllocation::allocate(poolSize);
|
||||
if (!!allocation)
|
||||
return new (allocation) BumpPointerPool(allocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void shrink()
|
||||
{
|
||||
ASSERT(!m_previous);
|
||||
m_current = m_start;
|
||||
while (m_next) {
|
||||
BumpPointerPool* nextNext = m_next->m_next;
|
||||
m_next->destroy();
|
||||
m_next = nextNext;
|
||||
}
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_allocation.deallocate();
|
||||
}
|
||||
|
||||
static BumpPointerPool* ensureCapacityCrossPool(BumpPointerPool* previousPool, size_t size)
|
||||
{
|
||||
// The pool passed should not have capacity, so we'll start with the next one.
|
||||
ASSERT(previousPool);
|
||||
ASSERT((static_cast<char*>(previousPool->m_current) + size) > previousPool->m_current); // check for overflow
|
||||
ASSERT((static_cast<char*>(previousPool->m_current) + size) > static_cast<void*>(previousPool));
|
||||
BumpPointerPool* pool = previousPool->m_next;
|
||||
|
||||
while (true) {
|
||||
if (!pool) {
|
||||
// We've run to the end; allocate a new pool.
|
||||
pool = BumpPointerPool::create(size);
|
||||
previousPool->m_next = pool;
|
||||
pool->m_previous = previousPool;
|
||||
return pool;
|
||||
}
|
||||
|
||||
//
|
||||
void* current = pool->m_current;
|
||||
void* allocationEnd = static_cast<char*>(current) + size;
|
||||
ASSERT(allocationEnd > current); // check for overflow
|
||||
if (allocationEnd <= static_cast<void*>(pool))
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
|
||||
static BumpPointerPool* deallocCrossPool(BumpPointerPool* pool, void* position)
|
||||
{
|
||||
// Should only be called if position is not in the current pool.
|
||||
ASSERT((position < pool->m_start) || (position > static_cast<void*>(pool)));
|
||||
|
||||
while (true) {
|
||||
// Unwind the current pool to the start, move back in the chain to the previous pool.
|
||||
pool->m_current = pool->m_start;
|
||||
pool = pool->m_previous;
|
||||
|
||||
// position was nowhere in the chain!
|
||||
if (!pool)
|
||||
CRASH();
|
||||
|
||||
if ((position >= pool->m_start) && (position <= static_cast<void*>(pool))) {
|
||||
ASSERT(position <= pool->m_current);
|
||||
pool->m_current = position;
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* m_current;
|
||||
void* m_start;
|
||||
BumpPointerPool* m_next;
|
||||
BumpPointerPool* m_previous;
|
||||
PageAllocation m_allocation;
|
||||
|
||||
friend class BumpPointerAllocator;
|
||||
};
|
||||
|
||||
// A BumpPointerAllocator manages a set of BumpPointerPool objects, which
|
||||
// can be used for LIFO (stack like) allocation.
|
||||
//
|
||||
// To begin allocating using this class call startAllocator(). The result
|
||||
// of this method will be null if the initial pool allocation fails, or a
|
||||
// pointer to a BumpPointerPool object that can be used to perform
|
||||
// allocations. Whilst running no memory will be released until
|
||||
// stopAllocator() is called. At this point all allocations made through
|
||||
// this allocator will be reaped, and underlying memory may be freed.
|
||||
//
|
||||
// (In practice we will still hold on to the initial pool to allow allocation
|
||||
// to be quickly restared, but aditional pools will be freed).
|
||||
//
|
||||
// This allocator is non-renetrant, it is encumbant on the clients to ensure
|
||||
// startAllocator() is not called again until stopAllocator() has been called.
|
||||
class BumpPointerAllocator {
|
||||
public:
|
||||
BumpPointerAllocator()
|
||||
: m_head(0)
|
||||
{
|
||||
}
|
||||
|
||||
~BumpPointerAllocator()
|
||||
{
|
||||
if (m_head)
|
||||
m_head->destroy();
|
||||
}
|
||||
|
||||
BumpPointerPool* startAllocator()
|
||||
{
|
||||
if (!m_head)
|
||||
m_head = BumpPointerPool::create();
|
||||
return m_head;
|
||||
}
|
||||
|
||||
void stopAllocator()
|
||||
{
|
||||
if (m_head)
|
||||
m_head->shrink();
|
||||
}
|
||||
|
||||
private:
|
||||
BumpPointerPool* m_head;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using WTF::BumpPointerAllocator;
|
||||
|
||||
#endif // BumpPointerAllocator_h
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef BumpSpace_h
|
||||
#define BumpSpace_h
|
||||
|
||||
#include "TinyBloomFilter.h"
|
||||
#include <wtf/Assertions.h>
|
||||
#include <wtf/CheckedBoolean.h>
|
||||
#include <wtf/DoublyLinkedList.h>
|
||||
#include <wtf/HashSet.h>
|
||||
#include <wtf/OSAllocator.h>
|
||||
#include <wtf/PageAllocationAligned.h>
|
||||
#include <wtf/StdLibExtras.h>
|
||||
#include <wtf/ThreadingPrimitives.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class Heap;
|
||||
class BumpBlock;
|
||||
class HeapBlock;
|
||||
|
||||
class BumpSpace {
|
||||
friend class SlotVisitor;
|
||||
public:
|
||||
BumpSpace(Heap*);
|
||||
void init();
|
||||
|
||||
CheckedBoolean tryAllocate(size_t, void**);
|
||||
CheckedBoolean tryReallocate(void**, size_t, size_t);
|
||||
|
||||
void startedCopying();
|
||||
void doneCopying();
|
||||
bool isInCopyPhase() { return m_inCopyingPhase; }
|
||||
|
||||
void pin(BumpBlock*);
|
||||
bool isPinned(void*);
|
||||
|
||||
bool contains(void*, BumpBlock*&);
|
||||
|
||||
size_t totalMemoryAllocated() { return m_totalMemoryAllocated; }
|
||||
size_t totalMemoryUtilized() { return m_totalMemoryUtilized; }
|
||||
|
||||
static BumpBlock* blockFor(void*);
|
||||
|
||||
private:
|
||||
enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
|
||||
|
||||
CheckedBoolean tryAllocateSlowCase(size_t, void**);
|
||||
CheckedBoolean addNewBlock();
|
||||
CheckedBoolean allocateNewBlock(BumpBlock**);
|
||||
bool fitsInCurrentBlock(size_t);
|
||||
|
||||
static void* allocateFromBlock(BumpBlock*, size_t);
|
||||
CheckedBoolean tryAllocateOversize(size_t, void**);
|
||||
CheckedBoolean tryReallocateOversize(void**, size_t, size_t);
|
||||
|
||||
static bool isOversize(size_t);
|
||||
|
||||
CheckedBoolean borrowBlock(BumpBlock**);
|
||||
CheckedBoolean getFreshBlock(AllocationEffort, BumpBlock**);
|
||||
void doneFillingBlock(BumpBlock*);
|
||||
void recycleBlock(BumpBlock*);
|
||||
static bool fitsInBlock(BumpBlock*, size_t);
|
||||
static BumpBlock* oversizeBlockFor(void* ptr);
|
||||
|
||||
Heap* m_heap;
|
||||
|
||||
BumpBlock* m_currentBlock;
|
||||
|
||||
TinyBloomFilter m_toSpaceFilter;
|
||||
TinyBloomFilter m_oversizeFilter;
|
||||
HashSet<BumpBlock*> m_toSpaceSet;
|
||||
|
||||
Mutex m_toSpaceLock;
|
||||
Mutex m_memoryStatsLock;
|
||||
|
||||
DoublyLinkedList<HeapBlock>* m_toSpace;
|
||||
DoublyLinkedList<HeapBlock>* m_fromSpace;
|
||||
|
||||
DoublyLinkedList<HeapBlock> m_blocks1;
|
||||
DoublyLinkedList<HeapBlock> m_blocks2;
|
||||
DoublyLinkedList<HeapBlock> m_oversizeBlocks;
|
||||
|
||||
size_t m_totalMemoryAllocated;
|
||||
size_t m_totalMemoryUtilized;
|
||||
|
||||
bool m_inCopyingPhase;
|
||||
|
||||
Mutex m_loanedBlocksLock;
|
||||
ThreadCondition m_loanedBlocksCondition;
|
||||
size_t m_numberOfLoanedBlocks;
|
||||
|
||||
static const size_t s_blockSize = 64 * KB;
|
||||
static const size_t s_maxAllocationSize = 32 * KB;
|
||||
static const size_t s_pageSize = 4 * KB;
|
||||
static const size_t s_pageMask = ~(s_pageSize - 1);
|
||||
static const size_t s_initialBlockNum = 16;
|
||||
static const size_t s_blockMask = ~(s_blockSize - 1);
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif
|
||||
@@ -1,400 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef BumpSpaceInlineMethods_h
|
||||
#define BumpSpaceInlineMethods_h
|
||||
|
||||
#include "BumpBlock.h"
|
||||
#include "BumpSpace.h"
|
||||
#include "Heap.h"
|
||||
#include "HeapBlock.h"
|
||||
#include "JSGlobalData.h"
|
||||
#include <wtf/CheckedBoolean.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline BumpSpace::BumpSpace(Heap* heap)
|
||||
: m_heap(heap)
|
||||
, m_currentBlock(0)
|
||||
, m_toSpace(0)
|
||||
, m_fromSpace(0)
|
||||
, m_totalMemoryAllocated(0)
|
||||
, m_totalMemoryUtilized(0)
|
||||
, m_inCopyingPhase(false)
|
||||
, m_numberOfLoanedBlocks(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void BumpSpace::init()
|
||||
{
|
||||
m_toSpace = &m_blocks1;
|
||||
m_fromSpace = &m_blocks2;
|
||||
|
||||
m_totalMemoryAllocated += s_blockSize * s_initialBlockNum;
|
||||
|
||||
if (!addNewBlock())
|
||||
CRASH();
|
||||
}
|
||||
|
||||
inline bool BumpSpace::contains(void* ptr, BumpBlock*& result)
|
||||
{
|
||||
BumpBlock* block = blockFor(ptr);
|
||||
result = block;
|
||||
return !m_toSpaceFilter.ruleOut(reinterpret_cast<Bits>(block)) && m_toSpaceSet.contains(block);
|
||||
}
|
||||
|
||||
inline void BumpSpace::pin(BumpBlock* block)
|
||||
{
|
||||
block->m_isPinned = true;
|
||||
}
|
||||
|
||||
inline void BumpSpace::startedCopying()
|
||||
{
|
||||
DoublyLinkedList<HeapBlock>* temp = m_fromSpace;
|
||||
m_fromSpace = m_toSpace;
|
||||
m_toSpace = temp;
|
||||
|
||||
m_toSpaceFilter.reset();
|
||||
|
||||
m_totalMemoryUtilized = 0;
|
||||
|
||||
ASSERT(!m_inCopyingPhase);
|
||||
ASSERT(!m_numberOfLoanedBlocks);
|
||||
m_inCopyingPhase = true;
|
||||
}
|
||||
|
||||
inline void BumpSpace::doneCopying()
|
||||
{
|
||||
{
|
||||
MutexLocker locker(m_loanedBlocksLock);
|
||||
while (m_numberOfLoanedBlocks > 0)
|
||||
m_loanedBlocksCondition.wait(m_loanedBlocksLock);
|
||||
}
|
||||
|
||||
ASSERT(m_inCopyingPhase);
|
||||
m_inCopyingPhase = false;
|
||||
while (!m_fromSpace->isEmpty()) {
|
||||
BumpBlock* block = static_cast<BumpBlock*>(m_fromSpace->removeHead());
|
||||
if (block->m_isPinned) {
|
||||
block->m_isPinned = false;
|
||||
m_toSpace->push(block);
|
||||
continue;
|
||||
}
|
||||
|
||||
m_toSpaceSet.remove(block);
|
||||
{
|
||||
MutexLocker locker(m_heap->m_freeBlockLock);
|
||||
m_heap->m_freeBlocks.push(block);
|
||||
m_heap->m_numberOfFreeBlocks++;
|
||||
}
|
||||
}
|
||||
|
||||
BumpBlock* curr = static_cast<BumpBlock*>(m_oversizeBlocks.head());
|
||||
while (curr) {
|
||||
BumpBlock* next = static_cast<BumpBlock*>(curr->next());
|
||||
if (!curr->m_isPinned) {
|
||||
m_oversizeBlocks.remove(curr);
|
||||
m_totalMemoryAllocated -= curr->m_allocation.size();
|
||||
m_totalMemoryUtilized -= curr->m_allocation.size() - sizeof(BumpBlock);
|
||||
curr->m_allocation.deallocate();
|
||||
} else
|
||||
curr->m_isPinned = false;
|
||||
curr = next;
|
||||
}
|
||||
|
||||
if (!(m_currentBlock = static_cast<BumpBlock*>(m_toSpace->head())))
|
||||
if (!addNewBlock())
|
||||
CRASH();
|
||||
}
|
||||
|
||||
inline void BumpSpace::doneFillingBlock(BumpBlock* block)
|
||||
{
|
||||
ASSERT(block);
|
||||
ASSERT(block->m_offset < reinterpret_cast<char*>(block) + s_blockSize);
|
||||
ASSERT(m_inCopyingPhase);
|
||||
|
||||
if (block->m_offset == block->m_payload) {
|
||||
recycleBlock(block);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
MutexLocker locker(m_toSpaceLock);
|
||||
m_toSpace->push(block);
|
||||
m_toSpaceSet.add(block);
|
||||
m_toSpaceFilter.add(reinterpret_cast<Bits>(block));
|
||||
}
|
||||
|
||||
{
|
||||
MutexLocker locker(m_memoryStatsLock);
|
||||
m_totalMemoryUtilized += static_cast<size_t>(static_cast<char*>(block->m_offset) - block->m_payload);
|
||||
}
|
||||
|
||||
{
|
||||
MutexLocker locker(m_loanedBlocksLock);
|
||||
ASSERT(m_numberOfLoanedBlocks > 0);
|
||||
m_numberOfLoanedBlocks--;
|
||||
if (!m_numberOfLoanedBlocks)
|
||||
m_loanedBlocksCondition.signal();
|
||||
}
|
||||
}
|
||||
|
||||
inline void BumpSpace::recycleBlock(BumpBlock* block)
|
||||
{
|
||||
{
|
||||
MutexLocker locker(m_heap->m_freeBlockLock);
|
||||
m_heap->m_freeBlocks.push(block);
|
||||
m_heap->m_numberOfFreeBlocks++;
|
||||
}
|
||||
|
||||
{
|
||||
MutexLocker locker(m_loanedBlocksLock);
|
||||
ASSERT(m_numberOfLoanedBlocks > 0);
|
||||
m_numberOfLoanedBlocks--;
|
||||
if (!m_numberOfLoanedBlocks)
|
||||
m_loanedBlocksCondition.signal();
|
||||
}
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::getFreshBlock(AllocationEffort allocationEffort, BumpBlock** outBlock)
|
||||
{
|
||||
HeapBlock* heapBlock = 0;
|
||||
BumpBlock* block = 0;
|
||||
{
|
||||
MutexLocker locker(m_heap->m_freeBlockLock);
|
||||
if (!m_heap->m_freeBlocks.isEmpty()) {
|
||||
heapBlock = m_heap->m_freeBlocks.removeHead();
|
||||
m_heap->m_numberOfFreeBlocks--;
|
||||
}
|
||||
}
|
||||
if (heapBlock)
|
||||
block = new (NotNull, heapBlock) BumpBlock(heapBlock->m_allocation);
|
||||
else if (allocationEffort == AllocationMustSucceed) {
|
||||
if (!allocateNewBlock(&block)) {
|
||||
*outBlock = 0;
|
||||
ASSERT_NOT_REACHED();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ASSERT(allocationEffort == AllocationCanFail);
|
||||
if (m_heap->waterMark() >= m_heap->highWaterMark() && m_heap->m_isSafeToCollect)
|
||||
m_heap->collect(Heap::DoNotSweep);
|
||||
|
||||
if (!getFreshBlock(AllocationMustSucceed, &block)) {
|
||||
*outBlock = 0;
|
||||
ASSERT_NOT_REACHED();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ASSERT(block);
|
||||
ASSERT(isPointerAligned(block->m_offset));
|
||||
*outBlock = block;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::borrowBlock(BumpBlock** outBlock)
|
||||
{
|
||||
BumpBlock* block = 0;
|
||||
if (!getFreshBlock(AllocationMustSucceed, &block)) {
|
||||
*outBlock = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT(m_inCopyingPhase);
|
||||
MutexLocker locker(m_loanedBlocksLock);
|
||||
m_numberOfLoanedBlocks++;
|
||||
|
||||
ASSERT(block->m_offset == block->m_payload);
|
||||
*outBlock = block;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::addNewBlock()
|
||||
{
|
||||
BumpBlock* block = 0;
|
||||
if (!getFreshBlock(AllocationCanFail, &block))
|
||||
return false;
|
||||
|
||||
m_toSpace->push(block);
|
||||
m_currentBlock = block;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::allocateNewBlock(BumpBlock** outBlock)
|
||||
{
|
||||
PageAllocationAligned allocation = PageAllocationAligned::allocate(s_blockSize, s_blockSize, OSAllocator::JSGCHeapPages);
|
||||
if (!static_cast<bool>(allocation)) {
|
||||
*outBlock = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
MutexLocker locker(m_memoryStatsLock);
|
||||
m_totalMemoryAllocated += s_blockSize;
|
||||
}
|
||||
|
||||
*outBlock = new (NotNull, allocation.base()) BumpBlock(allocation);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool BumpSpace::fitsInBlock(BumpBlock* block, size_t bytes)
|
||||
{
|
||||
return static_cast<char*>(block->m_offset) + bytes < reinterpret_cast<char*>(block) + s_blockSize && static_cast<char*>(block->m_offset) + bytes > block->m_offset;
|
||||
}
|
||||
|
||||
inline bool BumpSpace::fitsInCurrentBlock(size_t bytes)
|
||||
{
|
||||
return fitsInBlock(m_currentBlock, bytes);
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::tryAllocate(size_t bytes, void** outPtr)
|
||||
{
|
||||
ASSERT(!m_heap->globalData()->isInitializingObject());
|
||||
|
||||
if (isOversize(bytes) || !fitsInCurrentBlock(bytes))
|
||||
return tryAllocateSlowCase(bytes, outPtr);
|
||||
|
||||
*outPtr = allocateFromBlock(m_currentBlock, bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::tryAllocateOversize(size_t bytes, void** outPtr)
|
||||
{
|
||||
ASSERT(isOversize(bytes));
|
||||
|
||||
size_t blockSize = WTF::roundUpToMultipleOf<s_pageSize>(sizeof(BumpBlock) + bytes);
|
||||
PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, s_pageSize, OSAllocator::JSGCHeapPages);
|
||||
if (!static_cast<bool>(allocation)) {
|
||||
*outPtr = 0;
|
||||
return false;
|
||||
}
|
||||
BumpBlock* block = new (NotNull, allocation.base()) BumpBlock(allocation);
|
||||
m_oversizeBlocks.push(block);
|
||||
ASSERT(isPointerAligned(block->m_offset));
|
||||
|
||||
m_oversizeFilter.add(reinterpret_cast<Bits>(block));
|
||||
|
||||
m_totalMemoryAllocated += blockSize;
|
||||
m_totalMemoryUtilized += bytes;
|
||||
|
||||
*outPtr = block->m_offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void* BumpSpace::allocateFromBlock(BumpBlock* block, size_t bytes)
|
||||
{
|
||||
ASSERT(!isOversize(bytes));
|
||||
ASSERT(fitsInBlock(block, bytes));
|
||||
ASSERT(isPointerAligned(block->m_offset));
|
||||
|
||||
void* ptr = block->m_offset;
|
||||
ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + s_blockSize);
|
||||
block->m_offset = static_cast<void*>((static_cast<char*>(ptr) + bytes));
|
||||
ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + s_blockSize);
|
||||
|
||||
ASSERT(isPointerAligned(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::tryReallocate(void** ptr, size_t oldSize, size_t newSize)
|
||||
{
|
||||
if (oldSize >= newSize)
|
||||
return true;
|
||||
|
||||
void* oldPtr = *ptr;
|
||||
ASSERT(!m_heap->globalData()->isInitializingObject());
|
||||
|
||||
if (isOversize(oldSize) || isOversize(newSize))
|
||||
return tryReallocateOversize(ptr, oldSize, newSize);
|
||||
|
||||
if (static_cast<char*>(oldPtr) + oldSize == m_currentBlock->m_offset && oldPtr > m_currentBlock && oldPtr < reinterpret_cast<char*>(m_currentBlock) + s_blockSize) {
|
||||
m_currentBlock->m_offset = oldPtr;
|
||||
if (fitsInCurrentBlock(newSize)) {
|
||||
m_totalMemoryUtilized += newSize - oldSize;
|
||||
return allocateFromBlock(m_currentBlock, newSize);
|
||||
}
|
||||
}
|
||||
m_totalMemoryUtilized -= oldSize;
|
||||
|
||||
void* result = 0;
|
||||
if (!tryAllocate(newSize, &result)) {
|
||||
*ptr = 0;
|
||||
return false;
|
||||
}
|
||||
memcpy(result, oldPtr, oldSize);
|
||||
*ptr = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline CheckedBoolean BumpSpace::tryReallocateOversize(void** ptr, size_t oldSize, size_t newSize)
|
||||
{
|
||||
ASSERT(isOversize(oldSize) || isOversize(newSize));
|
||||
ASSERT(newSize > oldSize);
|
||||
|
||||
void* oldPtr = *ptr;
|
||||
|
||||
void* newPtr = 0;
|
||||
if (!tryAllocateOversize(newSize, &newPtr)) {
|
||||
*ptr = 0;
|
||||
return false;
|
||||
}
|
||||
memcpy(newPtr, oldPtr, oldSize);
|
||||
|
||||
if (isOversize(oldSize)) {
|
||||
BumpBlock* oldBlock = oversizeBlockFor(oldPtr);
|
||||
m_oversizeBlocks.remove(oldBlock);
|
||||
oldBlock->m_allocation.deallocate();
|
||||
m_totalMemoryAllocated -= oldSize + sizeof(BumpBlock);
|
||||
}
|
||||
|
||||
m_totalMemoryUtilized -= oldSize;
|
||||
|
||||
*ptr = newPtr;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool BumpSpace::isOversize(size_t bytes)
|
||||
{
|
||||
return bytes > s_maxAllocationSize;
|
||||
}
|
||||
|
||||
inline bool BumpSpace::isPinned(void* ptr)
|
||||
{
|
||||
return blockFor(ptr)->m_isPinned;
|
||||
}
|
||||
|
||||
inline BumpBlock* BumpSpace::oversizeBlockFor(void* ptr)
|
||||
{
|
||||
return reinterpret_cast<BumpBlock*>(reinterpret_cast<size_t>(ptr) & s_pageMask);
|
||||
}
|
||||
|
||||
inline BumpBlock* BumpSpace::blockFor(void* ptr)
|
||||
{
|
||||
return reinterpret_cast<BumpBlock*>(reinterpret_cast<size_t>(ptr) & s_blockMask);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef ByteArray_h
|
||||
#define ByteArray_h
|
||||
|
||||
#include <limits.h>
|
||||
#include <wtf/PassRefPtr.h>
|
||||
#include <wtf/Platform.h>
|
||||
#include <wtf/RefCounted.h>
|
||||
#include <wtf/StdLibExtras.h>
|
||||
|
||||
namespace WTF {
|
||||
class ByteArray : public RefCountedBase {
|
||||
public:
|
||||
unsigned length() const { return m_size; }
|
||||
|
||||
void set(unsigned index, double value)
|
||||
{
|
||||
if (index >= m_size)
|
||||
return;
|
||||
if (!(value > 0)) // Clamp NaN to 0
|
||||
value = 0;
|
||||
else if (value > 255)
|
||||
value = 255;
|
||||
m_data[index] = static_cast<unsigned char>(value + 0.5);
|
||||
}
|
||||
|
||||
void set(unsigned index, unsigned char value)
|
||||
{
|
||||
if (index >= m_size)
|
||||
return;
|
||||
m_data[index] = value;
|
||||
}
|
||||
|
||||
bool get(unsigned index, unsigned char& result) const
|
||||
{
|
||||
if (index >= m_size)
|
||||
return false;
|
||||
result = m_data[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char get(unsigned index) const
|
||||
{
|
||||
ASSERT(index < m_size);
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
unsigned char* data() { return m_data; }
|
||||
|
||||
void clear() { memset(m_data, 0, m_size); }
|
||||
|
||||
void deref()
|
||||
{
|
||||
if (derefBase()) {
|
||||
// We allocated with new unsigned char[] in create(),
|
||||
// and then used placement new to construct the object.
|
||||
this->~ByteArray();
|
||||
delete[] reinterpret_cast<unsigned char*>(this);
|
||||
}
|
||||
}
|
||||
|
||||
WTF_EXPORT_PRIVATE static PassRefPtr<ByteArray> create(size_t size);
|
||||
|
||||
static size_t offsetOfSize() { return OBJECT_OFFSETOF(ByteArray, m_size); }
|
||||
static size_t offsetOfData() { return OBJECT_OFFSETOF(ByteArray, m_data); }
|
||||
|
||||
private:
|
||||
ByteArray(size_t size)
|
||||
: m_size(size)
|
||||
{
|
||||
}
|
||||
size_t m_size;
|
||||
// MSVC can't handle correctly unsized array.
|
||||
// warning C4200: nonstandard extension used : zero-sized array in struct/union
|
||||
// Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
|
||||
#if (COMPILER(MSVC) || COMPILER(SUNCC)) && !COMPILER(INTEL)
|
||||
unsigned char m_data[INT_MAX];
|
||||
#else
|
||||
unsigned char m_data[];
|
||||
#endif
|
||||
};
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::ByteArray;
|
||||
|
||||
#endif
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003, 2006, 2008, 2009, 2010 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef CString_h
|
||||
#define CString_h
|
||||
|
||||
#include "PassRefPtr.h"
|
||||
#include "RefCounted.h"
|
||||
#include "Vector.h"
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class CStringBuffer : public RefCounted<CStringBuffer> {
|
||||
public:
|
||||
const char* data() { return m_vector.data(); }
|
||||
size_t length() { return m_vector.size(); }
|
||||
|
||||
private:
|
||||
friend class CString;
|
||||
|
||||
static PassRefPtr<CStringBuffer> create(size_t length) { return adoptRef(new CStringBuffer(length)); }
|
||||
CStringBuffer(size_t length) : m_vector(length) { }
|
||||
char* mutableData() { return m_vector.data(); }
|
||||
|
||||
Vector<char> m_vector;
|
||||
};
|
||||
|
||||
// A container for a null-terminated char array supporting copy-on-write
|
||||
// assignment. The contained char array may be null.
|
||||
class CString {
|
||||
public:
|
||||
CString() { }
|
||||
WTF_EXPORT_PRIVATE CString(const char*);
|
||||
WTF_EXPORT_PRIVATE CString(const char*, size_t length);
|
||||
CString(CStringBuffer* buffer) : m_buffer(buffer) { }
|
||||
WTF_EXPORT_PRIVATE static CString newUninitialized(size_t length, char*& characterBuffer);
|
||||
|
||||
const char* data() const
|
||||
{
|
||||
return m_buffer ? m_buffer->data() : 0;
|
||||
}
|
||||
WTF_EXPORT_PRIVATE char* mutableData();
|
||||
size_t length() const
|
||||
{
|
||||
return m_buffer ? m_buffer->length() - 1 : 0;
|
||||
}
|
||||
|
||||
bool isNull() const { return !m_buffer; }
|
||||
|
||||
CStringBuffer* buffer() const { return m_buffer.get(); }
|
||||
|
||||
private:
|
||||
void copyBufferIfNeeded();
|
||||
void init(const char*, size_t length);
|
||||
RefPtr<CStringBuffer> m_buffer;
|
||||
};
|
||||
|
||||
WTF_EXPORT_PRIVATE bool operator==(const CString& a, const CString& b);
|
||||
inline bool operator!=(const CString& a, const CString& b) { return !(a == b); }
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::CString;
|
||||
|
||||
#endif // CString_h
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef CachedTranscendentalFunction_h
|
||||
#define CachedTranscendentalFunction_h
|
||||
|
||||
#include "JSValue.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
typedef double (*TranscendentalFunctionPtr)(double);
|
||||
|
||||
// CachedTranscendentalFunction provides a generic mechanism to cache results
|
||||
// for pure functions with the signature "double func(double)", and where NaN
|
||||
// maps to NaN.
|
||||
template<TranscendentalFunctionPtr orignalFunction>
|
||||
class CachedTranscendentalFunction {
|
||||
struct CacheEntry {
|
||||
double operand;
|
||||
double result;
|
||||
};
|
||||
|
||||
public:
|
||||
CachedTranscendentalFunction()
|
||||
: m_cache(0)
|
||||
{
|
||||
}
|
||||
|
||||
~CachedTranscendentalFunction()
|
||||
{
|
||||
if (m_cache)
|
||||
fastFree(m_cache);
|
||||
}
|
||||
|
||||
JSValue operator() (double operand)
|
||||
{
|
||||
if (UNLIKELY(!m_cache))
|
||||
initialize();
|
||||
CacheEntry* entry = &m_cache[hash(operand)];
|
||||
|
||||
if (entry->operand == operand)
|
||||
return jsDoubleNumber(entry->result);
|
||||
double result = orignalFunction(operand);
|
||||
entry->operand = operand;
|
||||
entry->result = result;
|
||||
return jsDoubleNumber(result);
|
||||
}
|
||||
|
||||
private:
|
||||
void initialize()
|
||||
{
|
||||
// Lazily allocate the table, populate with NaN->NaN mapping.
|
||||
m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry)));
|
||||
for (unsigned x = 0; x < s_cacheSize; ++x) {
|
||||
m_cache[x].operand = std::numeric_limits<double>::quiet_NaN();
|
||||
m_cache[x].result = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned hash(double d)
|
||||
{
|
||||
union doubleAndUInt64 {
|
||||
double d;
|
||||
uint32_t is[2];
|
||||
} u;
|
||||
u.d = d;
|
||||
|
||||
unsigned x = u.is[0] ^ u.is[1];
|
||||
x = (x >> 20) ^ (x >> 8);
|
||||
return x & (s_cacheSize - 1);
|
||||
}
|
||||
|
||||
static const unsigned s_cacheSize = 0x1000;
|
||||
CacheEntry* m_cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CachedTranscendentalFunction_h
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef CallData_h
|
||||
#define CallData_h
|
||||
|
||||
#include "JSValue.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ArgList;
|
||||
class ExecState;
|
||||
class FunctionExecutable;
|
||||
class JSObject;
|
||||
class ScopeChainNode;
|
||||
|
||||
enum CallType {
|
||||
CallTypeNone,
|
||||
CallTypeHost,
|
||||
CallTypeJS
|
||||
};
|
||||
|
||||
typedef EncodedJSValue (JSC_HOST_CALL *NativeFunction)(ExecState*);
|
||||
|
||||
union CallData {
|
||||
struct {
|
||||
NativeFunction function;
|
||||
} native;
|
||||
struct {
|
||||
FunctionExecutable* functionExecutable;
|
||||
ScopeChainNode* scopeChain;
|
||||
} js;
|
||||
};
|
||||
|
||||
JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CallData_h
|
||||
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
|
||||
* Copyright (C) 2003, 2007, 2008, 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CallFrame_h
|
||||
#define CallFrame_h
|
||||
|
||||
#include "JSGlobalData.h"
|
||||
#include "MacroAssemblerCodeRef.h"
|
||||
#include "RegisterFile.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class Arguments;
|
||||
class JSActivation;
|
||||
class Interpreter;
|
||||
class ScopeChainNode;
|
||||
|
||||
// Represents the current state of script execution.
|
||||
// Passed as the first argument to most functions.
|
||||
class ExecState : private Register {
|
||||
public:
|
||||
JSValue calleeAsValue() const { return this[RegisterFile::Callee].jsValue(); }
|
||||
JSObject* callee() const { return this[RegisterFile::Callee].function(); }
|
||||
CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
|
||||
ScopeChainNode* scopeChain() const
|
||||
{
|
||||
ASSERT(this[RegisterFile::ScopeChain].Register::scopeChain());
|
||||
return this[RegisterFile::ScopeChain].Register::scopeChain();
|
||||
}
|
||||
|
||||
// Global object in which execution began.
|
||||
JSGlobalObject* dynamicGlobalObject();
|
||||
|
||||
// Global object in which the currently executing code was defined.
|
||||
// Differs from dynamicGlobalObject() during function calls across web browser frames.
|
||||
inline JSGlobalObject* lexicalGlobalObject() const;
|
||||
|
||||
// Differs from lexicalGlobalObject because this will have DOM window shell rather than
|
||||
// the actual DOM window, which can't be "this" for security reasons.
|
||||
inline JSObject* globalThisValue() const;
|
||||
|
||||
inline JSGlobalData& globalData() const;
|
||||
|
||||
// Convenience functions for access to global data.
|
||||
// It takes a few memory references to get from a call frame to the global data
|
||||
// pointer, so these are inefficient, and should be used sparingly in new code.
|
||||
// But they're used in many places in legacy code, so they're not going away any time soon.
|
||||
|
||||
void clearException() { globalData().exception = JSValue(); }
|
||||
JSValue exception() const { return globalData().exception; }
|
||||
bool hadException() const { return globalData().exception; }
|
||||
|
||||
const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
|
||||
const MarkedArgumentBuffer& emptyList() const { return *globalData().emptyList; }
|
||||
Interpreter* interpreter() { return globalData().interpreter; }
|
||||
Heap* heap() { return &globalData().heap; }
|
||||
#ifndef NDEBUG
|
||||
void dumpCaller();
|
||||
#endif
|
||||
static const HashTable* arrayConstructorTable(CallFrame* callFrame) { return callFrame->globalData().arrayConstructorTable; }
|
||||
static const HashTable* arrayPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().arrayPrototypeTable; }
|
||||
static const HashTable* booleanPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().booleanPrototypeTable; }
|
||||
static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; }
|
||||
static const HashTable* dateConstructorTable(CallFrame* callFrame) { return callFrame->globalData().dateConstructorTable; }
|
||||
static const HashTable* errorPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().errorPrototypeTable; }
|
||||
static const HashTable* globalObjectTable(CallFrame* callFrame) { return callFrame->globalData().globalObjectTable; }
|
||||
static const HashTable* jsonTable(CallFrame* callFrame) { return callFrame->globalData().jsonTable; }
|
||||
static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
|
||||
static const HashTable* numberConstructorTable(CallFrame* callFrame) { return callFrame->globalData().numberConstructorTable; }
|
||||
static const HashTable* numberPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().numberPrototypeTable; }
|
||||
static const HashTable* objectConstructorTable(CallFrame* callFrame) { return callFrame->globalData().objectConstructorTable; }
|
||||
static const HashTable* objectPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().objectPrototypeTable; }
|
||||
static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
|
||||
static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
|
||||
static const HashTable* regExpPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().regExpPrototypeTable; }
|
||||
static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
|
||||
static const HashTable* stringConstructorTable(CallFrame* callFrame) { return callFrame->globalData().stringConstructorTable; }
|
||||
|
||||
static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
|
||||
Register* registers() { return this; }
|
||||
|
||||
CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
|
||||
|
||||
CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
|
||||
#if ENABLE(JIT)
|
||||
ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
|
||||
#endif
|
||||
#if ENABLE(DFG_JIT)
|
||||
InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); }
|
||||
#else
|
||||
// This will never be called if !ENABLE(DFG_JIT) since all calls should be guarded by
|
||||
// isInlineCallFrame(). But to make it easier to write code without having a bunch of
|
||||
// #if's, we make a dummy implementation available anyway.
|
||||
InlineCallFrame* inlineCallFrame() const
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if ENABLE(INTERPRETER)
|
||||
Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
|
||||
#endif
|
||||
|
||||
void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
|
||||
void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
|
||||
|
||||
ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain,
|
||||
CallFrame* callerFrame, int argc, JSObject* callee)
|
||||
{
|
||||
ASSERT(callerFrame); // Use noCaller() rather than 0 for the outer host call frame caller.
|
||||
ASSERT(callerFrame == noCaller() || callerFrame->removeHostCallFrameFlag()->registerFile()->end() >= this);
|
||||
|
||||
setCodeBlock(codeBlock);
|
||||
setScopeChain(scopeChain);
|
||||
setCallerFrame(callerFrame);
|
||||
setReturnPC(vPC); // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
|
||||
setArgumentCountIncludingThis(argc); // original argument count (for the sake of the "arguments" object)
|
||||
setCallee(callee);
|
||||
}
|
||||
|
||||
// Read a register from the codeframe (or constant from the CodeBlock).
|
||||
inline Register& r(int);
|
||||
// Read a register for a non-constant
|
||||
inline Register& uncheckedR(int);
|
||||
|
||||
// Access to arguments.
|
||||
size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
|
||||
size_t argumentCountIncludingThis() const { return this[RegisterFile::ArgumentCount].payload(); }
|
||||
static int argumentOffset(size_t argument) { return s_firstArgumentOffset - argument; }
|
||||
static int argumentOffsetIncludingThis(size_t argument) { return s_thisArgumentOffset - argument; }
|
||||
|
||||
JSValue argument(size_t argument)
|
||||
{
|
||||
if (argument >= argumentCount())
|
||||
return jsUndefined();
|
||||
return this[argumentOffset(argument)].jsValue();
|
||||
}
|
||||
void setArgument(size_t argument, JSValue value)
|
||||
{
|
||||
this[argumentOffset(argument)] = value;
|
||||
}
|
||||
|
||||
static int thisArgumentOffset() { return argumentOffsetIncludingThis(0); }
|
||||
JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
|
||||
void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
|
||||
|
||||
static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize; }
|
||||
|
||||
// FIXME: Remove these.
|
||||
int hostThisRegister() { return thisArgumentOffset(); }
|
||||
JSValue hostThisValue() { return thisValue(); }
|
||||
|
||||
static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); }
|
||||
|
||||
bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; }
|
||||
CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); }
|
||||
CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); }
|
||||
|
||||
void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount].payload() = count; }
|
||||
void setCallee(JSObject* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = Register::withCallee(callee); }
|
||||
void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; }
|
||||
void setReturnPC(void* value) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = (Instruction*)value; }
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
bool isInlineCallFrame();
|
||||
|
||||
void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = inlineCallFrame; }
|
||||
|
||||
// Call this to get the semantically correct JS CallFrame*. This resolves issues
|
||||
// surrounding inlining and the HostCallFrameFlag stuff.
|
||||
CallFrame* trueCallerFrame();
|
||||
#else
|
||||
bool isInlineCallFrame() { return false; }
|
||||
|
||||
CallFrame* trueCallerFrame() { return callerFrame()->removeHostCallFrameFlag(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
static const intptr_t HostCallFrameFlag = 1;
|
||||
static const int s_thisArgumentOffset = -1 - RegisterFile::CallFrameHeaderSize;
|
||||
static const int s_firstArgumentOffset = s_thisArgumentOffset - 1;
|
||||
|
||||
#ifndef NDEBUG
|
||||
RegisterFile* registerFile();
|
||||
#endif
|
||||
#if ENABLE(DFG_JIT)
|
||||
bool isInlineCallFrameSlow();
|
||||
#endif
|
||||
ExecState();
|
||||
~ExecState();
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CallFrame_h
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CallIdentifier_h
|
||||
#define CallIdentifier_h
|
||||
|
||||
#include <runtime/UString.h>
|
||||
#include <wtf/text/CString.h>
|
||||
#include <wtf/text/StringHash.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
struct CallIdentifier {
|
||||
WTF_MAKE_FAST_ALLOCATED;
|
||||
public:
|
||||
UString m_name;
|
||||
UString m_url;
|
||||
unsigned m_lineNumber;
|
||||
|
||||
CallIdentifier()
|
||||
: m_lineNumber(0)
|
||||
{
|
||||
}
|
||||
|
||||
CallIdentifier(const UString& name, const UString& url, int lineNumber)
|
||||
: m_name(name)
|
||||
, m_url(!url.isNull() ? url : "")
|
||||
, m_lineNumber(lineNumber)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool operator==(const CallIdentifier& ci) const { return ci.m_lineNumber == m_lineNumber && ci.m_name == m_name && ci.m_url == m_url; }
|
||||
inline bool operator!=(const CallIdentifier& ci) const { return !(*this == ci); }
|
||||
|
||||
struct Hash {
|
||||
static unsigned hash(const CallIdentifier& key)
|
||||
{
|
||||
unsigned hashCodes[3] = {
|
||||
key.m_name.impl()->hash(),
|
||||
key.m_url.impl()->hash(),
|
||||
key.m_lineNumber
|
||||
};
|
||||
return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
|
||||
}
|
||||
|
||||
static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
|
||||
static const bool safeToCompareToEmptyOrDeleted = true;
|
||||
};
|
||||
|
||||
unsigned hash() const { return Hash::hash(*this); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
operator const char*() const { return c_str(); }
|
||||
const char* c_str() const { return m_name.utf8().data(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
namespace WTF {
|
||||
|
||||
template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifier::Hash Hash; };
|
||||
|
||||
template<> struct HashTraits<JSC::CallIdentifier> : GenericHashTraits<JSC::CallIdentifier> {
|
||||
static void constructDeletedValue(JSC::CallIdentifier& slot)
|
||||
{
|
||||
new (NotNull, &slot) JSC::CallIdentifier(JSC::UString(), JSC::UString(), std::numeric_limits<unsigned>::max());
|
||||
}
|
||||
static bool isDeletedValue(const JSC::CallIdentifier& value)
|
||||
{
|
||||
return value.m_name.isNull() && value.m_url.isNull() && value.m_lineNumber == std::numeric_limits<unsigned>::max();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
#endif // CallIdentifier_h
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef CallLinkInfo_h
|
||||
#define CallLinkInfo_h
|
||||
|
||||
#include "CodeLocation.h"
|
||||
#include "JITWriteBarrier.h"
|
||||
#include "JSFunction.h"
|
||||
#include "Opcode.h"
|
||||
#include "WriteBarrier.h"
|
||||
#include <wtf/Platform.h>
|
||||
#include <wtf/SentinelLinkedList.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
#if ENABLE(JIT)
|
||||
|
||||
class RepatchBuffer;
|
||||
|
||||
struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
|
||||
enum CallType { None, Call, CallVarargs, Construct };
|
||||
static CallType callTypeFor(OpcodeID opcodeID)
|
||||
{
|
||||
if (opcodeID == op_call || opcodeID == op_call_eval)
|
||||
return Call;
|
||||
if (opcodeID == op_construct)
|
||||
return Construct;
|
||||
ASSERT(opcodeID == op_call_varargs);
|
||||
return CallVarargs;
|
||||
}
|
||||
|
||||
CallLinkInfo()
|
||||
: hasSeenShouldRepatch(false)
|
||||
, isDFG(false)
|
||||
, callType(None)
|
||||
{
|
||||
}
|
||||
|
||||
~CallLinkInfo()
|
||||
{
|
||||
if (isOnList())
|
||||
remove();
|
||||
}
|
||||
|
||||
CodeLocationLabel callReturnLocation; // it's a near call in the old JIT, or a normal call in DFG
|
||||
CodeLocationDataLabelPtr hotPathBegin;
|
||||
CodeLocationNearCall hotPathOther;
|
||||
JITWriteBarrier<JSFunction> callee;
|
||||
WriteBarrier<JSFunction> lastSeenCallee;
|
||||
bool hasSeenShouldRepatch : 1;
|
||||
bool isDFG : 1;
|
||||
CallType callType : 2;
|
||||
unsigned bytecodeIndex;
|
||||
|
||||
bool isLinked() { return callee; }
|
||||
void unlink(JSGlobalData&, RepatchBuffer&);
|
||||
|
||||
bool seenOnce()
|
||||
{
|
||||
return hasSeenShouldRepatch;
|
||||
}
|
||||
|
||||
void setSeen()
|
||||
{
|
||||
hasSeenShouldRepatch = true;
|
||||
}
|
||||
};
|
||||
|
||||
inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
|
||||
{
|
||||
return callLinkInfo->callReturnLocation.executableAddress();
|
||||
}
|
||||
|
||||
inline unsigned getCallLinkInfoBytecodeIndex(CallLinkInfo* callLinkInfo)
|
||||
{
|
||||
return callLinkInfo->bytecodeIndex;
|
||||
}
|
||||
#endif // ENABLE(JIT)
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CallLinkInfo_h
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef CallLinkStatus_h
|
||||
#define CallLinkStatus_h
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class JSFunction;
|
||||
class CodeBlock;
|
||||
|
||||
class CallLinkStatus {
|
||||
public:
|
||||
CallLinkStatus()
|
||||
: m_callTarget(0)
|
||||
, m_couldTakeSlowPath(false)
|
||||
{
|
||||
}
|
||||
|
||||
CallLinkStatus(JSFunction* callTarget, bool couldTakeSlowPath)
|
||||
: m_callTarget(callTarget)
|
||||
, m_couldTakeSlowPath(couldTakeSlowPath)
|
||||
{
|
||||
}
|
||||
|
||||
static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
|
||||
|
||||
bool isSet() const { return !!m_callTarget; }
|
||||
|
||||
bool operator!() const { return !m_callTarget; }
|
||||
|
||||
bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
|
||||
|
||||
JSFunction* callTarget() const { return m_callTarget; }
|
||||
|
||||
private:
|
||||
JSFunction* m_callTarget;
|
||||
bool m_couldTakeSlowPath;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CallLinkStatus_h
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef CallReturnOffsetToBytecodeOffset_h
|
||||
#define CallReturnOffsetToBytecodeOffset_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
#if ENABLE(JIT)
|
||||
// This structure is used to map from a call return location
|
||||
// (given as an offset in bytes into the JIT code) back to
|
||||
// the bytecode index of the corresponding bytecode operation.
|
||||
// This is then used to look up the corresponding handler.
|
||||
// FIXME: This should be made inlining aware! Currently it isn't
|
||||
// because we never inline code that has exception handlers.
|
||||
struct CallReturnOffsetToBytecodeOffset {
|
||||
CallReturnOffsetToBytecodeOffset(unsigned callReturnOffset, unsigned bytecodeOffset)
|
||||
: callReturnOffset(callReturnOffset)
|
||||
, bytecodeOffset(bytecodeOffset)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned callReturnOffset;
|
||||
unsigned bytecodeOffset;
|
||||
};
|
||||
|
||||
inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeOffset* pc)
|
||||
{
|
||||
return pc->callReturnOffset;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CallReturnOffsetToBytecodeOffset_h
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef CardSet_h
|
||||
#define CardSet_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wtf/Assertions.h>
|
||||
#include <wtf/Noncopyable.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
template <size_t cardSize, size_t blockSize> class CardSet {
|
||||
WTF_MAKE_NONCOPYABLE(CardSet);
|
||||
|
||||
public:
|
||||
static const size_t cardCount = (blockSize + cardSize - 1) / cardSize;
|
||||
|
||||
CardSet()
|
||||
{
|
||||
memset(m_cards, 0, cardCount);
|
||||
}
|
||||
|
||||
bool isCardMarkedForAtom(const void*);
|
||||
void markCardForAtom(const void*);
|
||||
uint8_t& cardForAtom(const void*);
|
||||
bool isCardMarked(size_t);
|
||||
bool testAndClear(size_t);
|
||||
|
||||
private:
|
||||
uint8_t m_cards[cardCount];
|
||||
COMPILE_ASSERT(!(cardSize & (cardSize - 1)), cardSet_cardSize_is_power_of_two);
|
||||
COMPILE_ASSERT(!(cardCount & (cardCount - 1)), cardSet_cardCount_is_power_of_two);
|
||||
};
|
||||
|
||||
template <size_t cardSize, size_t blockSize> uint8_t& CardSet<cardSize, blockSize>::cardForAtom(const void* ptr)
|
||||
{
|
||||
ASSERT(ptr > this && ptr < (reinterpret_cast<char*>(this) + cardCount * cardSize));
|
||||
uintptr_t card = (reinterpret_cast<uintptr_t>(ptr) / cardSize) % cardCount;
|
||||
return m_cards[card];
|
||||
}
|
||||
|
||||
template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::isCardMarkedForAtom(const void* ptr)
|
||||
{
|
||||
return cardForAtom(ptr);
|
||||
}
|
||||
|
||||
template <size_t cardSize, size_t blockSize> void CardSet<cardSize, blockSize>::markCardForAtom(const void* ptr)
|
||||
{
|
||||
cardForAtom(ptr) = 1;
|
||||
}
|
||||
|
||||
template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::isCardMarked(size_t i)
|
||||
{
|
||||
ASSERT(i < cardCount);
|
||||
return m_cards[i];
|
||||
}
|
||||
|
||||
template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::testAndClear(size_t i)
|
||||
{
|
||||
ASSERT(i < cardCount);
|
||||
bool result = m_cards[i];
|
||||
m_cards[i] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007, 2009, 2010 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef CharacterNames_h
|
||||
#define CharacterNames_h
|
||||
|
||||
#include "Unicode.h"
|
||||
|
||||
namespace WTF {
|
||||
namespace Unicode {
|
||||
|
||||
// Names here are taken from the Unicode standard.
|
||||
|
||||
// Most of these are UChar constants, not UChar32, which makes them
|
||||
// more convenient for WebCore code that mostly uses UTF-16.
|
||||
|
||||
const UChar32 aegeanWordSeparatorLine = 0x10100;
|
||||
const UChar32 aegeanWordSeparatorDot = 0x10101;
|
||||
const UChar blackCircle = 0x25CF;
|
||||
const UChar blackSquare = 0x25A0;
|
||||
const UChar blackUpPointingTriangle = 0x25B2;
|
||||
const UChar bullet = 0x2022;
|
||||
const UChar bullseye = 0x25CE;
|
||||
const UChar carriageReturn = 0x000D;
|
||||
const UChar ethiopicPrefaceColon = 0x1366;
|
||||
const UChar ethiopicWordspace = 0x1361;
|
||||
const UChar fisheye = 0x25C9;
|
||||
const UChar hebrewPunctuationGeresh = 0x05F3;
|
||||
const UChar hebrewPunctuationGershayim = 0x05F4;
|
||||
const UChar horizontalEllipsis = 0x2026;
|
||||
const UChar hyphen = 0x2010;
|
||||
const UChar hyphenMinus = 0x002D;
|
||||
const UChar ideographicComma = 0x3001;
|
||||
const UChar ideographicFullStop = 0x3002;
|
||||
const UChar ideographicSpace = 0x3000;
|
||||
const UChar leftDoubleQuotationMark = 0x201C;
|
||||
const UChar leftSingleQuotationMark = 0x2018;
|
||||
const UChar leftToRightEmbed = 0x202A;
|
||||
const UChar leftToRightMark = 0x200E;
|
||||
const UChar leftToRightOverride = 0x202D;
|
||||
const UChar minusSign = 0x2212;
|
||||
const UChar newlineCharacter = 0x000A;
|
||||
const UChar noBreakSpace = 0x00A0;
|
||||
const UChar objectReplacementCharacter = 0xFFFC;
|
||||
const UChar popDirectionalFormatting = 0x202C;
|
||||
const UChar replacementCharacter = 0xFFFD;
|
||||
const UChar rightDoubleQuotationMark = 0x201D;
|
||||
const UChar rightSingleQuotationMark = 0x2019;
|
||||
const UChar rightToLeftEmbed = 0x202B;
|
||||
const UChar rightToLeftMark = 0x200F;
|
||||
const UChar rightToLeftOverride = 0x202E;
|
||||
const UChar sesameDot = 0xFE45;
|
||||
const UChar softHyphen = 0x00AD;
|
||||
const UChar space = 0x0020;
|
||||
const UChar tibetanMarkIntersyllabicTsheg = 0x0F0B;
|
||||
const UChar tibetanMarkDelimiterTshegBstar = 0x0F0C;
|
||||
const UChar32 ugariticWordDivider = 0x1039F;
|
||||
const UChar whiteBullet = 0x25E6;
|
||||
const UChar whiteCircle = 0x25CB;
|
||||
const UChar whiteSesameDot = 0xFE46;
|
||||
const UChar whiteUpPointingTriangle = 0x25B3;
|
||||
const UChar yenSign = 0x00A5;
|
||||
const UChar zeroWidthJoiner = 0x200D;
|
||||
const UChar zeroWidthNonJoiner = 0x200C;
|
||||
const UChar zeroWidthSpace = 0x200B;
|
||||
const UChar zeroWidthNoBreakSpace = 0xFEFF;
|
||||
|
||||
} // namespace Unicode
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::Unicode::aegeanWordSeparatorLine;
|
||||
using WTF::Unicode::aegeanWordSeparatorDot;
|
||||
using WTF::Unicode::blackCircle;
|
||||
using WTF::Unicode::blackSquare;
|
||||
using WTF::Unicode::blackUpPointingTriangle;
|
||||
using WTF::Unicode::bullet;
|
||||
using WTF::Unicode::bullseye;
|
||||
using WTF::Unicode::carriageReturn;
|
||||
using WTF::Unicode::ethiopicPrefaceColon;
|
||||
using WTF::Unicode::ethiopicWordspace;
|
||||
using WTF::Unicode::fisheye;
|
||||
using WTF::Unicode::hebrewPunctuationGeresh;
|
||||
using WTF::Unicode::hebrewPunctuationGershayim;
|
||||
using WTF::Unicode::horizontalEllipsis;
|
||||
using WTF::Unicode::hyphen;
|
||||
using WTF::Unicode::hyphenMinus;
|
||||
using WTF::Unicode::ideographicComma;
|
||||
using WTF::Unicode::ideographicFullStop;
|
||||
using WTF::Unicode::ideographicSpace;
|
||||
using WTF::Unicode::leftDoubleQuotationMark;
|
||||
using WTF::Unicode::leftSingleQuotationMark;
|
||||
using WTF::Unicode::leftToRightEmbed;
|
||||
using WTF::Unicode::leftToRightMark;
|
||||
using WTF::Unicode::leftToRightOverride;
|
||||
using WTF::Unicode::minusSign;
|
||||
using WTF::Unicode::newlineCharacter;
|
||||
using WTF::Unicode::noBreakSpace;
|
||||
using WTF::Unicode::objectReplacementCharacter;
|
||||
using WTF::Unicode::popDirectionalFormatting;
|
||||
using WTF::Unicode::replacementCharacter;
|
||||
using WTF::Unicode::rightDoubleQuotationMark;
|
||||
using WTF::Unicode::rightSingleQuotationMark;
|
||||
using WTF::Unicode::rightToLeftEmbed;
|
||||
using WTF::Unicode::rightToLeftMark;
|
||||
using WTF::Unicode::rightToLeftOverride;
|
||||
using WTF::Unicode::sesameDot;
|
||||
using WTF::Unicode::softHyphen;
|
||||
using WTF::Unicode::space;
|
||||
using WTF::Unicode::tibetanMarkIntersyllabicTsheg;
|
||||
using WTF::Unicode::tibetanMarkDelimiterTshegBstar;
|
||||
using WTF::Unicode::ugariticWordDivider;
|
||||
using WTF::Unicode::whiteBullet;
|
||||
using WTF::Unicode::whiteCircle;
|
||||
using WTF::Unicode::whiteSesameDot;
|
||||
using WTF::Unicode::whiteUpPointingTriangle;
|
||||
using WTF::Unicode::yenSign;
|
||||
using WTF::Unicode::zeroWidthJoiner;
|
||||
using WTF::Unicode::zeroWidthNonJoiner;
|
||||
using WTF::Unicode::zeroWidthSpace;
|
||||
using WTF::Unicode::zeroWidthNoBreakSpace;
|
||||
|
||||
#endif // CharacterNames_h
|
||||
@@ -1,693 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef CheckedArithmetic_h
|
||||
#define CheckedArithmetic_h
|
||||
|
||||
#include "Assertions.h"
|
||||
#include "TypeTraits.h"
|
||||
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Checked<T>
|
||||
*
|
||||
* This class provides a mechanism to perform overflow-safe integer arithmetic
|
||||
* without having to manually ensure that you have all the required bounds checks
|
||||
* directly in your code.
|
||||
*
|
||||
* There are two modes of operation:
|
||||
* - The default is Checked<T, CrashOnOverflow>, and crashes at the point
|
||||
* and overflow has occurred.
|
||||
* - The alternative is Checked<T, RecordOverflow>, which uses an additional
|
||||
* byte of storage to track whether an overflow has occurred, subsequent
|
||||
* unchecked operations will crash if an overflow has occured
|
||||
*
|
||||
* It is possible to provide a custom overflow handler, in which case you need
|
||||
* to support these functions:
|
||||
* - void overflowed();
|
||||
* This function is called when an operation has produced an overflow.
|
||||
* - bool hasOverflowed();
|
||||
* This function must return true if overflowed() has been called on an
|
||||
* instance and false if it has not.
|
||||
* - void clearOverflow();
|
||||
* Used to reset overflow tracking when a value is being overwritten with
|
||||
* a new value.
|
||||
*
|
||||
* Checked<T> works for all integer types, with the following caveats:
|
||||
* - Mixing signedness of operands is only supported for types narrower than
|
||||
* 64bits.
|
||||
* - It does have a performance impact, so tight loops may want to be careful
|
||||
* when using it.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class CrashOnOverflow {
|
||||
protected:
|
||||
NO_RETURN_DUE_TO_CRASH void overflowed()
|
||||
{
|
||||
CRASH();
|
||||
}
|
||||
|
||||
void clearOverflow() { }
|
||||
|
||||
public:
|
||||
bool hasOverflowed() const { return false; }
|
||||
};
|
||||
|
||||
class RecordOverflow {
|
||||
protected:
|
||||
RecordOverflow()
|
||||
: m_overflowed(false)
|
||||
{
|
||||
}
|
||||
|
||||
void overflowed()
|
||||
{
|
||||
m_overflowed = true;
|
||||
}
|
||||
|
||||
void clearOverflow()
|
||||
{
|
||||
m_overflowed = false;
|
||||
}
|
||||
|
||||
public:
|
||||
bool hasOverflowed() const { return m_overflowed; }
|
||||
|
||||
private:
|
||||
unsigned char m_overflowed;
|
||||
};
|
||||
|
||||
template <typename T, class OverflowHandler = CrashOnOverflow> class Checked;
|
||||
template <typename T> struct RemoveChecked;
|
||||
template <typename T> struct RemoveChecked<Checked<T> >;
|
||||
|
||||
template <typename Target, typename Source, bool targetSigned = std::numeric_limits<Target>::is_signed, bool sourceSigned = std::numeric_limits<Source>::is_signed> struct BoundsChecker;
|
||||
template <typename Target, typename Source> struct BoundsChecker<Target, Source, false, false> {
|
||||
static bool inBounds(Source value)
|
||||
{
|
||||
// Same signedness so implicit type conversion will always increase precision
|
||||
// to widest type
|
||||
return value <= std::numeric_limits<Target>::max();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Target, typename Source> struct BoundsChecker<Target, Source, true, true> {
|
||||
static bool inBounds(Source value)
|
||||
{
|
||||
// Same signedness so implicit type conversion will always increase precision
|
||||
// to widest type
|
||||
return std::numeric_limits<Target>::min() <= value && value <= std::numeric_limits<Target>::max();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Target, typename Source> struct BoundsChecker<Target, Source, false, true> {
|
||||
static bool inBounds(Source value)
|
||||
{
|
||||
// Target is unsigned so any value less than zero is clearly unsafe
|
||||
if (value < 0)
|
||||
return false;
|
||||
// If our (unsigned) Target is the same or greater width we can
|
||||
// convert value to type Target without losing precision
|
||||
if (sizeof(Target) >= sizeof(Source))
|
||||
return static_cast<Target>(value) <= std::numeric_limits<Target>::max();
|
||||
// The signed Source type has greater precision than the target so
|
||||
// max(Target) -> Source will widen.
|
||||
return value <= static_cast<Source>(std::numeric_limits<Target>::max());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Target, typename Source> struct BoundsChecker<Target, Source, true, false> {
|
||||
static bool inBounds(Source value)
|
||||
{
|
||||
// Signed target with an unsigned source
|
||||
if (sizeof(Target) <= sizeof(Source))
|
||||
return value <= static_cast<Source>(std::numeric_limits<Target>::max());
|
||||
// Target is Wider than Source so we're guaranteed to fit any value in
|
||||
// unsigned Source
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Target, typename Source, bool SameType = IsSameType<Target, Source>::value> struct BoundsCheckElider;
|
||||
template <typename Target, typename Source> struct BoundsCheckElider<Target, Source, true> {
|
||||
static bool inBounds(Source) { return true; }
|
||||
};
|
||||
template <typename Target, typename Source> struct BoundsCheckElider<Target, Source, false> : public BoundsChecker<Target, Source> {
|
||||
};
|
||||
|
||||
template <typename Target, typename Source> static inline bool isInBounds(Source value)
|
||||
{
|
||||
return BoundsCheckElider<Target, Source>::inBounds(value);
|
||||
}
|
||||
|
||||
template <typename T> struct RemoveChecked {
|
||||
typedef T CleanType;
|
||||
static const CleanType DefaultValue = 0;
|
||||
};
|
||||
|
||||
template <typename T> struct RemoveChecked<Checked<T, CrashOnOverflow> > {
|
||||
typedef typename RemoveChecked<T>::CleanType CleanType;
|
||||
static const CleanType DefaultValue = 0;
|
||||
};
|
||||
|
||||
template <typename T> struct RemoveChecked<Checked<T, RecordOverflow> > {
|
||||
typedef typename RemoveChecked<T>::CleanType CleanType;
|
||||
static const CleanType DefaultValue = 0;
|
||||
};
|
||||
|
||||
// The ResultBase and SignednessSelector are used to workaround typeof not being
|
||||
// available in MSVC
|
||||
template <typename U, typename V, bool uIsBigger = (sizeof(U) > sizeof(V)), bool sameSize = (sizeof(U) == sizeof(V))> struct ResultBase;
|
||||
template <typename U, typename V> struct ResultBase<U, V, true, false> {
|
||||
typedef U ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V> struct ResultBase<U, V, false, false> {
|
||||
typedef V ResultType;
|
||||
};
|
||||
|
||||
template <typename U> struct ResultBase<U, U, false, true> {
|
||||
typedef U ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V, bool uIsSigned = std::numeric_limits<U>::is_signed, bool vIsSigned = std::numeric_limits<V>::is_signed> struct SignednessSelector;
|
||||
template <typename U, typename V> struct SignednessSelector<U, V, true, true> {
|
||||
typedef U ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V> struct SignednessSelector<U, V, false, false> {
|
||||
typedef U ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V> struct SignednessSelector<U, V, true, false> {
|
||||
typedef V ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V> struct SignednessSelector<U, V, false, true> {
|
||||
typedef U ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V> struct ResultBase<U, V, false, true> {
|
||||
typedef typename SignednessSelector<U, V>::ResultType ResultType;
|
||||
};
|
||||
|
||||
template <typename U, typename V> struct Result : ResultBase<typename RemoveChecked<U>::CleanType, typename RemoveChecked<V>::CleanType> {
|
||||
};
|
||||
|
||||
template <typename LHS, typename RHS, typename ResultType = typename Result<LHS, RHS>::ResultType,
|
||||
bool lhsSigned = std::numeric_limits<LHS>::is_signed, bool rhsSigned = std::numeric_limits<RHS>::is_signed> struct ArithmeticOperations;
|
||||
|
||||
template <typename LHS, typename RHS, typename ResultType> struct ArithmeticOperations<LHS, RHS, ResultType, true, true> {
|
||||
// LHS and RHS are signed types
|
||||
|
||||
// Helper function
|
||||
static inline bool signsMatch(LHS lhs, RHS rhs)
|
||||
{
|
||||
return (lhs ^ rhs) >= 0;
|
||||
}
|
||||
|
||||
static inline bool add(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
|
||||
{
|
||||
if (signsMatch(lhs, rhs)) {
|
||||
if (lhs >= 0) {
|
||||
if ((std::numeric_limits<ResultType>::max() - rhs) < lhs)
|
||||
return false;
|
||||
} else {
|
||||
ResultType temp = lhs - std::numeric_limits<ResultType>::min();
|
||||
if (rhs < -temp)
|
||||
return false;
|
||||
}
|
||||
} // if the signs do not match this operation can't overflow
|
||||
result = lhs + rhs;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sub(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
|
||||
{
|
||||
if (!signsMatch(lhs, rhs)) {
|
||||
if (lhs >= 0) {
|
||||
if (lhs > std::numeric_limits<ResultType>::max() + rhs)
|
||||
return false;
|
||||
} else {
|
||||
if (rhs > std::numeric_limits<ResultType>::max() + lhs)
|
||||
return false;
|
||||
}
|
||||
} // if the signs match this operation can't overflow
|
||||
result = lhs - rhs;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool multiply(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
|
||||
{
|
||||
if (signsMatch(lhs, rhs)) {
|
||||
if (lhs >= 0) {
|
||||
if (lhs && (std::numeric_limits<ResultType>::max() / lhs) < rhs)
|
||||
return false;
|
||||
} else {
|
||||
if (lhs == std::numeric_limits<ResultType>::min() || rhs == std::numeric_limits<ResultType>::min())
|
||||
return false;
|
||||
if ((std::numeric_limits<ResultType>::max() / -lhs) < -rhs)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (lhs < 0) {
|
||||
if (rhs && lhs < (std::numeric_limits<ResultType>::min() / rhs))
|
||||
return false;
|
||||
} else {
|
||||
if (lhs && rhs < (std::numeric_limits<ResultType>::min() / lhs))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
result = lhs * rhs;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool equals(LHS lhs, RHS rhs) { return lhs == rhs; }
|
||||
|
||||
};
|
||||
|
||||
template <typename LHS, typename RHS, typename ResultType> struct ArithmeticOperations<LHS, RHS, ResultType, false, false> {
|
||||
// LHS and RHS are unsigned types so bounds checks are nice and easy
|
||||
static inline bool add(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
|
||||
{
|
||||
ResultType temp = lhs + rhs;
|
||||
if (temp < lhs)
|
||||
return false;
|
||||
result = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sub(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
|
||||
{
|
||||
ResultType temp = lhs - rhs;
|
||||
if (temp > lhs)
|
||||
return false;
|
||||
result = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool multiply(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
|
||||
{
|
||||
ResultType temp = lhs * rhs;
|
||||
if (temp < lhs)
|
||||
return false;
|
||||
result = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool equals(LHS lhs, RHS rhs) { return lhs == rhs; }
|
||||
|
||||
};
|
||||
|
||||
template <typename ResultType> struct ArithmeticOperations<int, unsigned, ResultType, true, false> {
|
||||
static inline bool add(int64_t lhs, int64_t rhs, ResultType& result)
|
||||
{
|
||||
int64_t temp = lhs + rhs;
|
||||
if (temp < std::numeric_limits<ResultType>::min())
|
||||
return false;
|
||||
if (temp > std::numeric_limits<ResultType>::max())
|
||||
return false;
|
||||
result = static_cast<ResultType>(temp);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sub(int64_t lhs, int64_t rhs, ResultType& result)
|
||||
{
|
||||
int64_t temp = lhs - rhs;
|
||||
if (temp < std::numeric_limits<ResultType>::min())
|
||||
return false;
|
||||
if (temp > std::numeric_limits<ResultType>::max())
|
||||
return false;
|
||||
result = static_cast<ResultType>(temp);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool multiply(int64_t lhs, int64_t rhs, ResultType& result)
|
||||
{
|
||||
int64_t temp = lhs * rhs;
|
||||
if (temp < std::numeric_limits<ResultType>::min())
|
||||
return false;
|
||||
if (temp > std::numeric_limits<ResultType>::max())
|
||||
return false;
|
||||
result = static_cast<ResultType>(temp);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool equals(int lhs, unsigned rhs)
|
||||
{
|
||||
return static_cast<int64_t>(lhs) == static_cast<int64_t>(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ResultType> struct ArithmeticOperations<unsigned, int, ResultType, false, true> {
|
||||
static inline bool add(int64_t lhs, int64_t rhs, ResultType& result)
|
||||
{
|
||||
return ArithmeticOperations<int, unsigned, ResultType>::add(rhs, lhs, result);
|
||||
}
|
||||
|
||||
static inline bool sub(int64_t lhs, int64_t rhs, ResultType& result)
|
||||
{
|
||||
return ArithmeticOperations<int, unsigned, ResultType>::sub(lhs, rhs, result);
|
||||
}
|
||||
|
||||
static inline bool multiply(int64_t lhs, int64_t rhs, ResultType& result)
|
||||
{
|
||||
return ArithmeticOperations<int, unsigned, ResultType>::multiply(rhs, lhs, result);
|
||||
}
|
||||
|
||||
static inline bool equals(unsigned lhs, int rhs)
|
||||
{
|
||||
return ArithmeticOperations<int, unsigned, ResultType>::equals(rhs, lhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename V, typename R> static inline bool safeAdd(U lhs, V rhs, R& result)
|
||||
{
|
||||
return ArithmeticOperations<U, V, R>::add(lhs, rhs, result);
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename R> static inline bool safeSub(U lhs, V rhs, R& result)
|
||||
{
|
||||
return ArithmeticOperations<U, V, R>::sub(lhs, rhs, result);
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename R> static inline bool safeMultiply(U lhs, V rhs, R& result)
|
||||
{
|
||||
return ArithmeticOperations<U, V, R>::multiply(lhs, rhs, result);
|
||||
}
|
||||
|
||||
template <typename U, typename V> static inline bool safeEquals(U lhs, V rhs)
|
||||
{
|
||||
return ArithmeticOperations<U, V>::equals(lhs, rhs);
|
||||
}
|
||||
|
||||
enum ResultOverflowedTag { ResultOverflowed };
|
||||
|
||||
// FIXME: Needed to workaround http://llvm.org/bugs/show_bug.cgi?id=10801
|
||||
static inline bool workAroundClangBug() { return true; }
|
||||
|
||||
template <typename T, class OverflowHandler> class Checked : public OverflowHandler {
|
||||
public:
|
||||
template <typename _T, class _OverflowHandler> friend class Checked;
|
||||
Checked()
|
||||
: m_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
Checked(ResultOverflowedTag)
|
||||
: m_value(0)
|
||||
{
|
||||
// FIXME: Remove this when clang fixes http://llvm.org/bugs/show_bug.cgi?id=10801
|
||||
if (workAroundClangBug())
|
||||
this->overflowed();
|
||||
}
|
||||
|
||||
template <typename U> Checked(U value)
|
||||
{
|
||||
if (!isInBounds<T>(value))
|
||||
this->overflowed();
|
||||
m_value = static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename V> Checked(const Checked<T, V>& rhs)
|
||||
: m_value(rhs.m_value)
|
||||
{
|
||||
if (rhs.hasOverflowed())
|
||||
this->overflowed();
|
||||
}
|
||||
|
||||
template <typename U> Checked(const Checked<U, OverflowHandler>& rhs)
|
||||
: OverflowHandler(rhs)
|
||||
{
|
||||
if (!isInBounds<T>(rhs.m_value))
|
||||
this->overflowed();
|
||||
m_value = static_cast<T>(rhs.m_value);
|
||||
}
|
||||
|
||||
template <typename U, typename V> Checked(const Checked<U, V>& rhs)
|
||||
{
|
||||
if (rhs.hasOverflowed())
|
||||
this->overflowed();
|
||||
if (!isInBounds<T>(rhs.m_value))
|
||||
this->overflowed();
|
||||
m_value = static_cast<T>(rhs.m_value);
|
||||
}
|
||||
|
||||
const Checked& operator=(Checked rhs)
|
||||
{
|
||||
this->clearOverflow();
|
||||
if (rhs.hasOverflowed())
|
||||
this->overflowed();
|
||||
m_value = static_cast<T>(rhs.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U> const Checked& operator=(U value)
|
||||
{
|
||||
return *this = Checked(value);
|
||||
}
|
||||
|
||||
template <typename U, typename V> const Checked& operator=(const Checked<U, V>& rhs)
|
||||
{
|
||||
return *this = Checked(rhs);
|
||||
}
|
||||
|
||||
// prefix
|
||||
const Checked& operator++()
|
||||
{
|
||||
if (m_value == std::numeric_limits<T>::max())
|
||||
this->overflowed();
|
||||
m_value++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Checked& operator--()
|
||||
{
|
||||
if (m_value == std::numeric_limits<T>::min())
|
||||
this->overflowed();
|
||||
m_value--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// postfix operators
|
||||
const Checked operator++(int)
|
||||
{
|
||||
if (m_value == std::numeric_limits<T>::max())
|
||||
this->overflowed();
|
||||
return Checked(m_value++);
|
||||
}
|
||||
|
||||
const Checked operator--(int)
|
||||
{
|
||||
if (m_value == std::numeric_limits<T>::min())
|
||||
this->overflowed();
|
||||
return Checked(m_value--);
|
||||
}
|
||||
|
||||
// Boolean operators
|
||||
bool operator!() const
|
||||
{
|
||||
if (this->hasOverflowed())
|
||||
CRASH();
|
||||
return !m_value;
|
||||
}
|
||||
|
||||
typedef void* (Checked::*UnspecifiedBoolType);
|
||||
operator UnspecifiedBoolType*() const
|
||||
{
|
||||
if (this->hasOverflowed())
|
||||
CRASH();
|
||||
return (m_value) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
|
||||
}
|
||||
|
||||
// Value accessors. unsafeGet() will crash if there's been an overflow.
|
||||
T unsafeGet() const
|
||||
{
|
||||
if (this->hasOverflowed())
|
||||
CRASH();
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool safeGet(T& value) const WARN_UNUSED_RETURN
|
||||
{
|
||||
value = m_value;
|
||||
return this->hasOverflowed();
|
||||
}
|
||||
|
||||
// Mutating assignment
|
||||
template <typename U> const Checked operator+=(U rhs)
|
||||
{
|
||||
if (!safeAdd(m_value, rhs, m_value))
|
||||
this->overflowed();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U> const Checked operator-=(U rhs)
|
||||
{
|
||||
if (!safeSub(m_value, rhs, m_value))
|
||||
this->overflowed();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U> const Checked operator*=(U rhs)
|
||||
{
|
||||
if (!safeMultiply(m_value, rhs, m_value))
|
||||
this->overflowed();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U, typename V> const Checked operator+=(Checked<U, V> rhs)
|
||||
{
|
||||
if (rhs.hasOverflowed())
|
||||
this->overflowed();
|
||||
return *this += rhs.m_value;
|
||||
}
|
||||
|
||||
template <typename U, typename V> const Checked operator-=(Checked<U, V> rhs)
|
||||
{
|
||||
if (rhs.hasOverflowed())
|
||||
this->overflowed();
|
||||
return *this -= rhs.m_value;
|
||||
}
|
||||
|
||||
template <typename U, typename V> const Checked operator*=(Checked<U, V> rhs)
|
||||
{
|
||||
if (rhs.hasOverflowed())
|
||||
this->overflowed();
|
||||
return *this *= rhs.m_value;
|
||||
}
|
||||
|
||||
// Equality comparisons
|
||||
template <typename V> bool operator==(Checked<T, V> rhs)
|
||||
{
|
||||
return unsafeGet() == rhs.unsafeGet();
|
||||
}
|
||||
|
||||
template <typename U> bool operator==(U rhs)
|
||||
{
|
||||
if (this->hasOverflowed())
|
||||
this->overflowed();
|
||||
return safeEquals(m_value, rhs);
|
||||
}
|
||||
|
||||
template <typename U, typename V> const Checked operator==(Checked<U, V> rhs)
|
||||
{
|
||||
return unsafeGet() == Checked(rhs.unsafeGet());
|
||||
}
|
||||
|
||||
template <typename U> bool operator!=(U rhs)
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow implicit conversion of floating point to integer types
|
||||
Checked(float);
|
||||
Checked(double);
|
||||
void operator=(float);
|
||||
void operator=(double);
|
||||
void operator+=(float);
|
||||
void operator+=(double);
|
||||
void operator-=(float);
|
||||
void operator-=(double);
|
||||
T m_value;
|
||||
};
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator+(Checked<U, OverflowHandler> lhs, Checked<V, OverflowHandler> rhs)
|
||||
{
|
||||
U x = 0;
|
||||
V y = 0;
|
||||
bool overflowed = lhs.safeGet(x) || rhs.safeGet(y);
|
||||
typename Result<U, V>::ResultType result = 0;
|
||||
overflowed |= !safeAdd(x, y, result);
|
||||
if (overflowed)
|
||||
return ResultOverflowed;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator-(Checked<U, OverflowHandler> lhs, Checked<V, OverflowHandler> rhs)
|
||||
{
|
||||
U x = 0;
|
||||
V y = 0;
|
||||
bool overflowed = lhs.safeGet(x) || rhs.safeGet(y);
|
||||
typename Result<U, V>::ResultType result = 0;
|
||||
overflowed |= !safeSub(x, y, result);
|
||||
if (overflowed)
|
||||
return ResultOverflowed;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator*(Checked<U, OverflowHandler> lhs, Checked<V, OverflowHandler> rhs)
|
||||
{
|
||||
U x = 0;
|
||||
V y = 0;
|
||||
bool overflowed = lhs.safeGet(x) || rhs.safeGet(y);
|
||||
typename Result<U, V>::ResultType result = 0;
|
||||
overflowed |= !safeMultiply(x, y, result);
|
||||
if (overflowed)
|
||||
return ResultOverflowed;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator+(Checked<U, OverflowHandler> lhs, V rhs)
|
||||
{
|
||||
return lhs + Checked<V, OverflowHandler>(rhs);
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator-(Checked<U, OverflowHandler> lhs, V rhs)
|
||||
{
|
||||
return lhs - Checked<V, OverflowHandler>(rhs);
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator*(Checked<U, OverflowHandler> lhs, V rhs)
|
||||
{
|
||||
return lhs * Checked<V, OverflowHandler>(rhs);
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator+(U lhs, Checked<V, OverflowHandler> rhs)
|
||||
{
|
||||
return Checked<U, OverflowHandler>(lhs) + rhs;
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator-(U lhs, Checked<V, OverflowHandler> rhs)
|
||||
{
|
||||
return Checked<U, OverflowHandler>(lhs) - rhs;
|
||||
}
|
||||
|
||||
template <typename U, typename V, typename OverflowHandler> static inline Checked<typename Result<U, V>::ResultType, OverflowHandler> operator*(U lhs, Checked<V, OverflowHandler> rhs)
|
||||
{
|
||||
return Checked<U, OverflowHandler>(lhs) * rhs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using WTF::Checked;
|
||||
using WTF::RecordOverflow;
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef CheckedBoolean_h
|
||||
#define CheckedBoolean_h
|
||||
|
||||
#include <wtf/Assertions.h>
|
||||
|
||||
class CheckedBoolean {
|
||||
public:
|
||||
CheckedBoolean(bool value)
|
||||
: m_value(value)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_checked(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
~CheckedBoolean()
|
||||
{
|
||||
ASSERT(m_checked);
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
#if !ASSERT_DISABLED
|
||||
m_checked = true;
|
||||
#endif
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_value;
|
||||
#if !ASSERT_DISABLED
|
||||
bool m_checked;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
|
||||
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ClassInfo_h
|
||||
#define ClassInfo_h
|
||||
|
||||
#include "CallFrame.h"
|
||||
#include "ConstructData.h"
|
||||
#include "JSCell.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class HashEntry;
|
||||
struct HashTable;
|
||||
|
||||
struct MethodTable {
|
||||
typedef void (*DestroyFunctionPtr)(JSCell*);
|
||||
DestroyFunctionPtr destroy;
|
||||
|
||||
typedef void (*VisitChildrenFunctionPtr)(JSCell*, SlotVisitor&);
|
||||
VisitChildrenFunctionPtr visitChildren;
|
||||
|
||||
typedef CallType (*GetCallDataFunctionPtr)(JSCell*, CallData&);
|
||||
GetCallDataFunctionPtr getCallData;
|
||||
|
||||
typedef ConstructType (*GetConstructDataFunctionPtr)(JSCell*, ConstructData&);
|
||||
GetConstructDataFunctionPtr getConstructData;
|
||||
|
||||
typedef void (*PutFunctionPtr)(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
|
||||
PutFunctionPtr put;
|
||||
|
||||
typedef void (*PutByIndexFunctionPtr)(JSCell*, ExecState*, unsigned propertyName, JSValue);
|
||||
PutByIndexFunctionPtr putByIndex;
|
||||
|
||||
typedef bool (*DeletePropertyFunctionPtr)(JSCell*, ExecState*, const Identifier&);
|
||||
DeletePropertyFunctionPtr deleteProperty;
|
||||
|
||||
typedef bool (*DeletePropertyByIndexFunctionPtr)(JSCell*, ExecState*, unsigned);
|
||||
DeletePropertyByIndexFunctionPtr deletePropertyByIndex;
|
||||
|
||||
typedef bool (*GetOwnPropertySlotFunctionPtr)(JSCell*, ExecState*, const Identifier&, PropertySlot&);
|
||||
GetOwnPropertySlotFunctionPtr getOwnPropertySlot;
|
||||
|
||||
typedef bool (*GetOwnPropertySlotByIndexFunctionPtr)(JSCell*, ExecState*, unsigned, PropertySlot&);
|
||||
GetOwnPropertySlotByIndexFunctionPtr getOwnPropertySlotByIndex;
|
||||
|
||||
typedef JSObject* (*ToThisObjectFunctionPtr)(JSCell*, ExecState*);
|
||||
ToThisObjectFunctionPtr toThisObject;
|
||||
|
||||
typedef void (*DefineGetterFunctionPtr)(JSObject*, ExecState*, const Identifier&, JSObject*, unsigned);
|
||||
DefineGetterFunctionPtr defineGetter;
|
||||
|
||||
typedef void (*DefineSetterFunctionPtr)(JSObject*, ExecState*, const Identifier&, JSObject*, unsigned);
|
||||
DefineSetterFunctionPtr defineSetter;
|
||||
|
||||
typedef JSValue (*DefaultValueFunctionPtr)(const JSObject*, ExecState*, PreferredPrimitiveType);
|
||||
DefaultValueFunctionPtr defaultValue;
|
||||
|
||||
typedef void (*GetOwnPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
|
||||
GetOwnPropertyNamesFunctionPtr getOwnPropertyNames;
|
||||
|
||||
typedef void (*GetPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
|
||||
GetPropertyNamesFunctionPtr getPropertyNames;
|
||||
|
||||
typedef UString (*ClassNameFunctionPtr)(const JSObject*);
|
||||
ClassNameFunctionPtr className;
|
||||
|
||||
typedef bool (*HasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue, JSValue);
|
||||
HasInstanceFunctionPtr hasInstance;
|
||||
|
||||
typedef void (*PutWithAttributesFunctionPtr)(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
|
||||
PutWithAttributesFunctionPtr putDirectVirtual;
|
||||
|
||||
typedef bool (*DefineOwnPropertyFunctionPtr)(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool);
|
||||
DefineOwnPropertyFunctionPtr defineOwnProperty;
|
||||
|
||||
typedef bool (*GetOwnPropertyDescriptorFunctionPtr)(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
|
||||
GetOwnPropertyDescriptorFunctionPtr getOwnPropertyDescriptor;
|
||||
};
|
||||
|
||||
#define CREATE_MEMBER_CHECKER(member) \
|
||||
template <typename T> \
|
||||
struct MemberCheck##member { \
|
||||
struct Fallback { \
|
||||
void member(...); \
|
||||
}; \
|
||||
struct Derived : T, Fallback { }; \
|
||||
template <typename U, U> struct Check; \
|
||||
typedef char Yes[2]; \
|
||||
typedef char No[1]; \
|
||||
template <typename U> \
|
||||
static No &func(Check<void (Fallback::*)(...), &U::member>*); \
|
||||
template <typename U> \
|
||||
static Yes &func(...); \
|
||||
enum { has = sizeof(func<Derived>(0)) == sizeof(Yes) }; \
|
||||
}
|
||||
|
||||
#define HAS_MEMBER_NAMED(klass, name) (MemberCheck##name<klass>::has)
|
||||
|
||||
#define CREATE_METHOD_TABLE(ClassName) { \
|
||||
&ClassName::destroy, \
|
||||
&ClassName::visitChildren, \
|
||||
&ClassName::getCallData, \
|
||||
&ClassName::getConstructData, \
|
||||
&ClassName::put, \
|
||||
&ClassName::putByIndex, \
|
||||
&ClassName::deleteProperty, \
|
||||
&ClassName::deletePropertyByIndex, \
|
||||
&ClassName::getOwnPropertySlot, \
|
||||
&ClassName::getOwnPropertySlotByIndex, \
|
||||
&ClassName::toThisObject, \
|
||||
&ClassName::defineGetter, \
|
||||
&ClassName::defineSetter, \
|
||||
&ClassName::defaultValue, \
|
||||
&ClassName::getOwnPropertyNames, \
|
||||
&ClassName::getPropertyNames, \
|
||||
&ClassName::className, \
|
||||
&ClassName::hasInstance, \
|
||||
&ClassName::putDirectVirtual, \
|
||||
&ClassName::defineOwnProperty, \
|
||||
&ClassName::getOwnPropertyDescriptor, \
|
||||
}, \
|
||||
sizeof(ClassName), \
|
||||
ClassName::TypedArrayStorageType
|
||||
|
||||
struct ClassInfo {
|
||||
/**
|
||||
* A string denoting the class name. Example: "Window".
|
||||
*/
|
||||
const char* className;
|
||||
|
||||
/**
|
||||
* Pointer to the class information of the base class.
|
||||
* 0L if there is none.
|
||||
*/
|
||||
const ClassInfo* parentClass;
|
||||
/**
|
||||
* Static hash-table of properties.
|
||||
* For classes that can be used from multiple threads, it is accessed via a getter function that would typically return a pointer to thread-specific value.
|
||||
*/
|
||||
const HashTable* propHashTable(ExecState* exec) const
|
||||
{
|
||||
if (classPropHashTableGetterFunction)
|
||||
return classPropHashTableGetterFunction(exec);
|
||||
return staticPropHashTable;
|
||||
}
|
||||
|
||||
bool isSubClassOf(const ClassInfo* other) const
|
||||
{
|
||||
for (const ClassInfo* ci = this; ci; ci = ci->parentClass) {
|
||||
if (ci == other)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasStaticProperties() const
|
||||
{
|
||||
for (const ClassInfo* ci = this; ci; ci = ci->parentClass) {
|
||||
if (ci->staticPropHashTable || ci->classPropHashTableGetterFunction)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const HashTable* staticPropHashTable;
|
||||
typedef const HashTable* (*ClassPropHashTableGetterFunction)(ExecState*);
|
||||
const ClassPropHashTableGetterFunction classPropHashTableGetterFunction;
|
||||
|
||||
MethodTable methodTable;
|
||||
|
||||
size_t cellSize;
|
||||
|
||||
TypedArrayType typedArrayStorageType;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // ClassInfo_h
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef CodeOrigin_h
|
||||
#define CodeOrigin_h
|
||||
|
||||
#include "ValueRecovery.h"
|
||||
#include "WriteBarrier.h"
|
||||
#include <wtf/StdLibExtras.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
struct InlineCallFrame;
|
||||
class ExecutableBase;
|
||||
class JSFunction;
|
||||
|
||||
struct CodeOrigin {
|
||||
// Bytecode offset that you'd use to re-execute this instruction.
|
||||
unsigned bytecodeIndex : 29;
|
||||
// Bytecode offset corresponding to the opcode that gives the result (needed to handle
|
||||
// op_call/op_call_put_result and op_method_check/op_get_by_id).
|
||||
unsigned valueProfileOffset : 3;
|
||||
|
||||
InlineCallFrame* inlineCallFrame;
|
||||
|
||||
CodeOrigin()
|
||||
: bytecodeIndex(std::numeric_limits<uint32_t>::max())
|
||||
, valueProfileOffset(0)
|
||||
, inlineCallFrame(0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CodeOrigin(unsigned bytecodeIndex, InlineCallFrame* inlineCallFrame = 0, unsigned valueProfileOffset = 0)
|
||||
: bytecodeIndex(bytecodeIndex)
|
||||
, valueProfileOffset(valueProfileOffset)
|
||||
, inlineCallFrame(inlineCallFrame)
|
||||
{
|
||||
ASSERT(bytecodeIndex < (1u << 29));
|
||||
ASSERT(valueProfileOffset < (1u << 3));
|
||||
}
|
||||
|
||||
bool isSet() const { return bytecodeIndex != std::numeric_limits<uint32_t>::max(); }
|
||||
|
||||
unsigned bytecodeIndexForValueProfile() const
|
||||
{
|
||||
return bytecodeIndex + valueProfileOffset;
|
||||
}
|
||||
|
||||
// The inline depth is the depth of the inline stack, so 1 = not inlined,
|
||||
// 2 = inlined one deep, etc.
|
||||
unsigned inlineDepth() const;
|
||||
|
||||
// If the code origin corresponds to inlined code, gives you the heap object that
|
||||
// would have owned the code if it had not been inlined. Otherwise returns 0.
|
||||
ExecutableBase* codeOriginOwner() const;
|
||||
|
||||
static unsigned inlineDepthForCallFrame(InlineCallFrame*);
|
||||
|
||||
bool operator==(const CodeOrigin& other) const;
|
||||
|
||||
bool operator!=(const CodeOrigin& other) const { return !(*this == other); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Get the inline stack. This is slow, and is intended for debugging only.
|
||||
Vector<CodeOrigin> inlineStack() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct InlineCallFrame {
|
||||
Vector<ValueRecovery> arguments;
|
||||
WriteBarrier<ExecutableBase> executable;
|
||||
WriteBarrier<JSFunction> callee;
|
||||
CodeOrigin caller;
|
||||
unsigned stackOffset : 31;
|
||||
bool isCall : 1;
|
||||
};
|
||||
|
||||
struct CodeOriginAtCallReturnOffset {
|
||||
CodeOrigin codeOrigin;
|
||||
unsigned callReturnOffset;
|
||||
};
|
||||
|
||||
inline unsigned CodeOrigin::inlineDepthForCallFrame(InlineCallFrame* inlineCallFrame)
|
||||
{
|
||||
unsigned result = 1;
|
||||
for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame)
|
||||
result++;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline unsigned CodeOrigin::inlineDepth() const
|
||||
{
|
||||
return inlineDepthForCallFrame(inlineCallFrame);
|
||||
}
|
||||
|
||||
inline bool CodeOrigin::operator==(const CodeOrigin& other) const
|
||||
{
|
||||
return bytecodeIndex == other.bytecodeIndex
|
||||
&& inlineCallFrame == other.inlineCallFrame;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Get the inline stack. This is slow, and is intended for debugging only.
|
||||
inline Vector<CodeOrigin> CodeOrigin::inlineStack() const
|
||||
{
|
||||
Vector<CodeOrigin> result(inlineDepth());
|
||||
result.last() = *this;
|
||||
unsigned index = result.size() - 2;
|
||||
for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame)
|
||||
result[index--] = current->caller;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline unsigned getCallReturnOffsetForCodeOrigin(CodeOriginAtCallReturnOffset* data)
|
||||
{
|
||||
return data->callReturnOffset;
|
||||
}
|
||||
|
||||
inline ExecutableBase* CodeOrigin::codeOriginOwner() const
|
||||
{
|
||||
if (!inlineCallFrame)
|
||||
return 0;
|
||||
return inlineCallFrame->executable.get();
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CodeOrigin_h
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef CodeType_h
|
||||
#define CodeType_h
|
||||
|
||||
namespace JSC {
|
||||
|
||||
enum CodeType { GlobalCode, EvalCode, FunctionCode };
|
||||
|
||||
}
|
||||
|
||||
#endif // CodeType_h
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_Collator_h
|
||||
#define WTF_Collator_h
|
||||
|
||||
#include <wtf/FastAllocBase.h>
|
||||
#include <wtf/Noncopyable.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
#include <wtf/unicode/Unicode.h>
|
||||
|
||||
#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
|
||||
struct UCollator;
|
||||
#endif
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class Collator {
|
||||
WTF_MAKE_NONCOPYABLE(Collator); WTF_MAKE_FAST_ALLOCATED;
|
||||
public:
|
||||
enum Result { Equal = 0, Greater = 1, Less = -1 };
|
||||
|
||||
WTF_EXPORT_PRIVATE Collator(const char* locale); // Parsing is lenient; e.g. language identifiers (such as "en-US") are accepted, too.
|
||||
WTF_EXPORT_PRIVATE ~Collator();
|
||||
WTF_EXPORT_PRIVATE void setOrderLowerFirst(bool);
|
||||
|
||||
static PassOwnPtr<Collator> userDefault();
|
||||
|
||||
WTF_EXPORT_PRIVATE Result collate(const ::UChar*, size_t, const ::UChar*, size_t) const;
|
||||
|
||||
private:
|
||||
#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
|
||||
void createCollator() const;
|
||||
void releaseCollator();
|
||||
mutable UCollator* m_collator;
|
||||
#endif
|
||||
char* m_locale;
|
||||
bool m_lowerFirst;
|
||||
};
|
||||
}
|
||||
|
||||
using WTF::Collator;
|
||||
|
||||
#endif
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CommonIdentifiers_h
|
||||
#define CommonIdentifiers_h
|
||||
|
||||
#include "Identifier.h"
|
||||
#include <wtf/Noncopyable.h>
|
||||
|
||||
// MarkedArgumentBuffer of property names, passed to a macro so we can do set them up various
|
||||
// ways without repeating the list.
|
||||
#define JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
|
||||
macro(__defineGetter__) \
|
||||
macro(__defineSetter__) \
|
||||
macro(__lookupGetter__) \
|
||||
macro(__lookupSetter__) \
|
||||
macro(apply) \
|
||||
macro(arguments) \
|
||||
macro(bind) \
|
||||
macro(call) \
|
||||
macro(callee) \
|
||||
macro(caller) \
|
||||
macro(compile) \
|
||||
macro(configurable) \
|
||||
macro(constructor) \
|
||||
macro(enumerable) \
|
||||
macro(eval) \
|
||||
macro(exec) \
|
||||
macro(fromCharCode) \
|
||||
macro(global) \
|
||||
macro(get) \
|
||||
macro(hasOwnProperty) \
|
||||
macro(ignoreCase) \
|
||||
macro(index) \
|
||||
macro(input) \
|
||||
macro(isArray) \
|
||||
macro(isPrototypeOf) \
|
||||
macro(stack) \
|
||||
macro(length) \
|
||||
macro(message) \
|
||||
macro(multiline) \
|
||||
macro(name) \
|
||||
macro(now) \
|
||||
macro(parse) \
|
||||
macro(propertyIsEnumerable) \
|
||||
macro(prototype) \
|
||||
macro(set) \
|
||||
macro(source) \
|
||||
macro(test) \
|
||||
macro(toExponential) \
|
||||
macro(toFixed) \
|
||||
macro(toISOString) \
|
||||
macro(toJSON) \
|
||||
macro(toLocaleString) \
|
||||
macro(toPrecision) \
|
||||
macro(toString) \
|
||||
macro(UTC) \
|
||||
macro(value) \
|
||||
macro(valueOf) \
|
||||
macro(writable) \
|
||||
macro(displayName) \
|
||||
macro(undefined)
|
||||
|
||||
#define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
|
||||
macro(null) \
|
||||
macro(true) \
|
||||
macro(false) \
|
||||
macro(break) \
|
||||
macro(case) \
|
||||
macro(catch) \
|
||||
macro(const) \
|
||||
macro(default) \
|
||||
macro(finally) \
|
||||
macro(for) \
|
||||
macro(instanceof) \
|
||||
macro(new) \
|
||||
macro(var) \
|
||||
macro(continue) \
|
||||
macro(function) \
|
||||
macro(return) \
|
||||
macro(void) \
|
||||
macro(delete) \
|
||||
macro(if) \
|
||||
macro(this) \
|
||||
macro(do) \
|
||||
macro(while) \
|
||||
macro(else) \
|
||||
macro(in) \
|
||||
macro(switch) \
|
||||
macro(throw) \
|
||||
macro(try) \
|
||||
macro(typeof) \
|
||||
macro(with) \
|
||||
macro(debugger) \
|
||||
macro(class) \
|
||||
macro(enum) \
|
||||
macro(export) \
|
||||
macro(extends) \
|
||||
macro(import) \
|
||||
macro(super) \
|
||||
macro(implements) \
|
||||
macro(interface) \
|
||||
macro(let) \
|
||||
macro(package) \
|
||||
macro(private) \
|
||||
macro(protected) \
|
||||
macro(public) \
|
||||
macro(static) \
|
||||
macro(yield)
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class CommonIdentifiers {
|
||||
WTF_MAKE_NONCOPYABLE(CommonIdentifiers); WTF_MAKE_FAST_ALLOCATED;
|
||||
private:
|
||||
CommonIdentifiers(JSGlobalData*);
|
||||
friend class JSGlobalData;
|
||||
|
||||
public:
|
||||
const Identifier nullIdentifier;
|
||||
const Identifier emptyIdentifier;
|
||||
const Identifier underscoreProto;
|
||||
const Identifier thisIdentifier;
|
||||
const Identifier useStrictIdentifier;
|
||||
|
||||
|
||||
#define JSC_IDENTIFIER_DECLARE_KEYWORD_NAME_GLOBAL(name) const Identifier name##Keyword;
|
||||
JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(JSC_IDENTIFIER_DECLARE_KEYWORD_NAME_GLOBAL)
|
||||
#undef JSC_IDENTIFIER_DECLARE_KEYWORD_NAME_GLOBAL
|
||||
|
||||
#define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name;
|
||||
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
|
||||
#undef JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CommonIdentifiers_h
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011, 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef CommonSlowPaths_h
|
||||
#define CommonSlowPaths_h
|
||||
|
||||
#include "CodeBlock.h"
|
||||
#include "ExceptionHelpers.h"
|
||||
#include "JSArray.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// The purpose of this namespace is to include slow paths that are shared
|
||||
// between the interpreter and baseline JIT. They are written to be agnostic
|
||||
// with respect to the slow-path calling convention, but they do rely on the
|
||||
// JS code being executed more-or-less directly from bytecode (so the call
|
||||
// frame layout is unmodified, making it potentially awkward to use these
|
||||
// from any optimizing JIT, like the DFG).
|
||||
|
||||
namespace CommonSlowPaths {
|
||||
|
||||
ALWAYS_INLINE bool opInstanceOfSlow(ExecState* exec, JSValue value, JSValue baseVal, JSValue proto)
|
||||
{
|
||||
ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
|
||||
|| !value.isObject() || !baseVal.isObject() || !proto.isObject()
|
||||
|| !asObject(baseVal)->structure()->typeInfo().implementsDefaultHasInstance());
|
||||
|
||||
|
||||
// ECMA-262 15.3.5.3:
|
||||
// Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
|
||||
TypeInfo typeInfo(UnspecifiedType);
|
||||
if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) {
|
||||
exec->globalData().exception = createInvalidParamError(exec, "instanceof", baseVal);
|
||||
return false;
|
||||
}
|
||||
ASSERT(typeInfo.type() != UnspecifiedType);
|
||||
|
||||
if (!typeInfo.overridesHasInstance() && !value.isObject())
|
||||
return false;
|
||||
|
||||
return asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), exec, value, proto);
|
||||
}
|
||||
|
||||
inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
|
||||
{
|
||||
if (!baseVal.isObject()) {
|
||||
exec->globalData().exception = createInvalidParamError(exec, "in", baseVal);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject* baseObj = asObject(baseVal);
|
||||
|
||||
uint32_t i;
|
||||
if (propName.getUInt32(i))
|
||||
return baseObj->hasProperty(exec, i);
|
||||
|
||||
Identifier property(exec, propName.toString(exec)->value(exec));
|
||||
if (exec->globalData().exception)
|
||||
return false;
|
||||
return baseObj->hasProperty(exec, property);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE JSValue opResolve(ExecState* exec, Identifier& ident)
|
||||
{
|
||||
ScopeChainNode* scopeChain = exec->scopeChain();
|
||||
|
||||
ScopeChainIterator iter = scopeChain->begin();
|
||||
ScopeChainIterator end = scopeChain->end();
|
||||
ASSERT(iter != end);
|
||||
|
||||
do {
|
||||
JSObject* o = iter->get();
|
||||
PropertySlot slot(o);
|
||||
if (o->getPropertySlot(exec, ident, slot))
|
||||
return slot.getValue(exec, ident);
|
||||
} while (++iter != end);
|
||||
|
||||
exec->globalData().exception = createUndefinedVariableError(exec, ident);
|
||||
return JSValue();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE JSValue opResolveSkip(ExecState* exec, Identifier& ident, int skip)
|
||||
{
|
||||
ScopeChainNode* scopeChain = exec->scopeChain();
|
||||
|
||||
ScopeChainIterator iter = scopeChain->begin();
|
||||
ScopeChainIterator end = scopeChain->end();
|
||||
ASSERT(iter != end);
|
||||
CodeBlock* codeBlock = exec->codeBlock();
|
||||
bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
|
||||
ASSERT(skip || !checkTopLevel);
|
||||
if (checkTopLevel && skip--) {
|
||||
if (exec->uncheckedR(codeBlock->activationRegister()).jsValue())
|
||||
++iter;
|
||||
}
|
||||
while (skip--) {
|
||||
++iter;
|
||||
ASSERT(iter != end);
|
||||
}
|
||||
do {
|
||||
JSObject* o = iter->get();
|
||||
PropertySlot slot(o);
|
||||
if (o->getPropertySlot(exec, ident, slot))
|
||||
return slot.getValue(exec, ident);
|
||||
} while (++iter != end);
|
||||
|
||||
exec->globalData().exception = createUndefinedVariableError(exec, ident);
|
||||
return JSValue();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE JSValue opResolveWithBase(ExecState* exec, Identifier& ident, Register& baseSlot)
|
||||
{
|
||||
ScopeChainNode* scopeChain = exec->scopeChain();
|
||||
|
||||
ScopeChainIterator iter = scopeChain->begin();
|
||||
ScopeChainIterator end = scopeChain->end();
|
||||
|
||||
// FIXME: add scopeDepthIsZero optimization
|
||||
|
||||
ASSERT(iter != end);
|
||||
|
||||
JSObject* base;
|
||||
do {
|
||||
base = iter->get();
|
||||
PropertySlot slot(base);
|
||||
if (base->getPropertySlot(exec, ident, slot)) {
|
||||
JSValue result = slot.getValue(exec, ident);
|
||||
if (exec->globalData().exception)
|
||||
return JSValue();
|
||||
|
||||
baseSlot = JSValue(base);
|
||||
return result;
|
||||
}
|
||||
++iter;
|
||||
} while (iter != end);
|
||||
|
||||
exec->globalData().exception = createUndefinedVariableError(exec, ident);
|
||||
return JSValue();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE JSValue opResolveWithThis(ExecState* exec, Identifier& ident, Register& baseSlot)
|
||||
{
|
||||
ScopeChainNode* scopeChain = exec->scopeChain();
|
||||
|
||||
ScopeChainIterator iter = scopeChain->begin();
|
||||
ScopeChainIterator end = scopeChain->end();
|
||||
|
||||
// FIXME: add scopeDepthIsZero optimization
|
||||
|
||||
ASSERT(iter != end);
|
||||
|
||||
JSObject* base;
|
||||
do {
|
||||
base = iter->get();
|
||||
++iter;
|
||||
PropertySlot slot(base);
|
||||
if (base->getPropertySlot(exec, ident, slot)) {
|
||||
JSValue result = slot.getValue(exec, ident);
|
||||
if (exec->globalData().exception)
|
||||
return JSValue();
|
||||
|
||||
// All entries on the scope chain should be EnvironmentRecords (activations etc),
|
||||
// other then 'with' object, which are directly referenced from the scope chain,
|
||||
// and the global object. If we hit either an EnvironmentRecord or a global
|
||||
// object at the end of the scope chain, this is undefined. If we hit a non-
|
||||
// EnvironmentRecord within the scope chain, pass the base as the this value.
|
||||
if (iter == end || base->structure()->typeInfo().isEnvironmentRecord())
|
||||
baseSlot = jsUndefined();
|
||||
else
|
||||
baseSlot = JSValue(base);
|
||||
return result;
|
||||
}
|
||||
} while (iter != end);
|
||||
|
||||
exec->globalData().exception = createUndefinedVariableError(exec, ident);
|
||||
return JSValue();
|
||||
}
|
||||
|
||||
} } // namespace JSC::CommonSlowPaths
|
||||
|
||||
#endif // CommonSlowPaths_h
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef CompactJITCodeMap_h
|
||||
#define CompactJITCodeMap_h
|
||||
|
||||
#include <wtf/Assertions.h>
|
||||
#include <wtf/FastAllocBase.h>
|
||||
#include <wtf/FastMalloc.h>
|
||||
#include <wtf/OwnPtr.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
#include <wtf/UnusedParam.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Gives you a compressed map between between bytecode indices and machine code
|
||||
// entry points. The compression simply tries to use either 1, 2, or 4 bytes for
|
||||
// any given offset. The largest offset that can be stored is 2^30.
|
||||
|
||||
// Example use:
|
||||
//
|
||||
// CompactJITCodeMap::Encoder encoder(map);
|
||||
// encoder.append(a, b);
|
||||
// encoder.append(c, d); // preconditions: c >= a, d >= b
|
||||
// OwnPtr<CompactJITCodeMap> map = encoder.finish();
|
||||
//
|
||||
// At some later time:
|
||||
//
|
||||
// Vector<BytecodeAndMachineOffset> decoded;
|
||||
// map->decode(decoded);
|
||||
|
||||
struct BytecodeAndMachineOffset {
|
||||
BytecodeAndMachineOffset() { }
|
||||
|
||||
BytecodeAndMachineOffset(unsigned bytecodeIndex, unsigned machineCodeOffset)
|
||||
: m_bytecodeIndex(bytecodeIndex)
|
||||
, m_machineCodeOffset(machineCodeOffset)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned m_bytecodeIndex;
|
||||
unsigned m_machineCodeOffset;
|
||||
|
||||
static inline unsigned getBytecodeIndex(BytecodeAndMachineOffset* mapping)
|
||||
{
|
||||
return mapping->m_bytecodeIndex;
|
||||
}
|
||||
|
||||
static inline unsigned getMachineCodeOffset(BytecodeAndMachineOffset* mapping)
|
||||
{
|
||||
return mapping->m_machineCodeOffset;
|
||||
}
|
||||
};
|
||||
|
||||
class CompactJITCodeMap {
|
||||
WTF_MAKE_FAST_ALLOCATED;
|
||||
public:
|
||||
~CompactJITCodeMap()
|
||||
{
|
||||
if (m_buffer)
|
||||
fastFree(m_buffer);
|
||||
}
|
||||
|
||||
unsigned numberOfEntries() const
|
||||
{
|
||||
return m_numberOfEntries;
|
||||
}
|
||||
|
||||
void decode(Vector<BytecodeAndMachineOffset>& result) const;
|
||||
|
||||
private:
|
||||
CompactJITCodeMap(uint8_t* buffer, unsigned size, unsigned numberOfEntries)
|
||||
: m_buffer(buffer)
|
||||
#if !ASSERT_DISABLED
|
||||
, m_size(size)
|
||||
#endif
|
||||
, m_numberOfEntries(numberOfEntries)
|
||||
{
|
||||
UNUSED_PARAM(size);
|
||||
}
|
||||
|
||||
uint8_t at(unsigned index) const
|
||||
{
|
||||
ASSERT(index < m_size);
|
||||
return m_buffer[index];
|
||||
}
|
||||
|
||||
unsigned decodeNumber(unsigned& index) const
|
||||
{
|
||||
uint8_t headValue = at(index++);
|
||||
if (!(headValue & 128))
|
||||
return headValue;
|
||||
if (!(headValue & 64))
|
||||
return (static_cast<unsigned>(headValue & ~128) << 8) | at(index++);
|
||||
unsigned second = at(index++);
|
||||
unsigned third = at(index++);
|
||||
unsigned fourth = at(index++);
|
||||
return (static_cast<unsigned>(headValue & ~(128 + 64)) << 24) | (second << 16) | (third << 8) | fourth;
|
||||
}
|
||||
|
||||
uint8_t* m_buffer;
|
||||
#if !ASSERT_DISABLED
|
||||
unsigned m_size;
|
||||
#endif
|
||||
unsigned m_numberOfEntries;
|
||||
|
||||
public:
|
||||
class Encoder {
|
||||
WTF_MAKE_NONCOPYABLE(Encoder);
|
||||
public:
|
||||
Encoder();
|
||||
~Encoder();
|
||||
|
||||
void ensureCapacityFor(unsigned numberOfEntriesToAdd);
|
||||
void append(unsigned bytecodeIndex, unsigned machineCodeOffset);
|
||||
PassOwnPtr<CompactJITCodeMap> finish();
|
||||
|
||||
private:
|
||||
void appendByte(uint8_t value);
|
||||
void encodeNumber(uint32_t value);
|
||||
|
||||
uint8_t* m_buffer;
|
||||
unsigned m_size;
|
||||
unsigned m_capacity;
|
||||
unsigned m_numberOfEntries;
|
||||
|
||||
unsigned m_previousBytecodeIndex;
|
||||
unsigned m_previousMachineCodeOffset;
|
||||
};
|
||||
|
||||
class Decoder {
|
||||
WTF_MAKE_NONCOPYABLE(Decoder);
|
||||
public:
|
||||
Decoder(const CompactJITCodeMap*);
|
||||
|
||||
unsigned numberOfEntriesRemaining() const;
|
||||
void read(unsigned& bytecodeIndex, unsigned& machineCodeOffset);
|
||||
|
||||
private:
|
||||
const CompactJITCodeMap* m_jitCodeMap;
|
||||
unsigned m_previousBytecodeIndex;
|
||||
unsigned m_previousMachineCodeOffset;
|
||||
unsigned m_numberOfEntriesRemaining;
|
||||
unsigned m_bufferIndex;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class Encoder;
|
||||
friend class Decoder;
|
||||
};
|
||||
|
||||
inline void CompactJITCodeMap::decode(Vector<BytecodeAndMachineOffset>& result) const
|
||||
{
|
||||
Decoder decoder(this);
|
||||
result.resize(decoder.numberOfEntriesRemaining());
|
||||
for (unsigned i = 0; i < result.size(); ++i)
|
||||
decoder.read(result[i].m_bytecodeIndex, result[i].m_machineCodeOffset);
|
||||
|
||||
ASSERT(!decoder.numberOfEntriesRemaining());
|
||||
}
|
||||
|
||||
inline CompactJITCodeMap::Encoder::Encoder()
|
||||
: m_buffer(0)
|
||||
, m_size(0)
|
||||
, m_capacity(0)
|
||||
, m_numberOfEntries(0)
|
||||
, m_previousBytecodeIndex(0)
|
||||
, m_previousMachineCodeOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline CompactJITCodeMap::Encoder::~Encoder()
|
||||
{
|
||||
if (m_buffer)
|
||||
fastFree(m_buffer);
|
||||
}
|
||||
|
||||
inline void CompactJITCodeMap::Encoder::append(unsigned bytecodeIndex, unsigned machineCodeOffset)
|
||||
{
|
||||
ASSERT(bytecodeIndex >= m_previousBytecodeIndex);
|
||||
ASSERT(machineCodeOffset >= m_previousMachineCodeOffset);
|
||||
ensureCapacityFor(1);
|
||||
encodeNumber(bytecodeIndex - m_previousBytecodeIndex);
|
||||
encodeNumber(machineCodeOffset - m_previousMachineCodeOffset);
|
||||
m_previousBytecodeIndex = bytecodeIndex;
|
||||
m_previousMachineCodeOffset = machineCodeOffset;
|
||||
m_numberOfEntries++;
|
||||
}
|
||||
|
||||
inline PassOwnPtr<CompactJITCodeMap> CompactJITCodeMap::Encoder::finish()
|
||||
{
|
||||
m_capacity = m_size;
|
||||
m_buffer = static_cast<uint8_t*>(fastRealloc(m_buffer, m_capacity));
|
||||
OwnPtr<CompactJITCodeMap> result = adoptPtr(new CompactJITCodeMap(m_buffer, m_size, m_numberOfEntries));
|
||||
m_buffer = 0;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
m_numberOfEntries = 0;
|
||||
m_previousBytecodeIndex = 0;
|
||||
m_previousMachineCodeOffset = 0;
|
||||
return result.release();
|
||||
}
|
||||
|
||||
inline void CompactJITCodeMap::Encoder::appendByte(uint8_t value)
|
||||
{
|
||||
ASSERT(m_size + 1 <= m_capacity);
|
||||
m_buffer[m_size++] = value;
|
||||
}
|
||||
|
||||
inline void CompactJITCodeMap::Encoder::encodeNumber(uint32_t value)
|
||||
{
|
||||
ASSERT(m_size + 4 <= m_capacity);
|
||||
ASSERT(value < (1 << 30));
|
||||
if (value <= 127) {
|
||||
uint8_t headValue = static_cast<uint8_t>(value);
|
||||
ASSERT(!(headValue & 128));
|
||||
appendByte(headValue);
|
||||
} else if (value <= 16383) {
|
||||
uint8_t headValue = static_cast<uint8_t>(value >> 8);
|
||||
ASSERT(!(headValue & 128));
|
||||
ASSERT(!(headValue & 64));
|
||||
appendByte(headValue | 128);
|
||||
appendByte(static_cast<uint8_t>(value));
|
||||
} else {
|
||||
uint8_t headValue = static_cast<uint8_t>(value >> 24);
|
||||
ASSERT(!(headValue & 128));
|
||||
ASSERT(!(headValue & 64));
|
||||
appendByte(headValue | 128 | 64);
|
||||
appendByte(static_cast<uint8_t>(value >> 16));
|
||||
appendByte(static_cast<uint8_t>(value >> 8));
|
||||
appendByte(static_cast<uint8_t>(value));
|
||||
}
|
||||
}
|
||||
|
||||
inline void CompactJITCodeMap::Encoder::ensureCapacityFor(unsigned numberOfEntriesToAdd)
|
||||
{
|
||||
unsigned capacityNeeded = m_size + numberOfEntriesToAdd * 2 * 4;
|
||||
if (capacityNeeded > m_capacity) {
|
||||
m_capacity = capacityNeeded * 2;
|
||||
m_buffer = static_cast<uint8_t*>(fastRealloc(m_buffer, m_capacity));
|
||||
}
|
||||
}
|
||||
|
||||
inline CompactJITCodeMap::Decoder::Decoder(const CompactJITCodeMap* jitCodeMap)
|
||||
: m_jitCodeMap(jitCodeMap)
|
||||
, m_previousBytecodeIndex(0)
|
||||
, m_previousMachineCodeOffset(0)
|
||||
, m_numberOfEntriesRemaining(jitCodeMap->m_numberOfEntries)
|
||||
, m_bufferIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline unsigned CompactJITCodeMap::Decoder::numberOfEntriesRemaining() const
|
||||
{
|
||||
ASSERT(m_numberOfEntriesRemaining || m_bufferIndex == m_jitCodeMap->m_size);
|
||||
return m_numberOfEntriesRemaining;
|
||||
}
|
||||
|
||||
inline void CompactJITCodeMap::Decoder::read(unsigned& bytecodeIndex, unsigned& machineCodeOffset)
|
||||
{
|
||||
ASSERT(numberOfEntriesRemaining());
|
||||
|
||||
m_previousBytecodeIndex += m_jitCodeMap->decodeNumber(m_bufferIndex);
|
||||
m_previousMachineCodeOffset += m_jitCodeMap->decodeNumber(m_bufferIndex);
|
||||
bytecodeIndex = m_previousBytecodeIndex;
|
||||
machineCodeOffset = m_previousMachineCodeOffset;
|
||||
m_numberOfEntriesRemaining--;
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // CompactJITCodeMap_h
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011, 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_Compiler_h
|
||||
#define WTF_Compiler_h
|
||||
|
||||
/* COMPILER() - the compiler being used to build the project */
|
||||
#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE)
|
||||
|
||||
/* COMPILER_SUPPORTS() - whether the compiler being used to build the project supports the given feature. */
|
||||
#define COMPILER_SUPPORTS(WTF_COMPILER_FEATURE) (defined WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE && WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE)
|
||||
|
||||
/* ==== COMPILER() - the compiler being used to build the project ==== */
|
||||
|
||||
/* COMPILER(CLANG) - Clang */
|
||||
#if defined(__clang__)
|
||||
#define WTF_COMPILER_CLANG 1
|
||||
|
||||
#ifndef __has_extension
|
||||
#define __has_extension __has_feature /* Compatibility with older versions of clang */
|
||||
#endif
|
||||
|
||||
/* Specific compiler features */
|
||||
#define WTF_COMPILER_SUPPORTS_CXX_VARIADIC_TEMPLATES __has_feature(cxx_variadic_templates)
|
||||
#define WTF_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES __has_feature(cxx_rvalue_references)
|
||||
#define WTF_COMPILER_SUPPORTS_CXX_DELETED_FUNCTIONS __has_feature(cxx_deleted_functions)
|
||||
#define WTF_COMPILER_SUPPORTS_CXX_NULLPTR __has_feature(cxx_nullptr)
|
||||
#define WTF_COMPILER_SUPPORTS_BLOCKS __has_feature(blocks)
|
||||
|
||||
#endif
|
||||
|
||||
/* COMPILER(MSVC) - Microsoft Visual C++ */
|
||||
/* COMPILER(MSVC7_OR_LOWER) - Microsoft Visual C++ 2003 or lower*/
|
||||
/* COMPILER(MSVC9_OR_LOWER) - Microsoft Visual C++ 2008 or lower*/
|
||||
#if defined(_MSC_VER)
|
||||
#define WTF_COMPILER_MSVC 1
|
||||
#if _MSC_VER < 1400
|
||||
#define WTF_COMPILER_MSVC7_OR_LOWER 1
|
||||
#elif _MSC_VER < 1600
|
||||
#define WTF_COMPILER_MSVC9_OR_LOWER 1
|
||||
#endif
|
||||
|
||||
/* Specific compiler features */
|
||||
#if _MSC_VER >= 1600
|
||||
#define WTF_COMPILER_SUPPORTS_CXX_NULLPTR 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* COMPILER(RVCT) - ARM RealView Compilation Tools */
|
||||
/* COMPILER(RVCT4_OR_GREATER) - ARM RealView Compilation Tools 4.0 or greater */
|
||||
#if defined(__CC_ARM) || defined(__ARMCC__)
|
||||
#define WTF_COMPILER_RVCT 1
|
||||
#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) (__ARMCC_VERSION >= (major * 100000 + minor * 10000 + patch * 1000 + build))
|
||||
#else
|
||||
/* Define this for !RVCT compilers, just so we can write things like RVCT_VERSION_AT_LEAST(3, 0, 0, 0). */
|
||||
#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) 0
|
||||
#endif
|
||||
|
||||
/* COMPILER(GCCE) - GNU Compiler Collection for Embedded */
|
||||
#if defined(__GCCE__)
|
||||
#define WTF_COMPILER_GCCE 1
|
||||
#define GCCE_VERSION (__GCCE__ * 10000 + __GCCE_MINOR__ * 100 + __GCCE_PATCHLEVEL__)
|
||||
#define GCCE_VERSION_AT_LEAST(major, minor, patch) (GCCE_VERSION >= (major * 10000 + minor * 100 + patch))
|
||||
#endif
|
||||
|
||||
/* COMPILER(GCC) - GNU Compiler Collection */
|
||||
/* --gnu option of the RVCT compiler also defines __GNUC__ */
|
||||
#if defined(__GNUC__) && !COMPILER(RVCT)
|
||||
#define WTF_COMPILER_GCC 1
|
||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch))
|
||||
|
||||
/* Specific compiler features */
|
||||
#if !COMPILER(CLANG) && GCC_VERSION_AT_LEAST(4, 6, 0) && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
#define WTF_COMPILER_SUPPORTS_CXX_NULLPTR 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Define this for !GCC compilers, just so we can write things like GCC_VERSION_AT_LEAST(4, 1, 0). */
|
||||
#define GCC_VERSION_AT_LEAST(major, minor, patch) 0
|
||||
#endif
|
||||
|
||||
/* COMPILER(MINGW) - MinGW GCC */
|
||||
/* COMPILER(MINGW64) - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */
|
||||
#if defined(__MINGW32__)
|
||||
#define WTF_COMPILER_MINGW 1
|
||||
#include <_mingw.h> /* private MinGW header */
|
||||
#if defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */
|
||||
#define WTF_COMPILER_MINGW64 1
|
||||
#endif /* __MINGW64_VERSION_MAJOR */
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
/* COMPILER(INTEL) - Intel C++ Compiler */
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#define WTF_COMPILER_INTEL 1
|
||||
#endif
|
||||
|
||||
/* COMPILER(SUNCC) */
|
||||
#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
|
||||
#define WTF_COMPILER_SUNCC 1
|
||||
#endif
|
||||
|
||||
/* ==== Compiler features ==== */
|
||||
|
||||
|
||||
/* ALWAYS_INLINE */
|
||||
|
||||
#ifndef ALWAYS_INLINE
|
||||
#if COMPILER(GCC) && defined(NDEBUG) && !COMPILER(MINGW)
|
||||
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
|
||||
#elif (COMPILER(MSVC) || COMPILER(RVCT)) && defined(NDEBUG)
|
||||
#define ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
#define ALWAYS_INLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* NEVER_INLINE */
|
||||
|
||||
#ifndef NEVER_INLINE
|
||||
#if COMPILER(GCC)
|
||||
#define NEVER_INLINE __attribute__((__noinline__))
|
||||
#elif COMPILER(RVCT)
|
||||
#define NEVER_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define NEVER_INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* UNLIKELY */
|
||||
|
||||
#ifndef UNLIKELY
|
||||
#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(3, 0, 0, 0) && defined(__GNUC__))
|
||||
#define UNLIKELY(x) __builtin_expect((x), 0)
|
||||
#else
|
||||
#define UNLIKELY(x) (x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* LIKELY */
|
||||
|
||||
#ifndef LIKELY
|
||||
#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(3, 0, 0, 0) && defined(__GNUC__))
|
||||
#define LIKELY(x) __builtin_expect((x), 1)
|
||||
#else
|
||||
#define LIKELY(x) (x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* NO_RETURN */
|
||||
|
||||
|
||||
#ifndef NO_RETURN
|
||||
#if COMPILER(GCC)
|
||||
#define NO_RETURN __attribute((__noreturn__))
|
||||
#elif COMPILER(MSVC) || COMPILER(RVCT)
|
||||
#define NO_RETURN __declspec(noreturn)
|
||||
#else
|
||||
#define NO_RETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* NO_RETURN_WITH_VALUE */
|
||||
|
||||
#ifndef NO_RETURN_WITH_VALUE
|
||||
#if !COMPILER(MSVC)
|
||||
#define NO_RETURN_WITH_VALUE NO_RETURN
|
||||
#else
|
||||
#define NO_RETURN_WITH_VALUE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* WARN_UNUSED_RETURN */
|
||||
|
||||
#if COMPILER(GCC)
|
||||
#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
|
||||
#else
|
||||
#define WARN_UNUSED_RETURN
|
||||
#endif
|
||||
|
||||
/* OVERRIDE */
|
||||
|
||||
#ifndef OVERRIDE
|
||||
#if COMPILER(CLANG)
|
||||
#if __has_extension(cxx_override_control)
|
||||
#define OVERRIDE override
|
||||
#endif
|
||||
#elif COMPILER(MSVC)
|
||||
#define OVERRIDE override
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE
|
||||
#define OVERRIDE
|
||||
#endif
|
||||
|
||||
/* FINAL */
|
||||
|
||||
#ifndef FINAL
|
||||
#if COMPILER(CLANG)
|
||||
#if __has_extension(cxx_override_control)
|
||||
#define FINAL final
|
||||
#endif
|
||||
#elif COMPILER(MSVC)
|
||||
#define FINAL sealed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FINAL
|
||||
#define FINAL
|
||||
#endif
|
||||
|
||||
/* OBJC_CLASS */
|
||||
|
||||
#ifndef OBJC_CLASS
|
||||
#ifdef __OBJC__
|
||||
#define OBJC_CLASS @class
|
||||
#else
|
||||
#define OBJC_CLASS class
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* WTF_Compiler_h */
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
|
||||
* Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef Completion_h
|
||||
#define Completion_h
|
||||
|
||||
#include "JSValue.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ExecState;
|
||||
class ScopeChainNode;
|
||||
class SourceCode;
|
||||
|
||||
JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
|
||||
JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, ScopeChainNode*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // Completion_h
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Google 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_Complex_h
|
||||
#define WTF_Complex_h
|
||||
|
||||
#include <complex>
|
||||
#include <wtf/MathExtras.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
typedef std::complex<double> Complex;
|
||||
|
||||
inline Complex complexFromMagnitudePhase(double magnitude, double phase)
|
||||
{
|
||||
return Complex(magnitude * cos(phase), magnitude * sin(phase));
|
||||
}
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::Complex;
|
||||
using WTF::complexFromMagnitudePhase;
|
||||
|
||||
#endif // WTF_Complex_h
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef ConservativeRoots_h
|
||||
#define ConservativeRoots_h
|
||||
|
||||
#include "Heap.h"
|
||||
#include <wtf/OSAllocator.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class JSCell;
|
||||
class DFGCodeBlocks;
|
||||
class Heap;
|
||||
|
||||
class ConservativeRoots {
|
||||
public:
|
||||
ConservativeRoots(const MarkedBlockSet*, BumpSpace*);
|
||||
~ConservativeRoots();
|
||||
|
||||
void add(void* begin, void* end);
|
||||
void add(void* begin, void* end, DFGCodeBlocks&);
|
||||
|
||||
size_t size();
|
||||
JSCell** roots();
|
||||
|
||||
private:
|
||||
static const size_t inlineCapacity = 128;
|
||||
static const size_t nonInlineCapacity = 8192 / sizeof(JSCell*);
|
||||
|
||||
template<typename MarkHook>
|
||||
void genericAddPointer(void*, TinyBloomFilter, MarkHook&);
|
||||
|
||||
template<typename MarkHook>
|
||||
void genericAddSpan(void*, void* end, MarkHook&);
|
||||
|
||||
void grow();
|
||||
|
||||
JSCell** m_roots;
|
||||
size_t m_size;
|
||||
size_t m_capacity;
|
||||
const MarkedBlockSet* m_blocks;
|
||||
BumpSpace* m_bumpSpace;
|
||||
JSCell* m_inlineRoots[inlineCapacity];
|
||||
};
|
||||
|
||||
inline size_t ConservativeRoots::size()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline JSCell** ConservativeRoots::roots()
|
||||
{
|
||||
return m_roots;
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // ConservativeRoots_h
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef ConstructData_h
|
||||
#define ConstructData_h
|
||||
|
||||
#include "CallData.h"
|
||||
#include "JSValue.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ArgList;
|
||||
class ExecState;
|
||||
class FunctionExecutable;
|
||||
class JSObject;
|
||||
class ScopeChainNode;
|
||||
|
||||
enum ConstructType {
|
||||
ConstructTypeNone,
|
||||
ConstructTypeHost,
|
||||
ConstructTypeJS
|
||||
};
|
||||
|
||||
union ConstructData {
|
||||
struct {
|
||||
NativeFunction function;
|
||||
} native;
|
||||
struct {
|
||||
FunctionExecutable* functionExecutable;
|
||||
ScopeChainNode* scopeChain;
|
||||
} js;
|
||||
};
|
||||
|
||||
JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // ConstructData_h
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
|
||||
*
|
||||
* 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 COMPUTER, 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 COMPUTER, 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_CryptographicallyRandomNumber_h
|
||||
#define WTF_CryptographicallyRandomNumber_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
#if USE(OS_RANDOMNESS)
|
||||
WTF_EXPORT_PRIVATE uint32_t cryptographicallyRandomNumber();
|
||||
WTF_EXPORT_PRIVATE void cryptographicallyRandomValues(void* buffer, size_t length);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if USE(OS_RANDOMNESS)
|
||||
using WTF::cryptographicallyRandomNumber;
|
||||
using WTF::cryptographicallyRandomValues;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (C) 2008 Google 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 THE COPYRIGHT
|
||||
* OWNER 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.
|
||||
*/
|
||||
|
||||
#ifndef CurrentTime_h
|
||||
#define CurrentTime_h
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// Returns the current UTC time in seconds, counted from January 1, 1970.
|
||||
// Precision varies depending on platform but is usually as good or better
|
||||
// than a millisecond.
|
||||
WTF_EXPORT_PRIVATE double currentTime();
|
||||
|
||||
// Same thing, in milliseconds.
|
||||
inline double currentTimeMS()
|
||||
{
|
||||
return currentTime() * 1000.0;
|
||||
}
|
||||
|
||||
inline void getLocalTime(const time_t* localTime, struct tm* localTM)
|
||||
{
|
||||
#if COMPILER(MSVC7_OR_LOWER) || COMPILER(MINGW) || OS(WINCE)
|
||||
*localTM = *localtime(localTime);
|
||||
#elif COMPILER(MSVC)
|
||||
localtime_s(localTM, localTime);
|
||||
#else
|
||||
localtime_r(localTime, localTM);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Provides a monotonically increasing time in seconds since an arbitrary point in the past.
|
||||
// On unsupported platforms, this function only guarantees the result will be non-decreasing.
|
||||
WTF_EXPORT_PRIVATE double monotonicallyIncreasingTime();
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::currentTime;
|
||||
using WTF::currentTimeMS;
|
||||
using WTF::getLocalTime;
|
||||
using WTF::monotonicallyIncreasingTime;
|
||||
|
||||
#endif // CurrentTime_h
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGAbstractState_h
|
||||
#define DFGAbstractState_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "DFGAbstractValue.h"
|
||||
#include "DFGGraph.h"
|
||||
#include "DFGNode.h"
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class CodeBlock;
|
||||
|
||||
namespace DFG {
|
||||
|
||||
struct BasicBlock;
|
||||
|
||||
// This implements the notion of an abstract state for flow-sensitive intraprocedural
|
||||
// control flow analysis (CFA), with a focus on the elimination of redundant type checks.
|
||||
// It also implements most of the mechanisms of abstract interpretation that such an
|
||||
// analysis would use. This class should be used in two idioms:
|
||||
//
|
||||
// 1) Performing the CFA. In this case, AbstractState should be run over all basic
|
||||
// blocks repeatedly until convergence is reached. Convergence is defined by
|
||||
// endBasicBlock(AbstractState::MergeToSuccessors) returning false for all blocks.
|
||||
//
|
||||
// 2) Rematerializing the results of a previously executed CFA. In this case,
|
||||
// AbstractState should be run over whatever basic block you're interested in up
|
||||
// to the point of the node at which you'd like to interrogate the known type
|
||||
// of all other nodes. At this point it's safe to discard the AbstractState entirely,
|
||||
// call reset(), or to run it to the end of the basic block and call
|
||||
// endBasicBlock(AbstractState::DontMerge). The latter option is safest because
|
||||
// it performs some useful integrity checks.
|
||||
//
|
||||
// After the CFA is run, the inter-block state is saved at the heads and tails of all
|
||||
// basic blocks. This allows the intra-block state to be rematerialized by just
|
||||
// executing the CFA for that block. If you need to know inter-block state only, then
|
||||
// you only need to examine the BasicBlock::m_valuesAtHead or m_valuesAtTail fields.
|
||||
//
|
||||
// Running this analysis involves the following, modulo the inter-block state
|
||||
// merging and convergence fixpoint:
|
||||
//
|
||||
// AbstractState state(codeBlock, graph);
|
||||
// state.beginBasicBlock(basicBlock);
|
||||
// bool endReached = true;
|
||||
// for (NodeIndex idx = basicBlock.begin; idx < basicBlock.end; ++idx) {
|
||||
// if (!state.execute(idx))
|
||||
// break;
|
||||
// }
|
||||
// bool result = state.endBasicBlock(<either Merge or DontMerge>);
|
||||
|
||||
class AbstractState {
|
||||
public:
|
||||
enum MergeMode {
|
||||
// Don't merge the state in AbstractState with basic blocks.
|
||||
DontMerge,
|
||||
|
||||
// Merge the state in AbstractState with the tail of the basic
|
||||
// block being analyzed.
|
||||
MergeToTail,
|
||||
|
||||
// Merge the state in AbstractState with the tail of the basic
|
||||
// block, and with the heads of successor blocks.
|
||||
MergeToSuccessors
|
||||
};
|
||||
|
||||
AbstractState(CodeBlock*, Graph&);
|
||||
|
||||
~AbstractState();
|
||||
|
||||
AbstractValue& forNode(NodeIndex nodeIndex)
|
||||
{
|
||||
return m_nodes[nodeIndex - m_block->begin];
|
||||
}
|
||||
|
||||
// Call this before beginning CFA to initialize the abstract values of
|
||||
// arguments, and to indicate which blocks should be listed for CFA
|
||||
// execution.
|
||||
static void initialize(Graph&);
|
||||
|
||||
// Start abstractly executing the given basic block. Initializes the
|
||||
// notion of abstract state to what we believe it to be at the head
|
||||
// of the basic block, according to the basic block's data structures.
|
||||
// This method also sets cfaShouldRevisit to false.
|
||||
void beginBasicBlock(BasicBlock*);
|
||||
|
||||
// Finish abstractly executing a basic block. If MergeToTail or
|
||||
// MergeToSuccessors is passed, then this merges everything we have
|
||||
// learned about how the state changes during this block's execution into
|
||||
// the block's data structures. There are three return modes, depending
|
||||
// on the value of mergeMode:
|
||||
//
|
||||
// DontMerge:
|
||||
// Always returns false.
|
||||
//
|
||||
// MergeToTail:
|
||||
// Returns true if the state of the block at the tail was changed.
|
||||
// This means that you must call mergeToSuccessors(), and if that
|
||||
// returns true, then you must revisit (at least) the successor
|
||||
// blocks. False will always be returned if the block is terminal
|
||||
// (i.e. ends in Throw or Return, or has a ForceOSRExit inside it).
|
||||
//
|
||||
// MergeToSuccessors:
|
||||
// Returns true if the state of the block at the tail was changed,
|
||||
// and, if the state at the heads of successors was changed.
|
||||
// A true return means that you must revisit (at least) the successor
|
||||
// blocks. This also sets cfaShouldRevisit to true for basic blocks
|
||||
// that must be visited next.
|
||||
bool endBasicBlock(MergeMode);
|
||||
|
||||
// Reset the AbstractState. This throws away any results, and at this point
|
||||
// you can safely call beginBasicBlock() on any basic block.
|
||||
void reset();
|
||||
|
||||
// Abstractly executes the given node. The new abstract state is stored into an
|
||||
// abstract register file stored in *this. Loads of local variables (that span
|
||||
// basic blocks) interrogate the basic block's notion of the state at the head.
|
||||
// Stores to local variables are handled in endBasicBlock(). This returns true
|
||||
// if execution should continue past this node. Notably, it will return true
|
||||
// for block terminals, so long as those terminals are not Return or variants
|
||||
// of Throw.
|
||||
bool execute(NodeIndex);
|
||||
|
||||
// Is the execution state still valid? This will be false if execute() has
|
||||
// returned false previously.
|
||||
bool isValid() const { return m_isValid; }
|
||||
|
||||
// Merge the abstract state stored at the first block's tail into the second
|
||||
// block's head. Returns true if the second block's state changed. If so,
|
||||
// that block must be abstractly interpreted again. This also sets
|
||||
// to->cfaShouldRevisit to true, if it returns true, or if to has not been
|
||||
// visited yet.
|
||||
static bool merge(BasicBlock* from, BasicBlock* to);
|
||||
|
||||
// Merge the abstract state stored at the block's tail into all of its
|
||||
// successors. Returns true if any of the successors' states changed. Note
|
||||
// that this is automatically called in endBasicBlock() if MergeMode is
|
||||
// MergeToSuccessors.
|
||||
static bool mergeToSuccessors(Graph&, BasicBlock*);
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump(FILE* out);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void clobberStructures(NodeIndex);
|
||||
|
||||
bool mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex);
|
||||
|
||||
static bool mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, NodeIndex destinationNodeIndex, NodeIndex sourceNodeIndex);
|
||||
|
||||
CodeBlock* m_codeBlock;
|
||||
Graph& m_graph;
|
||||
|
||||
Vector<AbstractValue, 32> m_nodes;
|
||||
Operands<AbstractValue> m_variables;
|
||||
BasicBlock* m_block;
|
||||
bool m_haveStructures;
|
||||
|
||||
bool m_isValid;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGAbstractState_h
|
||||
|
||||
@@ -1,488 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGAbstractValue_h
|
||||
#define DFGAbstractValue_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "JSCell.h"
|
||||
#include "PredictedType.h"
|
||||
#include "StructureSet.h"
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
class StructureAbstractValue {
|
||||
public:
|
||||
StructureAbstractValue()
|
||||
: m_structure(0)
|
||||
{
|
||||
}
|
||||
|
||||
StructureAbstractValue(Structure* structure)
|
||||
: m_structure(structure)
|
||||
{
|
||||
}
|
||||
|
||||
StructureAbstractValue(const StructureSet& set)
|
||||
{
|
||||
switch (set.size()) {
|
||||
case 0:
|
||||
m_structure = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_structure = set[0];
|
||||
break;
|
||||
|
||||
default:
|
||||
m_structure = topValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_structure = 0;
|
||||
}
|
||||
|
||||
void makeTop()
|
||||
{
|
||||
m_structure = topValue();
|
||||
}
|
||||
|
||||
static StructureAbstractValue top()
|
||||
{
|
||||
StructureAbstractValue value;
|
||||
value.makeTop();
|
||||
return value;
|
||||
}
|
||||
|
||||
void add(Structure* structure)
|
||||
{
|
||||
ASSERT(!contains(structure) && !isTop());
|
||||
if (m_structure)
|
||||
makeTop();
|
||||
else
|
||||
m_structure = structure;
|
||||
}
|
||||
|
||||
bool addAll(const StructureSet& other)
|
||||
{
|
||||
if (isTop() || !other.size())
|
||||
return false;
|
||||
if (other.size() > 1) {
|
||||
makeTop();
|
||||
return true;
|
||||
}
|
||||
if (!m_structure) {
|
||||
m_structure = other[0];
|
||||
return true;
|
||||
}
|
||||
if (m_structure == other[0])
|
||||
return false;
|
||||
makeTop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool addAll(const StructureAbstractValue& other)
|
||||
{
|
||||
if (!other.m_structure)
|
||||
return false;
|
||||
if (isTop())
|
||||
return false;
|
||||
if (other.isTop()) {
|
||||
makeTop();
|
||||
return true;
|
||||
}
|
||||
if (m_structure) {
|
||||
if (m_structure == other.m_structure)
|
||||
return false;
|
||||
makeTop();
|
||||
return true;
|
||||
}
|
||||
m_structure = other.m_structure;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool contains(Structure* structure) const
|
||||
{
|
||||
if (isTop())
|
||||
return true;
|
||||
if (m_structure == structure)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSubsetOf(const StructureSet& other) const
|
||||
{
|
||||
if (isTop())
|
||||
return false;
|
||||
if (!m_structure)
|
||||
return true;
|
||||
return other.contains(m_structure);
|
||||
}
|
||||
|
||||
bool doesNotContainAnyOtherThan(Structure* structure) const
|
||||
{
|
||||
if (isTop())
|
||||
return false;
|
||||
if (!m_structure)
|
||||
return true;
|
||||
return m_structure == structure;
|
||||
}
|
||||
|
||||
bool isSupersetOf(const StructureSet& other) const
|
||||
{
|
||||
if (isTop())
|
||||
return true;
|
||||
if (!other.size())
|
||||
return true;
|
||||
if (other.size() > 1)
|
||||
return false;
|
||||
return m_structure == other[0];
|
||||
}
|
||||
|
||||
bool isSubsetOf(const StructureAbstractValue& other) const
|
||||
{
|
||||
if (other.isTop())
|
||||
return true;
|
||||
if (isTop())
|
||||
return false;
|
||||
if (m_structure) {
|
||||
if (other.m_structure)
|
||||
return m_structure == other.m_structure;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isSupersetOf(const StructureAbstractValue& other) const
|
||||
{
|
||||
return other.isSubsetOf(*this);
|
||||
}
|
||||
|
||||
void filter(const StructureSet& other)
|
||||
{
|
||||
if (!m_structure)
|
||||
return;
|
||||
|
||||
if (isTop()) {
|
||||
switch (other.size()) {
|
||||
case 0:
|
||||
m_structure = 0;
|
||||
return;
|
||||
|
||||
case 1:
|
||||
m_structure = other[0];
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (other.contains(m_structure))
|
||||
return;
|
||||
|
||||
m_structure = 0;
|
||||
}
|
||||
|
||||
void filter(const StructureAbstractValue& other)
|
||||
{
|
||||
if (isTop()) {
|
||||
m_structure = other.m_structure;
|
||||
return;
|
||||
}
|
||||
if (m_structure == other.m_structure)
|
||||
return;
|
||||
if (other.isTop())
|
||||
return;
|
||||
m_structure = 0;
|
||||
}
|
||||
|
||||
void filter(PredictedType other)
|
||||
{
|
||||
if (!(other & PredictCell)) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isClearOrTop())
|
||||
return;
|
||||
|
||||
if (!(predictionFromStructure(m_structure) & other))
|
||||
m_structure = 0;
|
||||
}
|
||||
|
||||
bool isClear() const
|
||||
{
|
||||
return !m_structure;
|
||||
}
|
||||
|
||||
bool isTop() const { return m_structure == topValue(); }
|
||||
|
||||
bool isClearOrTop() const { return m_structure <= topValue(); }
|
||||
bool isNeitherClearNorTop() const { return !isClearOrTop(); }
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
ASSERT(!isTop());
|
||||
return !!m_structure;
|
||||
}
|
||||
|
||||
Structure* at(size_t i) const
|
||||
{
|
||||
ASSERT(!isTop());
|
||||
ASSERT(m_structure);
|
||||
ASSERT_UNUSED(i, !i);
|
||||
return m_structure;
|
||||
}
|
||||
|
||||
Structure* operator[](size_t i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
Structure* last() const
|
||||
{
|
||||
return at(0);
|
||||
}
|
||||
|
||||
PredictedType predictionFromStructures() const
|
||||
{
|
||||
if (isTop())
|
||||
return PredictCell;
|
||||
if (isClear())
|
||||
return PredictNone;
|
||||
return predictionFromStructure(m_structure);
|
||||
}
|
||||
|
||||
bool operator==(const StructureAbstractValue& other) const
|
||||
{
|
||||
return m_structure == other.m_structure;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump(FILE* out) const
|
||||
{
|
||||
if (isTop()) {
|
||||
fprintf(out, "TOP");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(out, "[");
|
||||
if (m_structure)
|
||||
fprintf(out, "%p", m_structure);
|
||||
fprintf(out, "]");
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
static Structure* topValue() { return reinterpret_cast<Structure*>(1); }
|
||||
|
||||
// This can only remember one structure at a time.
|
||||
Structure* m_structure;
|
||||
};
|
||||
|
||||
struct AbstractValue {
|
||||
AbstractValue()
|
||||
: m_type(PredictNone)
|
||||
{
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_type = PredictNone;
|
||||
m_structure.clear();
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
bool isClear()
|
||||
{
|
||||
return m_type == PredictNone && m_structure.isClear();
|
||||
}
|
||||
|
||||
void makeTop()
|
||||
{
|
||||
m_type = PredictTop;
|
||||
m_structure.makeTop();
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
void clobberStructures()
|
||||
{
|
||||
if (m_type & PredictCell)
|
||||
m_structure.makeTop();
|
||||
else
|
||||
ASSERT(m_structure.isClear());
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
bool isTop() const
|
||||
{
|
||||
return m_type == PredictTop && m_structure.isTop();
|
||||
}
|
||||
|
||||
static AbstractValue top()
|
||||
{
|
||||
AbstractValue result;
|
||||
result.makeTop();
|
||||
return result;
|
||||
}
|
||||
|
||||
void set(JSValue value)
|
||||
{
|
||||
m_structure.clear();
|
||||
if (value.isCell())
|
||||
m_structure.add(value.asCell()->structure());
|
||||
|
||||
m_type = predictionFromValue(value);
|
||||
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
void set(Structure* structure)
|
||||
{
|
||||
m_structure.clear();
|
||||
m_structure.add(structure);
|
||||
|
||||
m_type = predictionFromStructure(structure);
|
||||
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
void set(PredictedType type)
|
||||
{
|
||||
if (type & PredictCell)
|
||||
m_structure.makeTop();
|
||||
else
|
||||
m_structure.clear();
|
||||
m_type = type;
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
bool operator==(const AbstractValue& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_structure == other.m_structure;
|
||||
}
|
||||
|
||||
bool merge(const AbstractValue& other)
|
||||
{
|
||||
bool result = mergePrediction(m_type, other.m_type) | m_structure.addAll(other.m_structure);
|
||||
checkConsistency();
|
||||
return result;
|
||||
}
|
||||
|
||||
void merge(PredictedType type)
|
||||
{
|
||||
mergePrediction(m_type, type);
|
||||
|
||||
if (type & PredictCell)
|
||||
m_structure.makeTop();
|
||||
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
void filter(const StructureSet& other)
|
||||
{
|
||||
m_type &= other.predictionFromStructures();
|
||||
m_structure.filter(other);
|
||||
|
||||
// It's possible that prior to the above two statements we had (Foo, TOP), where
|
||||
// Foo is a PredictedType that is disjoint with the passed StructureSet. In that
|
||||
// case, we will now have (None, [someStructure]). In general, we need to make
|
||||
// sure that new information gleaned from the PredictedType needs to be fed back
|
||||
// into the information gleaned from the StructureSet.
|
||||
m_structure.filter(m_type);
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
void filter(PredictedType type)
|
||||
{
|
||||
if (type == PredictTop)
|
||||
return;
|
||||
m_type &= type;
|
||||
|
||||
// It's possible that prior to this filter() call we had, say, (Final, TOP), and
|
||||
// the passed type is Array. At this point we'll have (None, TOP). The best way
|
||||
// to ensure that the structure filtering does the right thing is to filter on
|
||||
// the new type (None) rather than the one passed (Array).
|
||||
m_structure.filter(m_type);
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
bool validate(JSValue value) const
|
||||
{
|
||||
if (isTop())
|
||||
return true;
|
||||
|
||||
if (mergePredictions(m_type, predictionFromValue(value)) != m_type)
|
||||
return false;
|
||||
|
||||
if (m_structure.isTop())
|
||||
return true;
|
||||
|
||||
if (value.isCell()) {
|
||||
ASSERT(m_type & PredictCell);
|
||||
return m_structure.contains(value.asCell()->structure());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void checkConsistency() const
|
||||
{
|
||||
if (!(m_type & PredictCell))
|
||||
ASSERT(m_structure.isClear());
|
||||
|
||||
// Note that it's possible for a prediction like (Final, []). This really means that
|
||||
// the value is bottom and that any code that uses the value is unreachable. But
|
||||
// we don't want to get pedantic about this as it would only increase the computational
|
||||
// complexity of the code.
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump(FILE* out) const
|
||||
{
|
||||
fprintf(out, "(%s, ", predictionToString(m_type));
|
||||
m_structure.dump(out);
|
||||
fprintf(out, ")");
|
||||
}
|
||||
#endif
|
||||
|
||||
StructureAbstractValue m_structure;
|
||||
PredictedType m_type;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGAbstractValue_h
|
||||
|
||||
|
||||
@@ -1,331 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGAssemblyHelpers_h
|
||||
#define DFGAssemblyHelpers_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "CodeBlock.h"
|
||||
#include "DFGFPRInfo.h"
|
||||
#include "DFGGPRInfo.h"
|
||||
#include "DFGNode.h"
|
||||
#include "JSGlobalData.h"
|
||||
#include "MacroAssembler.h"
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
#ifndef NDEBUG
|
||||
typedef void (*V_DFGDebugOperation_EP)(ExecState*, void*);
|
||||
#endif
|
||||
|
||||
class AssemblyHelpers : public MacroAssembler {
|
||||
public:
|
||||
AssemblyHelpers(JSGlobalData* globalData, CodeBlock* codeBlock)
|
||||
: m_globalData(globalData)
|
||||
, m_codeBlock(codeBlock)
|
||||
, m_baselineCodeBlock(codeBlock->baselineVersion())
|
||||
{
|
||||
ASSERT(m_codeBlock);
|
||||
ASSERT(m_baselineCodeBlock);
|
||||
ASSERT(!m_baselineCodeBlock->alternative());
|
||||
ASSERT(m_baselineCodeBlock->getJITType() == JITCode::BaselineJIT);
|
||||
}
|
||||
|
||||
CodeBlock* codeBlock() { return m_codeBlock; }
|
||||
JSGlobalData* globalData() { return m_globalData; }
|
||||
AssemblerType_T& assembler() { return m_assembler; }
|
||||
|
||||
#if CPU(X86_64) || CPU(X86)
|
||||
void preserveReturnAddressAfterCall(GPRReg reg)
|
||||
{
|
||||
pop(reg);
|
||||
}
|
||||
|
||||
void restoreReturnAddressBeforeReturn(GPRReg reg)
|
||||
{
|
||||
push(reg);
|
||||
}
|
||||
|
||||
void restoreReturnAddressBeforeReturn(Address address)
|
||||
{
|
||||
push(address);
|
||||
}
|
||||
#endif // CPU(X86_64) || CPU(X86)
|
||||
|
||||
#if CPU(ARM)
|
||||
ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
|
||||
{
|
||||
move(linkRegister, reg);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void restoreReturnAddressBeforeReturn(RegisterID reg)
|
||||
{
|
||||
move(reg, linkRegister);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void restoreReturnAddressBeforeReturn(Address address)
|
||||
{
|
||||
loadPtr(address, linkRegister);
|
||||
}
|
||||
#endif
|
||||
|
||||
void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, GPRReg to)
|
||||
{
|
||||
loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
|
||||
}
|
||||
void emitPutToCallFrameHeader(GPRReg from, RegisterFile::CallFrameHeaderEntry entry)
|
||||
{
|
||||
storePtr(from, Address(GPRInfo::callFrameRegister, entry * sizeof(Register)));
|
||||
}
|
||||
|
||||
void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
|
||||
{
|
||||
storePtr(TrustedImmPtr(value), Address(GPRInfo::callFrameRegister, entry * sizeof(Register)));
|
||||
}
|
||||
|
||||
Jump branchIfNotCell(GPRReg reg)
|
||||
{
|
||||
#if USE(JSVALUE64)
|
||||
return branchTestPtr(MacroAssembler::NonZero, reg, GPRInfo::tagMaskRegister);
|
||||
#else
|
||||
return branch32(MacroAssembler::NotEqual, reg, TrustedImm32(JSValue::CellTag));
|
||||
#endif
|
||||
}
|
||||
|
||||
static Address addressForGlobalVar(GPRReg global, int32_t varNumber)
|
||||
{
|
||||
return Address(global, varNumber * sizeof(Register));
|
||||
}
|
||||
|
||||
static Address tagForGlobalVar(GPRReg global, int32_t varNumber)
|
||||
{
|
||||
return Address(global, varNumber * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
|
||||
}
|
||||
|
||||
static Address payloadForGlobalVar(GPRReg global, int32_t varNumber)
|
||||
{
|
||||
return Address(global, varNumber * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
|
||||
}
|
||||
|
||||
static Address addressFor(VirtualRegister virtualRegister)
|
||||
{
|
||||
return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register));
|
||||
}
|
||||
|
||||
static Address tagFor(VirtualRegister virtualRegister)
|
||||
{
|
||||
return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
|
||||
}
|
||||
|
||||
static Address payloadFor(VirtualRegister virtualRegister)
|
||||
{
|
||||
return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
|
||||
}
|
||||
|
||||
Jump branchIfNotObject(GPRReg structureReg)
|
||||
{
|
||||
return branch8(Below, Address(structureReg, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Add a debug call. This call has no effect on JIT code execution state.
|
||||
void debugCall(V_DFGDebugOperation_EP function, void* argument)
|
||||
{
|
||||
EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_globalData->scratchBufferForSize(sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters)));
|
||||
|
||||
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
|
||||
storePtr(GPRInfo::toRegister(i), buffer + i);
|
||||
for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
|
||||
move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
|
||||
storeDouble(FPRInfo::toRegister(i), GPRInfo::regT0);
|
||||
}
|
||||
#if CPU(X86_64) || CPU(ARM_THUMB2)
|
||||
move(TrustedImmPtr(argument), GPRInfo::argumentGPR1);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
#elif CPU(X86)
|
||||
poke(GPRInfo::callFrameRegister, 0);
|
||||
poke(TrustedImmPtr(argument), 1);
|
||||
#else
|
||||
#error "DFG JIT not supported on this platform."
|
||||
#endif
|
||||
move(TrustedImmPtr(reinterpret_cast<void*>(function)), GPRInfo::regT0);
|
||||
call(GPRInfo::regT0);
|
||||
for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
|
||||
move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
|
||||
loadDouble(GPRInfo::regT0, FPRInfo::toRegister(i));
|
||||
}
|
||||
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
|
||||
loadPtr(buffer + i, GPRInfo::toRegister(i));
|
||||
}
|
||||
#endif
|
||||
|
||||
// These methods JIT generate dynamic, debug-only checks - akin to ASSERTs.
|
||||
#if DFG_ENABLE(JIT_ASSERT)
|
||||
void jitAssertIsInt32(GPRReg);
|
||||
void jitAssertIsJSInt32(GPRReg);
|
||||
void jitAssertIsJSNumber(GPRReg);
|
||||
void jitAssertIsJSDouble(GPRReg);
|
||||
void jitAssertIsCell(GPRReg);
|
||||
#else
|
||||
void jitAssertIsInt32(GPRReg) { }
|
||||
void jitAssertIsJSInt32(GPRReg) { }
|
||||
void jitAssertIsJSNumber(GPRReg) { }
|
||||
void jitAssertIsJSDouble(GPRReg) { }
|
||||
void jitAssertIsCell(GPRReg) { }
|
||||
#endif
|
||||
|
||||
// These methods convert between doubles, and doubles boxed and JSValues.
|
||||
#if USE(JSVALUE64)
|
||||
GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
|
||||
{
|
||||
moveDoubleToPtr(fpr, gpr);
|
||||
subPtr(GPRInfo::tagTypeNumberRegister, gpr);
|
||||
jitAssertIsJSDouble(gpr);
|
||||
return gpr;
|
||||
}
|
||||
FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
|
||||
{
|
||||
jitAssertIsJSDouble(gpr);
|
||||
addPtr(GPRInfo::tagTypeNumberRegister, gpr);
|
||||
movePtrToDouble(gpr, fpr);
|
||||
return fpr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE(JSVALUE32_64) && CPU(X86)
|
||||
void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
|
||||
{
|
||||
movePackedToInt32(fpr, payloadGPR);
|
||||
rshiftPacked(TrustedImm32(32), fpr);
|
||||
movePackedToInt32(fpr, tagGPR);
|
||||
}
|
||||
void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
|
||||
{
|
||||
jitAssertIsJSDouble(tagGPR);
|
||||
moveInt32ToPacked(payloadGPR, fpr);
|
||||
moveInt32ToPacked(tagGPR, scratchFPR);
|
||||
lshiftPacked(TrustedImm32(32), scratchFPR);
|
||||
orPacked(scratchFPR, fpr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE(JSVALUE32_64) && CPU(ARM)
|
||||
void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
|
||||
{
|
||||
m_assembler.vmov(payloadGPR, tagGPR, fpr);
|
||||
}
|
||||
void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
|
||||
{
|
||||
jitAssertIsJSDouble(tagGPR);
|
||||
UNUSED_PARAM(scratchFPR);
|
||||
m_assembler.vmov(fpr, payloadGPR, tagGPR);
|
||||
}
|
||||
#endif
|
||||
|
||||
enum ExceptionCheckKind { NormalExceptionCheck, InvertedExceptionCheck };
|
||||
Jump emitExceptionCheck(ExceptionCheckKind kind = NormalExceptionCheck)
|
||||
{
|
||||
#if USE(JSVALUE64)
|
||||
return branchTestPtr(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(&globalData()->exception));
|
||||
#elif USE(JSVALUE32_64)
|
||||
return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(&globalData()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLE(SAMPLING_COUNTERS)
|
||||
static void emitCount(MacroAssembler& jit, AbstractSamplingCounter& counter, int32_t increment = 1)
|
||||
{
|
||||
jit.add64(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
|
||||
}
|
||||
void emitCount(AbstractSamplingCounter& counter, int32_t increment = 1)
|
||||
{
|
||||
add64(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE(SAMPLING_FLAGS)
|
||||
void setSamplingFlag(int32_t);
|
||||
void clearSamplingFlag(int32_t flag);
|
||||
#endif
|
||||
|
||||
JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin)
|
||||
{
|
||||
return codeBlock()->globalObjectFor(codeOrigin);
|
||||
}
|
||||
|
||||
JSObject* globalThisObjectFor(CodeOrigin codeOrigin)
|
||||
{
|
||||
JSGlobalObject* object = globalObjectFor(codeOrigin);
|
||||
return object->methodTable()->toThisObject(object, 0);
|
||||
}
|
||||
|
||||
bool strictModeFor(CodeOrigin codeOrigin)
|
||||
{
|
||||
if (!codeOrigin.inlineCallFrame)
|
||||
return codeBlock()->isStrictMode();
|
||||
return codeOrigin.inlineCallFrame->callee->jsExecutable()->isStrictMode();
|
||||
}
|
||||
|
||||
static CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
|
||||
{
|
||||
if (codeOrigin.inlineCallFrame) {
|
||||
ExecutableBase* executable = codeOrigin.inlineCallFrame->executable.get();
|
||||
ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info);
|
||||
return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
|
||||
}
|
||||
return baselineCodeBlock;
|
||||
}
|
||||
|
||||
CodeBlock* baselineCodeBlockFor(const CodeOrigin& codeOrigin)
|
||||
{
|
||||
return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock());
|
||||
}
|
||||
|
||||
CodeBlock* baselineCodeBlock()
|
||||
{
|
||||
return m_baselineCodeBlock;
|
||||
}
|
||||
|
||||
Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
|
||||
|
||||
static const double twoToThe32;
|
||||
|
||||
protected:
|
||||
JSGlobalData* m_globalData;
|
||||
CodeBlock* m_codeBlock;
|
||||
CodeBlock* m_baselineCodeBlock;
|
||||
|
||||
HashMap<CodeBlock*, Vector<BytecodeAndMachineOffset> > m_decodedCodeMaps;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGAssemblyHelpers_h
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGBasicBlock_h
|
||||
#define DFGBasicBlock_h
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "DFGAbstractValue.h"
|
||||
#include "DFGNode.h"
|
||||
#include "DFGOperands.h"
|
||||
#include <wtf/OwnPtr.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
typedef Vector <BlockIndex, 2> PredecessorList;
|
||||
|
||||
struct BasicBlock {
|
||||
BasicBlock(unsigned bytecodeBegin, NodeIndex begin, unsigned numArguments, unsigned numLocals)
|
||||
: bytecodeBegin(bytecodeBegin)
|
||||
, begin(begin)
|
||||
, end(NoNode)
|
||||
, isOSRTarget(false)
|
||||
, cfaHasVisited(false)
|
||||
, cfaShouldRevisit(false)
|
||||
#if !ASSERT_DISABLED
|
||||
, isLinked(false)
|
||||
#endif
|
||||
, isReachable(false)
|
||||
, variablesAtHead(numArguments, numLocals)
|
||||
, variablesAtTail(numArguments, numLocals)
|
||||
, valuesAtHead(numArguments, numLocals)
|
||||
, valuesAtTail(numArguments, numLocals)
|
||||
{
|
||||
}
|
||||
|
||||
void ensureLocals(unsigned newNumLocals)
|
||||
{
|
||||
variablesAtHead.ensureLocals(newNumLocals);
|
||||
variablesAtTail.ensureLocals(newNumLocals);
|
||||
valuesAtHead.ensureLocals(newNumLocals);
|
||||
valuesAtTail.ensureLocals(newNumLocals);
|
||||
}
|
||||
|
||||
// This value is used internally for block linking and OSR entry. It is mostly meaningless
|
||||
// for other purposes due to inlining.
|
||||
unsigned bytecodeBegin;
|
||||
|
||||
NodeIndex begin;
|
||||
NodeIndex end;
|
||||
bool isOSRTarget;
|
||||
bool cfaHasVisited;
|
||||
bool cfaShouldRevisit;
|
||||
#if !ASSERT_DISABLED
|
||||
bool isLinked;
|
||||
#endif
|
||||
bool isReachable;
|
||||
|
||||
PredecessorList m_predecessors;
|
||||
|
||||
Operands<NodeIndex, NodeIndexTraits> variablesAtHead;
|
||||
Operands<NodeIndex, NodeIndexTraits> variablesAtTail;
|
||||
|
||||
Operands<AbstractValue> valuesAtHead;
|
||||
Operands<AbstractValue> valuesAtTail;
|
||||
};
|
||||
|
||||
struct UnlinkedBlock {
|
||||
BlockIndex m_blockIndex;
|
||||
bool m_needsNormalLinking;
|
||||
bool m_needsEarlyReturnLinking;
|
||||
|
||||
UnlinkedBlock() { }
|
||||
|
||||
explicit UnlinkedBlock(BlockIndex blockIndex)
|
||||
: m_blockIndex(blockIndex)
|
||||
, m_needsNormalLinking(true)
|
||||
, m_needsEarlyReturnLinking(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGBasicBlock_h
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGByteCodeCache_h
|
||||
#define DFGByteCodeCache_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "CodeBlock.h"
|
||||
#include "Executable.h"
|
||||
#include "JSFunction.h"
|
||||
#include <wtf/HashMap.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
class CodeBlockKey {
|
||||
public:
|
||||
CodeBlockKey()
|
||||
: m_executable(0)
|
||||
, m_kind(CodeForCall) // CodeForCall = empty value
|
||||
{
|
||||
}
|
||||
|
||||
CodeBlockKey(WTF::HashTableDeletedValueType)
|
||||
: m_executable(0)
|
||||
, m_kind(CodeForConstruct) // CodeForConstruct = deleted value
|
||||
{
|
||||
}
|
||||
|
||||
CodeBlockKey(FunctionExecutable* executable, CodeSpecializationKind kind)
|
||||
: m_executable(executable)
|
||||
, m_kind(kind)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const CodeBlockKey& other) const
|
||||
{
|
||||
return m_executable == other.m_executable
|
||||
&& m_kind == other.m_kind;
|
||||
}
|
||||
|
||||
unsigned hash() const
|
||||
{
|
||||
return WTF::PtrHash<FunctionExecutable*>::hash(m_executable) ^ static_cast<unsigned>(m_kind);
|
||||
}
|
||||
|
||||
FunctionExecutable* executable() const { return m_executable; }
|
||||
CodeSpecializationKind kind() const { return m_kind; }
|
||||
|
||||
bool isHashTableDeletedValue() const
|
||||
{
|
||||
return !m_executable && m_kind == CodeForConstruct;
|
||||
}
|
||||
|
||||
private:
|
||||
FunctionExecutable* m_executable;
|
||||
CodeSpecializationKind m_kind;
|
||||
};
|
||||
|
||||
struct CodeBlockKeyHash {
|
||||
static unsigned hash(const CodeBlockKey& key) { return key.hash(); }
|
||||
static bool equal(const CodeBlockKey& a, const CodeBlockKey& b) { return a == b; }
|
||||
|
||||
static const bool safeToCompareToEmptyOrDeleted = true;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
namespace WTF {
|
||||
|
||||
template<typename T> struct DefaultHash;
|
||||
template<> struct DefaultHash<JSC::DFG::CodeBlockKey> {
|
||||
typedef JSC::DFG::CodeBlockKeyHash Hash;
|
||||
};
|
||||
|
||||
template<typename T> struct HashTraits;
|
||||
template<> struct HashTraits<JSC::DFG::CodeBlockKey> : SimpleClassHashTraits<JSC::DFG::CodeBlockKey> { };
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
struct ByteCodeCacheValue {
|
||||
FunctionCodeBlock* codeBlock;
|
||||
bool owned;
|
||||
bool oldValueOfShouldDiscardBytecode;
|
||||
|
||||
// All uses of this struct initialize everything manually. But gcc isn't
|
||||
// smart enough to see that, so this constructor is just here to make the
|
||||
// compiler happy.
|
||||
ByteCodeCacheValue()
|
||||
: codeBlock(0)
|
||||
, owned(false)
|
||||
, oldValueOfShouldDiscardBytecode(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<bool (*filterFunction)(CodeBlock*, CodeSpecializationKind)>
|
||||
class ByteCodeCache {
|
||||
public:
|
||||
typedef HashMap<CodeBlockKey, ByteCodeCacheValue> Map;
|
||||
|
||||
ByteCodeCache() { }
|
||||
|
||||
~ByteCodeCache()
|
||||
{
|
||||
Map::iterator begin = m_map.begin();
|
||||
Map::iterator end = m_map.end();
|
||||
for (Map::iterator iter = begin; iter != end; ++iter) {
|
||||
if (!iter->second.codeBlock)
|
||||
continue;
|
||||
if (iter->second.owned) {
|
||||
delete iter->second.codeBlock;
|
||||
continue;
|
||||
}
|
||||
iter->second.codeBlock->m_shouldDiscardBytecode = iter->second.oldValueOfShouldDiscardBytecode;
|
||||
}
|
||||
}
|
||||
|
||||
CodeBlock* get(const CodeBlockKey& key, ScopeChainNode* scope)
|
||||
{
|
||||
Map::iterator iter = m_map.find(key);
|
||||
if (iter != m_map.end())
|
||||
return iter->second.codeBlock;
|
||||
|
||||
ByteCodeCacheValue value;
|
||||
|
||||
// First see if there is already a parsed code block that still has some
|
||||
// bytecode in it.
|
||||
value.codeBlock = key.executable()->codeBlockWithBytecodeFor(key.kind());
|
||||
if (value.codeBlock) {
|
||||
value.owned = false;
|
||||
value.oldValueOfShouldDiscardBytecode = value.codeBlock->m_shouldDiscardBytecode;
|
||||
} else {
|
||||
// Nope, so try to parse one.
|
||||
JSObject* exception;
|
||||
value.owned = true;
|
||||
value.codeBlock = key.executable()->produceCodeBlockFor(scope, OptimizingCompilation, key.kind(), exception).leakPtr();
|
||||
}
|
||||
|
||||
// Check if there is any reason to reject this from our cache. If so, then
|
||||
// poison it.
|
||||
if (!!value.codeBlock && !filterFunction(value.codeBlock, key.kind())) {
|
||||
if (value.owned)
|
||||
delete value.codeBlock;
|
||||
value.codeBlock = 0;
|
||||
}
|
||||
|
||||
// If we're about to return a code block, make sure that we're not going
|
||||
// to be discarding its bytecode if a GC were to happen during DFG
|
||||
// compilation. That's unlikely, but it's good to thoroughly enjoy this
|
||||
// kind of paranoia.
|
||||
if (!!value.codeBlock)
|
||||
value.codeBlock->m_shouldDiscardBytecode = false;
|
||||
|
||||
m_map.add(key, value);
|
||||
|
||||
return value.codeBlock;
|
||||
}
|
||||
|
||||
private:
|
||||
Map m_map;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGByteCodeCache_h
|
||||
@@ -1,548 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGCCallHelpers_h
|
||||
#define DFGCCallHelpers_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "DFGAssemblyHelpers.h"
|
||||
#include "DFGGPRInfo.h"
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
class CCallHelpers : public AssemblyHelpers {
|
||||
public:
|
||||
CCallHelpers(JSGlobalData* globalData, CodeBlock* codeBlock)
|
||||
: AssemblyHelpers(globalData, codeBlock)
|
||||
{
|
||||
}
|
||||
|
||||
// These methods used to sort arguments into the correct registers.
|
||||
// On X86 we use cdecl calling conventions, which pass all arguments on the
|
||||
// stack. On other architectures we may need to sort values into the
|
||||
// correct registers.
|
||||
#if !NUMBER_OF_ARGUMENT_REGISTERS
|
||||
unsigned m_callArgumentOffset;
|
||||
void resetCallArguments() { m_callArgumentOffset = 0; }
|
||||
|
||||
// These methods are using internally to implement the callOperation methods.
|
||||
void addCallArgument(GPRReg value)
|
||||
{
|
||||
poke(value, m_callArgumentOffset++);
|
||||
}
|
||||
void addCallArgument(TrustedImm32 imm)
|
||||
{
|
||||
poke(imm, m_callArgumentOffset++);
|
||||
}
|
||||
void addCallArgument(TrustedImmPtr pointer)
|
||||
{
|
||||
poke(pointer, m_callArgumentOffset++);
|
||||
}
|
||||
void addCallArgument(FPRReg value)
|
||||
{
|
||||
storeDouble(value, Address(stackPointerRegister, m_callArgumentOffset * sizeof(void*)));
|
||||
m_callArgumentOffset += sizeof(double) / sizeof(void*);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArguments(FPRReg arg1)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(arg1);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsExecState()
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
addCallArgument(arg4);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
addCallArgument(arg4);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
addCallArgument(arg4);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
addCallArgument(arg4);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
|
||||
{
|
||||
resetCallArguments();
|
||||
addCallArgument(GPRInfo::callFrameRegister);
|
||||
addCallArgument(arg1);
|
||||
addCallArgument(arg2);
|
||||
addCallArgument(arg3);
|
||||
addCallArgument(arg4);
|
||||
addCallArgument(arg5);
|
||||
}
|
||||
#endif // !NUMBER_OF_ARGUMENT_REGISTERS
|
||||
// These methods are suitable for any calling convention that provides for
|
||||
// at least 4 argument registers, e.g. X86_64, ARMv7.
|
||||
#if NUMBER_OF_ARGUMENT_REGISTERS >= 4
|
||||
template<GPRReg destA, GPRReg destB>
|
||||
void setupTwoStubArgs(GPRReg srcA, GPRReg srcB)
|
||||
{
|
||||
// Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
|
||||
// (1) both are already in arg regs, the right way around.
|
||||
// (2) both are already in arg regs, the wrong way around.
|
||||
// (3) neither are currently in arg registers.
|
||||
// (4) srcA in in its correct reg.
|
||||
// (5) srcA in in the incorrect reg.
|
||||
// (6) srcB in in its correct reg.
|
||||
// (7) srcB in in the incorrect reg.
|
||||
//
|
||||
// The trivial approach is to simply emit two moves, to put srcA in place then srcB in
|
||||
// place (the MacroAssembler will omit redundant moves). This apporach will be safe in
|
||||
// cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
|
||||
// (requires a swap) and 7 (must move srcB first, to avoid trampling.)
|
||||
|
||||
if (srcB != destA) {
|
||||
// Handle the easy cases - two simple moves.
|
||||
move(srcA, destA);
|
||||
move(srcB, destB);
|
||||
} else if (srcA != destB) {
|
||||
// Handle the non-swap case - just put srcB in place first.
|
||||
move(srcB, destB);
|
||||
move(srcA, destA);
|
||||
} else
|
||||
swap(destA, destB);
|
||||
}
|
||||
#if CPU(X86_64)
|
||||
template<FPRReg destA, FPRReg destB>
|
||||
void setupTwoStubArgs(FPRReg srcA, FPRReg srcB)
|
||||
{
|
||||
// Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
|
||||
// (1) both are already in arg regs, the right way around.
|
||||
// (2) both are already in arg regs, the wrong way around.
|
||||
// (3) neither are currently in arg registers.
|
||||
// (4) srcA in in its correct reg.
|
||||
// (5) srcA in in the incorrect reg.
|
||||
// (6) srcB in in its correct reg.
|
||||
// (7) srcB in in the incorrect reg.
|
||||
//
|
||||
// The trivial approach is to simply emit two moves, to put srcA in place then srcB in
|
||||
// place (the MacroAssembler will omit redundant moves). This apporach will be safe in
|
||||
// cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
|
||||
// (requires a swap) and 7 (must move srcB first, to avoid trampling.)
|
||||
|
||||
if (srcB != destA) {
|
||||
// Handle the easy cases - two simple moves.
|
||||
moveDouble(srcA, destA);
|
||||
moveDouble(srcB, destB);
|
||||
return;
|
||||
}
|
||||
|
||||
if (srcA != destB) {
|
||||
// Handle the non-swap case - just put srcB in place first.
|
||||
moveDouble(srcB, destB);
|
||||
moveDouble(srcA, destA);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(srcB == destA && srcA == destB);
|
||||
// Need to swap; pick a temporary register.
|
||||
FPRReg temp;
|
||||
if (destA != FPRInfo::argumentFPR3 && destA != FPRInfo::argumentFPR3)
|
||||
temp = FPRInfo::argumentFPR3;
|
||||
else if (destA != FPRInfo::argumentFPR2 && destA != FPRInfo::argumentFPR2)
|
||||
temp = FPRInfo::argumentFPR2;
|
||||
else {
|
||||
ASSERT(destA != FPRInfo::argumentFPR1 && destA != FPRInfo::argumentFPR1);
|
||||
temp = FPRInfo::argumentFPR1;
|
||||
}
|
||||
moveDouble(destA, temp);
|
||||
moveDouble(destB, destA);
|
||||
moveDouble(temp, destB);
|
||||
}
|
||||
#endif
|
||||
void setupStubArguments(GPRReg arg1, GPRReg arg2)
|
||||
{
|
||||
setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
|
||||
}
|
||||
void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
|
||||
{
|
||||
// If neither of arg2/arg3 are in our way, then we can move arg1 into place.
|
||||
// Then we can use setupTwoStubArgs to fix arg2/arg3.
|
||||
if (arg2 != GPRInfo::argumentGPR1 && arg3 != GPRInfo::argumentGPR1) {
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
|
||||
return;
|
||||
}
|
||||
|
||||
// If neither of arg1/arg3 are in our way, then we can move arg2 into place.
|
||||
// Then we can use setupTwoStubArgs to fix arg1/arg3.
|
||||
if (arg1 != GPRInfo::argumentGPR2 && arg3 != GPRInfo::argumentGPR2) {
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
|
||||
return;
|
||||
}
|
||||
|
||||
// If neither of arg1/arg2 are in our way, then we can move arg3 into place.
|
||||
// Then we can use setupTwoStubArgs to fix arg1/arg2.
|
||||
if (arg1 != GPRInfo::argumentGPR3 && arg2 != GPRInfo::argumentGPR3) {
|
||||
move(arg3, GPRInfo::argumentGPR3);
|
||||
setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we get here, we haven't been able to move any of arg1/arg2/arg3.
|
||||
// Since all three are blocked, then all three must already be in the argument register.
|
||||
// But are they in the right ones?
|
||||
|
||||
// First, ensure arg1 is in place.
|
||||
if (arg1 != GPRInfo::argumentGPR1) {
|
||||
swap(arg1, GPRInfo::argumentGPR1);
|
||||
|
||||
// If arg1 wasn't in argumentGPR1, one of arg2/arg3 must be.
|
||||
ASSERT(arg2 == GPRInfo::argumentGPR1 || arg3 == GPRInfo::argumentGPR1);
|
||||
// If arg2 was in argumentGPR1 it no longer is (due to the swap).
|
||||
// Otherwise arg3 must have been. Mark him as moved.
|
||||
if (arg2 == GPRInfo::argumentGPR1)
|
||||
arg2 = arg1;
|
||||
else
|
||||
arg3 = arg1;
|
||||
}
|
||||
|
||||
// Either arg2 & arg3 need swapping, or we're all done.
|
||||
ASSERT((arg2 == GPRInfo::argumentGPR2 || arg3 == GPRInfo::argumentGPR3)
|
||||
|| (arg2 == GPRInfo::argumentGPR3 || arg3 == GPRInfo::argumentGPR2));
|
||||
|
||||
if (arg2 != GPRInfo::argumentGPR2)
|
||||
swap(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3);
|
||||
}
|
||||
|
||||
#if CPU(X86_64)
|
||||
ALWAYS_INLINE void setupArguments(FPRReg arg1)
|
||||
{
|
||||
moveDouble(arg1, FPRInfo::argumentFPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
|
||||
{
|
||||
setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2);
|
||||
}
|
||||
#else
|
||||
ALWAYS_INLINE void setupArguments(FPRReg arg1)
|
||||
{
|
||||
assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
|
||||
{
|
||||
assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
|
||||
assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
|
||||
}
|
||||
#endif
|
||||
|
||||
ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
|
||||
{
|
||||
setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsExecState()
|
||||
{
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
|
||||
{
|
||||
setupStubArguments(arg1, arg2);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
|
||||
{
|
||||
move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
|
||||
{
|
||||
setupStubArguments(arg1, arg2, arg3);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
|
||||
{
|
||||
setupStubArguments(arg1, arg2);
|
||||
move(arg3, GPRInfo::argumentGPR3);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
move(arg3, GPRInfo::argumentGPR3);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
move(arg3, GPRInfo::argumentGPR3);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
|
||||
{
|
||||
setupStubArguments(arg1, arg2);
|
||||
move(arg3, GPRInfo::argumentGPR3);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3)
|
||||
{
|
||||
move(arg1, GPRInfo::argumentGPR1);
|
||||
move(arg2, GPRInfo::argumentGPR2);
|
||||
move(arg3, GPRInfo::argumentGPR3);
|
||||
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
||||
}
|
||||
|
||||
#endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
|
||||
// These methods are suitable for any calling convention that provides for
|
||||
// exactly 4 argument registers, e.g. ARMv7.
|
||||
#if NUMBER_OF_ARGUMENT_REGISTERS == 4
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
|
||||
{
|
||||
poke(arg4);
|
||||
setupArgumentsWithExecState(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
|
||||
{
|
||||
poke(arg4);
|
||||
setupArgumentsWithExecState(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
|
||||
{
|
||||
poke(arg4);
|
||||
setupArgumentsWithExecState(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
|
||||
{
|
||||
poke(arg4);
|
||||
setupArgumentsWithExecState(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
|
||||
{
|
||||
poke(arg5, 1);
|
||||
poke(arg4);
|
||||
setupArgumentsWithExecState(arg1, arg2, arg3);
|
||||
}
|
||||
#endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
|
||||
|
||||
void setupResults(GPRReg destA, GPRReg destB)
|
||||
{
|
||||
GPRReg srcA = GPRInfo::returnValueGPR;
|
||||
GPRReg srcB = GPRInfo::returnValueGPR2;
|
||||
|
||||
if (srcB != destA) {
|
||||
// Handle the easy cases - two simple moves.
|
||||
move(srcA, destA);
|
||||
move(srcB, destB);
|
||||
} else if (srcA != destB) {
|
||||
// Handle the non-swap case - just put srcB in place first.
|
||||
move(srcB, destB);
|
||||
move(srcA, destA);
|
||||
} else
|
||||
swap(destA, destB);
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGCCallHelpers_h
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGCapabilities_h
|
||||
#define DFGCapabilities_h
|
||||
|
||||
#include "Intrinsic.h"
|
||||
#include "DFGNode.h"
|
||||
#include "Executable.h"
|
||||
#include "Options.h"
|
||||
#include "Interpreter.h"
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
// Fast check functions; if they return true it is still necessary to
|
||||
// check opcodes.
|
||||
inline bool mightCompileEval(CodeBlock* codeBlock)
|
||||
{
|
||||
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
|
||||
}
|
||||
inline bool mightCompileProgram(CodeBlock* codeBlock)
|
||||
{
|
||||
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
|
||||
}
|
||||
inline bool mightCompileFunctionForCall(CodeBlock* codeBlock)
|
||||
{
|
||||
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
|
||||
}
|
||||
inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
|
||||
{
|
||||
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
|
||||
}
|
||||
|
||||
inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
|
||||
{
|
||||
return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount;
|
||||
}
|
||||
inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
|
||||
{
|
||||
return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount;
|
||||
}
|
||||
|
||||
// Opcode checking.
|
||||
inline bool canCompileOpcode(OpcodeID opcodeID)
|
||||
{
|
||||
switch (opcodeID) {
|
||||
case op_enter:
|
||||
case op_convert_this:
|
||||
case op_create_this:
|
||||
case op_get_callee:
|
||||
case op_bitand:
|
||||
case op_bitor:
|
||||
case op_bitxor:
|
||||
case op_rshift:
|
||||
case op_lshift:
|
||||
case op_urshift:
|
||||
case op_pre_inc:
|
||||
case op_post_inc:
|
||||
case op_pre_dec:
|
||||
case op_post_dec:
|
||||
case op_add:
|
||||
case op_sub:
|
||||
case op_mul:
|
||||
case op_mod:
|
||||
case op_div:
|
||||
#if ENABLE(DEBUG_WITH_BREAKPOINT)
|
||||
case op_debug:
|
||||
#endif
|
||||
case op_mov:
|
||||
case op_check_has_instance:
|
||||
case op_instanceof:
|
||||
case op_not:
|
||||
case op_less:
|
||||
case op_lesseq:
|
||||
case op_greater:
|
||||
case op_greatereq:
|
||||
case op_eq:
|
||||
case op_eq_null:
|
||||
case op_stricteq:
|
||||
case op_neq:
|
||||
case op_neq_null:
|
||||
case op_nstricteq:
|
||||
case op_get_by_val:
|
||||
case op_put_by_val:
|
||||
case op_method_check:
|
||||
case op_get_scoped_var:
|
||||
case op_put_scoped_var:
|
||||
case op_get_by_id:
|
||||
case op_put_by_id:
|
||||
case op_get_global_var:
|
||||
case op_put_global_var:
|
||||
case op_jmp:
|
||||
case op_loop:
|
||||
case op_jtrue:
|
||||
case op_jfalse:
|
||||
case op_loop_if_true:
|
||||
case op_loop_if_false:
|
||||
case op_jeq_null:
|
||||
case op_jneq_null:
|
||||
case op_jless:
|
||||
case op_jlesseq:
|
||||
case op_jgreater:
|
||||
case op_jgreatereq:
|
||||
case op_jnless:
|
||||
case op_jnlesseq:
|
||||
case op_jngreater:
|
||||
case op_jngreatereq:
|
||||
case op_loop_hint:
|
||||
case op_loop_if_less:
|
||||
case op_loop_if_lesseq:
|
||||
case op_loop_if_greater:
|
||||
case op_loop_if_greatereq:
|
||||
case op_ret:
|
||||
case op_end:
|
||||
case op_call_put_result:
|
||||
case op_resolve:
|
||||
case op_resolve_base:
|
||||
case op_resolve_global:
|
||||
case op_new_object:
|
||||
case op_new_array:
|
||||
case op_new_array_buffer:
|
||||
case op_strcat:
|
||||
case op_to_primitive:
|
||||
case op_throw:
|
||||
case op_throw_reference_error:
|
||||
case op_call:
|
||||
case op_construct:
|
||||
return true;
|
||||
|
||||
// Opcodes we support conditionally. Enabling these opcodes currently results in
|
||||
// performance regressions. Each node that we disable under restrictions has a
|
||||
// comment describing what we know about the regression so far.
|
||||
|
||||
// Regresses string-validate-input, probably because it uses comparisons (< and >)
|
||||
// on strings, which currently will cause speculation failures in some cases.
|
||||
case op_new_regexp:
|
||||
#if DFG_ENABLE(RESTRICTIONS)
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool canInlineOpcode(OpcodeID opcodeID)
|
||||
{
|
||||
switch (opcodeID) {
|
||||
|
||||
// These opcodes would be easy to support with inlining, but we currently don't do it.
|
||||
// The issue is that the scope chain will not be set correctly.
|
||||
case op_get_scoped_var:
|
||||
case op_put_scoped_var:
|
||||
case op_resolve:
|
||||
case op_resolve_base:
|
||||
case op_resolve_global:
|
||||
|
||||
// Constant buffers aren't copied correctly. This is easy to fix, but for
|
||||
// now we just disable inlining for functions that use them.
|
||||
case op_new_array_buffer:
|
||||
|
||||
// Inlining doesn't correctly remap regular expression operands.
|
||||
case op_new_regexp:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return canCompileOpcode(opcodeID);
|
||||
}
|
||||
}
|
||||
|
||||
bool canCompileOpcodes(CodeBlock*);
|
||||
bool canInlineOpcodes(CodeBlock*);
|
||||
#else // ENABLE(DFG_JIT)
|
||||
inline bool mightCompileEval(CodeBlock*) { return false; }
|
||||
inline bool mightCompileProgram(CodeBlock*) { return false; }
|
||||
inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
|
||||
inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
|
||||
inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
|
||||
inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
|
||||
|
||||
inline bool canCompileOpcode(OpcodeID) { return false; }
|
||||
inline bool canInlineOpcode(OpcodeID) { return false; }
|
||||
inline bool canCompileOpcodes(CodeBlock*) { return false; }
|
||||
inline bool canInlineOpcodes(CodeBlock*) { return false; }
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
inline bool canCompileEval(CodeBlock* codeBlock)
|
||||
{
|
||||
return mightCompileEval(codeBlock) && canCompileOpcodes(codeBlock);
|
||||
}
|
||||
|
||||
inline bool canCompileProgram(CodeBlock* codeBlock)
|
||||
{
|
||||
return mightCompileProgram(codeBlock) && canCompileOpcodes(codeBlock);
|
||||
}
|
||||
|
||||
inline bool canCompileFunctionForCall(CodeBlock* codeBlock)
|
||||
{
|
||||
return mightCompileFunctionForCall(codeBlock) && canCompileOpcodes(codeBlock);
|
||||
}
|
||||
|
||||
inline bool canCompileFunctionForConstruct(CodeBlock* codeBlock)
|
||||
{
|
||||
return mightCompileFunctionForConstruct(codeBlock) && canCompileOpcodes(codeBlock);
|
||||
}
|
||||
|
||||
inline bool canInlineFunctionForCall(CodeBlock* codeBlock)
|
||||
{
|
||||
return mightInlineFunctionForCall(codeBlock) && canInlineOpcodes(codeBlock);
|
||||
}
|
||||
|
||||
inline bool canInlineFunctionForConstruct(CodeBlock* codeBlock)
|
||||
{
|
||||
return mightInlineFunctionForConstruct(codeBlock) && canInlineOpcodes(codeBlock);
|
||||
}
|
||||
|
||||
inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
|
||||
{
|
||||
if (kind == CodeForCall)
|
||||
return mightInlineFunctionForCall(codeBlock);
|
||||
ASSERT(kind == CodeForConstruct);
|
||||
return mightInlineFunctionForConstruct(codeBlock);
|
||||
}
|
||||
|
||||
inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
|
||||
{
|
||||
if (kind == CodeForCall)
|
||||
return canInlineFunctionForCall(codeBlock);
|
||||
ASSERT(kind == CodeForConstruct);
|
||||
return canInlineFunctionForConstruct(codeBlock);
|
||||
}
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // DFGCapabilities_h
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGCodeBlocks_h
|
||||
#define DFGCodeBlocks_h
|
||||
|
||||
#include <wtf/FastAllocBase.h>
|
||||
#include <wtf/HashSet.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class CodeBlock;
|
||||
class SlotVisitor;
|
||||
|
||||
// DFGCodeBlocks notifies the garbage collector about optimized code blocks that
|
||||
// have different marking behavior depending on whether or not they are on the
|
||||
// stack, and that may be jettisoned. Jettisoning is the process of discarding
|
||||
// a code block after all calls to it have been unlinked. This class takes special
|
||||
// care to ensure that if there are still call frames that are using the code
|
||||
// block, then it should not be immediately deleted, but rather, it should be
|
||||
// deleted once we know that there are no longer any references to it from any
|
||||
// call frames. This class takes its name from the DFG compiler; only code blocks
|
||||
// compiled by the DFG need special marking behavior if they are on the stack, and
|
||||
// only those code blocks may be jettisoned.
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
class DFGCodeBlocks {
|
||||
WTF_MAKE_FAST_ALLOCATED;
|
||||
|
||||
public:
|
||||
DFGCodeBlocks();
|
||||
~DFGCodeBlocks();
|
||||
|
||||
// Inform the collector that a code block has been jettisoned form its
|
||||
// executable and should only be kept alive if there are call frames that use
|
||||
// it. This is typically called either from a recompilation trigger, or from
|
||||
// an unconditional finalizer associated with a CodeBlock that had weak
|
||||
// references, where some subset of those references were dead.
|
||||
void jettison(PassOwnPtr<CodeBlock>);
|
||||
|
||||
// Clear all mark bits associated with DFG code blocks.
|
||||
void clearMarks();
|
||||
|
||||
// Mark a pointer that may be a CodeBlock that belongs to the set of DFG code
|
||||
// blocks. This is defined inline in CodeBlock.h
|
||||
void mark(void* candidateCodeBlock);
|
||||
|
||||
// Delete all jettisoned code blocks that have not been marked (i.e. are not referenced
|
||||
// from call frames).
|
||||
void deleteUnmarkedJettisonedCodeBlocks();
|
||||
|
||||
// Trace all marked code blocks (i.e. are referenced from call frames). The CodeBlock
|
||||
// is free to make use of m_dfgData->isMarked and m_dfgData->isJettisoned.
|
||||
void traceMarkedCodeBlocks(SlotVisitor&);
|
||||
|
||||
private:
|
||||
friend class CodeBlock;
|
||||
|
||||
HashSet<CodeBlock*> m_set;
|
||||
};
|
||||
#else
|
||||
class DFGCodeBlocks {
|
||||
WTF_MAKE_FAST_ALLOCATED;
|
||||
|
||||
public:
|
||||
void jettison(PassOwnPtr<CodeBlock>);
|
||||
void clearMarks() { }
|
||||
void mark(void*) { }
|
||||
void deleteUnmarkedJettisonedCodeBlocks() { }
|
||||
void traceMarkedCodeBlocks(SlotVisitor&) { }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGCommon_h
|
||||
#define DFGCommon_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "CodeOrigin.h"
|
||||
#include "VirtualRegister.h"
|
||||
|
||||
/* DFG_ENABLE() - turn on a specific features in the DFG JIT */
|
||||
#define DFG_ENABLE(DFG_FEATURE) (defined DFG_ENABLE_##DFG_FEATURE && DFG_ENABLE_##DFG_FEATURE)
|
||||
|
||||
// Emit various logging information for debugging, including dumping the dataflow graphs.
|
||||
#define DFG_ENABLE_DEBUG_VERBOSE 0
|
||||
// Emit dumps during propagation, in addition to just after.
|
||||
#define DFG_ENABLE_DEBUG_PROPAGATION_VERBOSE 0
|
||||
// Emit logging for OSR exit value recoveries at every node, not just nodes that
|
||||
// actually has speculation checks.
|
||||
#define DFG_ENABLE_VERBOSE_VALUE_RECOVERIES 0
|
||||
// Enable generation of dynamic checks into the instruction stream.
|
||||
#if !ASSERT_DISABLED
|
||||
#define DFG_ENABLE_JIT_ASSERT 1
|
||||
#else
|
||||
#define DFG_ENABLE_JIT_ASSERT 0
|
||||
#endif
|
||||
// Consistency check contents compiler data structures.
|
||||
#define DFG_ENABLE_CONSISTENCY_CHECK 0
|
||||
// Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
|
||||
#define DFG_ENABLE_JIT_BREAK_ON_EVERY_FUNCTION 0
|
||||
// Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
|
||||
#define DFG_ENABLE_JIT_BREAK_ON_EVERY_BLOCK 0
|
||||
// Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
|
||||
#define DFG_ENABLE_JIT_BREAK_ON_EVERY_NODE 0
|
||||
// Emit a pair of xorPtr()'s on regT0 with the node index to make it easy to spot node boundaries in disassembled code.
|
||||
#define DFG_ENABLE_XOR_DEBUG_AID 0
|
||||
// Emit a breakpoint into the speculation failure code.
|
||||
#define DFG_ENABLE_JIT_BREAK_ON_SPECULATION_FAILURE 0
|
||||
// Log every speculation failure.
|
||||
#define DFG_ENABLE_VERBOSE_SPECULATION_FAILURE 0
|
||||
// Disable the DFG JIT without having to touch Platform.h
|
||||
#define DFG_DEBUG_LOCAL_DISBALE 0
|
||||
// Enable OSR entry from baseline JIT.
|
||||
#define DFG_ENABLE_OSR_ENTRY ENABLE(DFG_JIT)
|
||||
// Generate stats on how successful we were in making use of the DFG jit, and remaining on the hot path.
|
||||
#define DFG_ENABLE_SUCCESS_STATS 0
|
||||
// Used to enable conditionally supported opcodes that currently result in performance regressions.
|
||||
#define DFG_ENABLE_RESTRICTIONS 1
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
// Type for a reference to another node in the graph.
|
||||
typedef uint32_t NodeIndex;
|
||||
static const NodeIndex NoNode = UINT_MAX;
|
||||
|
||||
typedef uint32_t BlockIndex;
|
||||
static const BlockIndex NoBlock = UINT_MAX;
|
||||
|
||||
struct NodeIndexTraits {
|
||||
static NodeIndex defaultValue() { return NoNode; }
|
||||
static void dump(NodeIndex value, FILE* out)
|
||||
{
|
||||
if (value == NoNode)
|
||||
fprintf(out, "-");
|
||||
else
|
||||
fprintf(out, "@%u", value);
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGCommon_h
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGCorrectableJumpPoint_h
|
||||
#define DFGCorrectableJumpPoint_h
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "LinkBuffer.h"
|
||||
#include "MacroAssembler.h"
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
// This is a type-safe union of MacroAssembler::Jump and CodeLocationJump.
|
||||
// Furthermore, it supports the notion of branching (possibly conditionally, but
|
||||
// also possibly jumping unconditionally) to an out-of-line patchable jump.
|
||||
// Thus it goes through three states:
|
||||
//
|
||||
// 1) Label of unpatchable branch or jump (i.e. MacroAssembler::Jump).
|
||||
// 2) Label of patchable jump (i.e. MacroAssembler::Jump).
|
||||
// 3) Corrected post-linking label of patchable jump (i.e. CodeLocationJump).
|
||||
//
|
||||
// The setting of state (1) corresponds to planting the in-line unpatchable
|
||||
// branch or jump. The state transition (1)->(2) corresponds to linking the
|
||||
// in-line branch or jump to the out-of-line patchable jump, and recording
|
||||
// the latter's label. The state transition (2)->(3) corresponds to recording
|
||||
// the out-of-line patchable jump's location after branch compaction has
|
||||
// completed.
|
||||
//
|
||||
// You can also go directly from the first state to the third state, if you
|
||||
// wish to use this class for in-line patchable jumps.
|
||||
|
||||
class CorrectableJumpPoint {
|
||||
public:
|
||||
CorrectableJumpPoint(MacroAssembler::Jump check)
|
||||
: m_codeOffset(check.m_label.m_offset)
|
||||
#ifndef NDEBUG
|
||||
, m_mode(InitialJump)
|
||||
#endif
|
||||
{
|
||||
#if CPU(ARM_THUMB2)
|
||||
m_type = check.m_type;
|
||||
m_condition = check.m_condition;
|
||||
#endif
|
||||
}
|
||||
|
||||
void switchToLateJump(MacroAssembler::Jump check)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
ASSERT(m_mode == InitialJump);
|
||||
m_mode = LateJump;
|
||||
#endif
|
||||
// Late jumps should only ever be real jumps.
|
||||
#if CPU(ARM_THUMB2)
|
||||
ASSERT(check.m_type == ARMv7Assembler::JumpNoConditionFixedSize);
|
||||
ASSERT(check.m_condition == ARMv7Assembler::ConditionInvalid);
|
||||
m_type = ARMv7Assembler::JumpNoConditionFixedSize;
|
||||
m_condition = ARMv7Assembler::ConditionInvalid;
|
||||
#endif
|
||||
m_codeOffset = check.m_label.m_offset;
|
||||
}
|
||||
|
||||
void correctInitialJump(LinkBuffer& linkBuffer)
|
||||
{
|
||||
ASSERT(m_mode == InitialJump);
|
||||
#if CPU(ARM_THUMB2)
|
||||
ASSERT(m_type == ARMv7Assembler::JumpNoConditionFixedSize);
|
||||
ASSERT(m_condition == ARMv7Assembler::ConditionInvalid);
|
||||
#endif
|
||||
correctJump(linkBuffer);
|
||||
}
|
||||
|
||||
void correctLateJump(LinkBuffer& linkBuffer)
|
||||
{
|
||||
ASSERT(m_mode == LateJump);
|
||||
correctJump(linkBuffer);
|
||||
}
|
||||
|
||||
MacroAssembler::Jump initialJump() const
|
||||
{
|
||||
ASSERT(m_mode == InitialJump);
|
||||
return getJump();
|
||||
}
|
||||
|
||||
MacroAssembler::Jump lateJump() const
|
||||
{
|
||||
ASSERT(m_mode == LateJump);
|
||||
return getJump();
|
||||
}
|
||||
|
||||
CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
|
||||
|
||||
private:
|
||||
void correctJump(LinkBuffer& linkBuffer)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
m_mode = CorrectedJump;
|
||||
#endif
|
||||
MacroAssembler::Label label;
|
||||
label.m_label.m_offset = m_codeOffset;
|
||||
m_codeOffset = linkBuffer.offsetOf(label);
|
||||
}
|
||||
|
||||
MacroAssembler::Jump getJump() const
|
||||
{
|
||||
MacroAssembler::Jump jump;
|
||||
jump.m_label.m_offset = m_codeOffset;
|
||||
#if CPU(ARM_THUMB2)
|
||||
jump.m_type = m_type;
|
||||
jump.m_condition = m_condition;
|
||||
#endif
|
||||
return jump;
|
||||
}
|
||||
|
||||
unsigned m_codeOffset;
|
||||
|
||||
#if CPU(ARM_THUMB2)
|
||||
ARMv7Assembler::JumpType m_type : 8;
|
||||
ARMv7Assembler::Condition m_condition : 8;
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
enum Mode {
|
||||
InitialJump,
|
||||
LateJump,
|
||||
CorrectedJump
|
||||
};
|
||||
|
||||
Mode m_mode;
|
||||
#endif
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGCorrectableJumpPoint_h
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGExitProfile_h
|
||||
#define DFGExitProfile_h
|
||||
|
||||
#include <wtf/HashSet.h>
|
||||
#include <wtf/OwnPtr.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
enum ExitKind {
|
||||
ExitKindUnset,
|
||||
BadType, // We exited because a type prediction was wrong.
|
||||
BadCache, // We exited because an inline cache was wrong.
|
||||
Overflow, // We exited because of overflow.
|
||||
NegativeZero, // We exited because we encountered negative zero.
|
||||
Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
inline const char* exitKindToString(ExitKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case ExitKindUnset:
|
||||
return "Unset";
|
||||
case BadType:
|
||||
return "BadType";
|
||||
case BadCache:
|
||||
return "BadCache";
|
||||
case Overflow:
|
||||
return "Overflow";
|
||||
case NegativeZero:
|
||||
return "NegativeZero";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool exitKindIsCountable(ExitKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case ExitKindUnset:
|
||||
ASSERT_NOT_REACHED();
|
||||
case BadType:
|
||||
case Uncountable:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FrequentExitSite {
|
||||
public:
|
||||
FrequentExitSite()
|
||||
: m_bytecodeOffset(0) // 0 = empty value
|
||||
, m_kind(ExitKindUnset)
|
||||
{
|
||||
}
|
||||
|
||||
FrequentExitSite(WTF::HashTableDeletedValueType)
|
||||
: m_bytecodeOffset(1) // 1 = deleted value
|
||||
, m_kind(ExitKindUnset)
|
||||
{
|
||||
}
|
||||
|
||||
explicit FrequentExitSite(unsigned bytecodeOffset, ExitKind kind)
|
||||
: m_bytecodeOffset(bytecodeOffset)
|
||||
, m_kind(kind)
|
||||
{
|
||||
ASSERT(exitKindIsCountable(kind));
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return m_kind == ExitKindUnset;
|
||||
}
|
||||
|
||||
bool operator==(const FrequentExitSite& other) const
|
||||
{
|
||||
return m_bytecodeOffset == other.m_bytecodeOffset
|
||||
&& m_kind == other.m_kind;
|
||||
}
|
||||
|
||||
unsigned hash() const
|
||||
{
|
||||
return WTF::intHash(m_bytecodeOffset) + m_kind;
|
||||
}
|
||||
|
||||
unsigned bytecodeOffset() const { return m_bytecodeOffset; }
|
||||
ExitKind kind() const { return m_kind; }
|
||||
|
||||
bool isHashTableDeletedValue() const
|
||||
{
|
||||
return m_kind == ExitKindUnset && m_bytecodeOffset;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_bytecodeOffset;
|
||||
ExitKind m_kind;
|
||||
};
|
||||
|
||||
struct FrequentExitSiteHash {
|
||||
static unsigned hash(const FrequentExitSite& key) { return key.hash(); }
|
||||
static bool equal(const FrequentExitSite& a, const FrequentExitSite& b) { return a == b; }
|
||||
static const bool safeToCompareToEmptyOrDeleted = true;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
namespace WTF {
|
||||
|
||||
template<typename T> struct DefaultHash;
|
||||
template<> struct DefaultHash<JSC::DFG::FrequentExitSite> {
|
||||
typedef JSC::DFG::FrequentExitSiteHash Hash;
|
||||
};
|
||||
|
||||
template<typename T> struct HashTraits;
|
||||
template<> struct HashTraits<JSC::DFG::FrequentExitSite> : SimpleClassHashTraits<JSC::DFG::FrequentExitSite> { };
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
class QueryableExitProfile;
|
||||
|
||||
class ExitProfile {
|
||||
public:
|
||||
ExitProfile();
|
||||
~ExitProfile();
|
||||
|
||||
// Add a new frequent exit site. Return true if this is a new one, or false
|
||||
// if we already knew about it. This is an O(n) operation, because it errs
|
||||
// on the side of keeping the data structure compact. Also, this will only
|
||||
// be called a fixed number of times per recompilation. Recompilation is
|
||||
// rare to begin with, and implies doing O(n) operations on the CodeBlock
|
||||
// anyway.
|
||||
bool add(const FrequentExitSite&);
|
||||
|
||||
private:
|
||||
friend class QueryableExitProfile;
|
||||
|
||||
OwnPtr<Vector<FrequentExitSite> > m_frequentExitSites;
|
||||
};
|
||||
|
||||
class QueryableExitProfile {
|
||||
public:
|
||||
explicit QueryableExitProfile(const ExitProfile&);
|
||||
~QueryableExitProfile();
|
||||
|
||||
bool hasExitSite(const FrequentExitSite& site) const
|
||||
{
|
||||
return m_frequentExitSites.find(site) != m_frequentExitSites.end();
|
||||
}
|
||||
|
||||
bool hasExitSite(unsigned bytecodeIndex, ExitKind kind) const
|
||||
{
|
||||
return hasExitSite(FrequentExitSite(bytecodeIndex, kind));
|
||||
}
|
||||
private:
|
||||
HashSet<FrequentExitSite> m_frequentExitSites;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // DFGExitProfile_h
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGOSREntry_h
|
||||
#define DFGOSREntry_h
|
||||
|
||||
#include "DFGAbstractValue.h"
|
||||
#include "DFGOperands.h"
|
||||
#include <wtf/BitVector.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ExecState;
|
||||
class CodeBlock;
|
||||
|
||||
namespace DFG {
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
struct OSREntryData {
|
||||
unsigned m_bytecodeIndex;
|
||||
unsigned m_machineCodeOffset;
|
||||
Operands<AbstractValue> m_expectedValues;
|
||||
BitVector m_localsForcedDouble;
|
||||
};
|
||||
|
||||
inline unsigned getOSREntryDataBytecodeIndex(OSREntryData* osrEntryData)
|
||||
{
|
||||
return osrEntryData->m_bytecodeIndex;
|
||||
}
|
||||
|
||||
void* prepareOSREntry(ExecState*, CodeBlock*, unsigned bytecodeIndex);
|
||||
#else
|
||||
inline void* prepareOSREntry(ExecState*, CodeBlock*, unsigned) { return 0; }
|
||||
#endif
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // DFGOSREntry_h
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGOSRExit_h
|
||||
#define DFGOSRExit_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "CodeOrigin.h"
|
||||
#include "DFGCommon.h"
|
||||
#include "DFGCorrectableJumpPoint.h"
|
||||
#include "DFGExitProfile.h"
|
||||
#include "DFGGPRInfo.h"
|
||||
#include "DFGOperands.h"
|
||||
#include "MacroAssembler.h"
|
||||
#include "ValueProfile.h"
|
||||
#include "ValueRecovery.h"
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
class SpeculativeJIT;
|
||||
|
||||
// This enum describes the types of additional recovery that
|
||||
// may need be performed should a speculation check fail.
|
||||
enum SpeculationRecoveryType {
|
||||
SpeculativeAdd,
|
||||
BooleanSpeculationCheck
|
||||
};
|
||||
|
||||
// === SpeculationRecovery ===
|
||||
//
|
||||
// This class provides additional information that may be associated with a
|
||||
// speculation check - for example
|
||||
class SpeculationRecovery {
|
||||
public:
|
||||
SpeculationRecovery(SpeculationRecoveryType type, GPRReg dest, GPRReg src)
|
||||
: m_type(type)
|
||||
, m_dest(dest)
|
||||
, m_src(src)
|
||||
{
|
||||
}
|
||||
|
||||
SpeculationRecoveryType type() { return m_type; }
|
||||
GPRReg dest() { return m_dest; }
|
||||
GPRReg src() { return m_src; }
|
||||
|
||||
private:
|
||||
// Indicates the type of additional recovery to be performed.
|
||||
SpeculationRecoveryType m_type;
|
||||
// different recovery types may required different additional information here.
|
||||
GPRReg m_dest;
|
||||
GPRReg m_src;
|
||||
};
|
||||
|
||||
// === OSRExit ===
|
||||
//
|
||||
// This structure describes how to exit the speculative path by
|
||||
// going into baseline code.
|
||||
struct OSRExit {
|
||||
OSRExit(ExitKind, JSValueSource, ValueProfile*, MacroAssembler::Jump, SpeculativeJIT*, unsigned recoveryIndex = 0);
|
||||
|
||||
MacroAssemblerCodeRef m_code;
|
||||
|
||||
JSValueSource m_jsValueSource;
|
||||
ValueProfile* m_valueProfile;
|
||||
|
||||
CorrectableJumpPoint m_check;
|
||||
NodeIndex m_nodeIndex;
|
||||
CodeOrigin m_codeOrigin;
|
||||
|
||||
unsigned m_recoveryIndex;
|
||||
|
||||
ExitKind m_kind;
|
||||
uint32_t m_count;
|
||||
|
||||
// Convenient way of iterating over ValueRecoveries while being
|
||||
// generic over argument versus variable.
|
||||
int numberOfRecoveries() const { return m_arguments.size() + m_variables.size(); }
|
||||
const ValueRecovery& valueRecovery(int index) const
|
||||
{
|
||||
if (index < (int)m_arguments.size())
|
||||
return m_arguments[index];
|
||||
return m_variables[index - m_arguments.size()];
|
||||
}
|
||||
ValueRecovery& valueRecoveryForOperand(int operand)
|
||||
{
|
||||
if (operandIsArgument(operand))
|
||||
return m_arguments[operandToArgument(operand)];
|
||||
return m_variables[operand];
|
||||
}
|
||||
bool isArgument(int index) const { return index < (int)m_arguments.size(); }
|
||||
bool isVariable(int index) const { return !isArgument(index); }
|
||||
int argumentForIndex(int index) const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
int variableForIndex(int index) const
|
||||
{
|
||||
return index - m_arguments.size();
|
||||
}
|
||||
int operandForIndex(int index) const
|
||||
{
|
||||
if (index < (int)m_arguments.size())
|
||||
return operandToArgument(index);
|
||||
return index - m_arguments.size();
|
||||
}
|
||||
|
||||
bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
|
||||
{
|
||||
if (!m_count || !exitKindIsCountable(m_kind))
|
||||
return false;
|
||||
return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump(FILE* out) const;
|
||||
#endif
|
||||
|
||||
Vector<ValueRecovery, 0> m_arguments;
|
||||
Vector<ValueRecovery, 0> m_variables;
|
||||
int m_lastSetOperand;
|
||||
|
||||
private:
|
||||
bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
|
||||
};
|
||||
|
||||
#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
|
||||
struct SpeculationFailureDebugInfo {
|
||||
CodeBlock* codeBlock;
|
||||
NodeIndex nodeIndex;
|
||||
};
|
||||
#endif
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGOSRExit_h
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGOSRExitCompiler_h
|
||||
#define DFGOSRExitCompiler_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "DFGAssemblyHelpers.h"
|
||||
#include "DFGOSRExit.h"
|
||||
#include "DFGOperations.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ExecState;
|
||||
|
||||
namespace DFG {
|
||||
|
||||
class OSRExitCompiler {
|
||||
public:
|
||||
OSRExitCompiler(AssemblyHelpers& jit)
|
||||
: m_jit(jit)
|
||||
{
|
||||
}
|
||||
|
||||
void compileExit(const OSRExit&, SpeculationRecovery*);
|
||||
|
||||
private:
|
||||
#if !ASSERT_DISABLED
|
||||
static unsigned badIndex() { return static_cast<unsigned>(-1); };
|
||||
#endif
|
||||
|
||||
void initializePoisoned(unsigned size)
|
||||
{
|
||||
#if ASSERT_DISABLED
|
||||
m_poisonScratchIndices.resize(size);
|
||||
#else
|
||||
m_poisonScratchIndices.fill(badIndex(), size);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned poisonIndex(unsigned index)
|
||||
{
|
||||
unsigned result = m_poisonScratchIndices[index];
|
||||
ASSERT(result != badIndex());
|
||||
return result;
|
||||
}
|
||||
|
||||
AssemblyHelpers& m_jit;
|
||||
Vector<unsigned> m_poisonScratchIndices;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
void DFG_OPERATION compileOSRExit(ExecState*);
|
||||
}
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGOSRExitCompiler_h
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGOperands_h
|
||||
#define DFGOperands_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "CallFrame.h"
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
// argument 0 is 'this'.
|
||||
inline bool operandIsArgument(int operand) { return operand < 0; }
|
||||
inline int operandToArgument(int operand) { return -operand + CallFrame::thisArgumentOffset(); }
|
||||
inline int argumentToOperand(int argument) { return -argument + CallFrame::thisArgumentOffset(); }
|
||||
|
||||
template<typename T> struct OperandValueTraits;
|
||||
|
||||
template<typename T>
|
||||
struct OperandValueTraits {
|
||||
static T defaultValue() { return T(); }
|
||||
static void dump(const T& value, FILE* out) { value.dump(out); }
|
||||
};
|
||||
|
||||
template<typename T, typename Traits = OperandValueTraits<T> >
|
||||
class Operands {
|
||||
public:
|
||||
Operands() { }
|
||||
|
||||
explicit Operands(size_t numArguments, size_t numLocals)
|
||||
{
|
||||
m_arguments.fill(Traits::defaultValue(), numArguments);
|
||||
m_locals.fill(Traits::defaultValue(), numLocals);
|
||||
}
|
||||
|
||||
size_t numberOfArguments() const { return m_arguments.size(); }
|
||||
size_t numberOfLocals() const { return m_locals.size(); }
|
||||
|
||||
T& argument(size_t idx) { return m_arguments[idx]; }
|
||||
const T& argument(size_t idx) const { return m_arguments[idx]; }
|
||||
|
||||
T& local(size_t idx) { return m_locals[idx]; }
|
||||
const T& local(size_t idx) const { return m_locals[idx]; }
|
||||
|
||||
void ensureLocals(size_t size)
|
||||
{
|
||||
if (size <= m_locals.size())
|
||||
return;
|
||||
|
||||
size_t oldSize = m_locals.size();
|
||||
m_locals.resize(size);
|
||||
for (size_t i = oldSize; i < m_locals.size(); ++i)
|
||||
m_locals[i] = Traits::defaultValue();
|
||||
}
|
||||
|
||||
void setLocal(size_t idx, const T& value)
|
||||
{
|
||||
ensureLocals(idx + 1);
|
||||
|
||||
m_locals[idx] = value;
|
||||
}
|
||||
|
||||
T getLocal(size_t idx)
|
||||
{
|
||||
if (idx >= m_locals.size())
|
||||
return Traits::defaultValue();
|
||||
return m_locals[idx];
|
||||
}
|
||||
|
||||
void setArgumentFirstTime(size_t idx, const T& value)
|
||||
{
|
||||
ASSERT(m_arguments[idx] == Traits::defaultValue());
|
||||
argument(idx) = value;
|
||||
}
|
||||
|
||||
void setLocalFirstTime(size_t idx, const T& value)
|
||||
{
|
||||
ASSERT(idx >= m_locals.size() || m_locals[idx] == Traits::defaultValue());
|
||||
setLocal(idx, value);
|
||||
}
|
||||
|
||||
T& operand(int operand)
|
||||
{
|
||||
if (operandIsArgument(operand)) {
|
||||
int argument = operandToArgument(operand);
|
||||
return m_arguments[argument];
|
||||
}
|
||||
|
||||
return m_locals[operand];
|
||||
}
|
||||
|
||||
const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
|
||||
|
||||
void setOperand(int operand, const T& value)
|
||||
{
|
||||
if (operandIsArgument(operand)) {
|
||||
int argument = operandToArgument(operand);
|
||||
m_arguments[argument] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
setLocal(operand, value);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (size_t i = 0; i < m_arguments.size(); ++i)
|
||||
m_arguments[i] = Traits::defaultValue();
|
||||
for (size_t i = 0; i < m_locals.size(); ++i)
|
||||
m_locals[i] = Traits::defaultValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Vector<T, 8> m_arguments;
|
||||
Vector<T, 16> m_locals;
|
||||
};
|
||||
|
||||
template<typename T, typename Traits>
|
||||
void dumpOperands(Operands<T, Traits>& operands, FILE* out)
|
||||
{
|
||||
for (size_t argument = 0; argument < operands.numberOfArguments(); ++argument) {
|
||||
if (argument)
|
||||
fprintf(out, " ");
|
||||
Traits::dump(operands.argument(argument), out);
|
||||
}
|
||||
fprintf(out, " : ");
|
||||
for (size_t local = 0; local < operands.numberOfLocals(); ++local) {
|
||||
if (local)
|
||||
fprintf(out, " ");
|
||||
Traits::dump(operands.local(local), out);
|
||||
}
|
||||
}
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGOperands_h
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGThunks_h
|
||||
#define DFGThunks_h
|
||||
|
||||
#include <wtf/Platform.h>
|
||||
|
||||
#if ENABLE(DFG_JIT)
|
||||
|
||||
#include "MacroAssemblerCodeRef.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class JSGlobalData;
|
||||
|
||||
namespace DFG {
|
||||
|
||||
MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData*);
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // ENABLE(DFG_JIT)
|
||||
|
||||
#endif // DFGThunks_h
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DFGVariableAccessData_h
|
||||
#define DFGVariableAccessData_h
|
||||
|
||||
#include "DFGOperands.h"
|
||||
#include "PredictedType.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include <wtf/Platform.h>
|
||||
#include <wtf/UnionFind.h>
|
||||
|
||||
namespace JSC { namespace DFG {
|
||||
|
||||
class VariableAccessData : public UnionFind<VariableAccessData> {
|
||||
public:
|
||||
enum Ballot { VoteValue, VoteDouble };
|
||||
|
||||
VariableAccessData()
|
||||
: m_local(static_cast<VirtualRegister>(std::numeric_limits<int>::min()))
|
||||
, m_prediction(PredictNone)
|
||||
, m_shouldUseDoubleFormat(false)
|
||||
{
|
||||
clearVotes();
|
||||
}
|
||||
|
||||
VariableAccessData(VirtualRegister local)
|
||||
: m_local(local)
|
||||
, m_prediction(PredictNone)
|
||||
, m_shouldUseDoubleFormat(false)
|
||||
{
|
||||
clearVotes();
|
||||
}
|
||||
|
||||
VirtualRegister local()
|
||||
{
|
||||
ASSERT(m_local == find()->m_local);
|
||||
return m_local;
|
||||
}
|
||||
|
||||
int operand()
|
||||
{
|
||||
return static_cast<int>(local());
|
||||
}
|
||||
|
||||
bool predict(PredictedType prediction)
|
||||
{
|
||||
return mergePrediction(find()->m_prediction, prediction);
|
||||
}
|
||||
|
||||
PredictedType prediction()
|
||||
{
|
||||
return find()->m_prediction;
|
||||
}
|
||||
|
||||
void clearVotes()
|
||||
{
|
||||
ASSERT(find() == this);
|
||||
m_votes[VoteValue] = 0;
|
||||
m_votes[VoteDouble] = 0;
|
||||
}
|
||||
|
||||
void vote(Ballot ballot)
|
||||
{
|
||||
ASSERT(static_cast<unsigned>(ballot) < 2);
|
||||
m_votes[ballot]++;
|
||||
}
|
||||
|
||||
double doubleVoteRatio()
|
||||
{
|
||||
ASSERT(find() == this);
|
||||
return static_cast<double>(m_votes[VoteDouble]) / m_votes[VoteValue];
|
||||
}
|
||||
|
||||
bool shouldUseDoubleFormatAccordingToVote()
|
||||
{
|
||||
// FIXME: make this work for arguments.
|
||||
return !operandIsArgument(operand()) && ((isNumberPrediction(prediction()) && doubleVoteRatio() >= Options::doubleVoteRatioForDoubleFormat) || isDoublePrediction(prediction()));
|
||||
}
|
||||
|
||||
bool shouldUseDoubleFormat()
|
||||
{
|
||||
ASSERT(find() == this);
|
||||
return m_shouldUseDoubleFormat;
|
||||
}
|
||||
|
||||
bool tallyVotesForShouldUseDoubleFormat()
|
||||
{
|
||||
ASSERT(find() == this);
|
||||
|
||||
bool newValueOfShouldUseDoubleFormat = shouldUseDoubleFormatAccordingToVote();
|
||||
if (!newValueOfShouldUseDoubleFormat) {
|
||||
// We monotonically convert to double. Hence, if the fixpoint leads us to conclude that we should
|
||||
// switch back to int, we instead ignore this and stick with double.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_shouldUseDoubleFormat)
|
||||
return false;
|
||||
|
||||
m_shouldUseDoubleFormat = true;
|
||||
mergePrediction(m_prediction, PredictDouble);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// This is slightly space-inefficient, since anything we're unified with
|
||||
// will have the same operand and should have the same prediction. But
|
||||
// putting them here simplifies the code, and we don't expect DFG space
|
||||
// usage for variable access nodes do be significant.
|
||||
|
||||
VirtualRegister m_local;
|
||||
PredictedType m_prediction;
|
||||
|
||||
float m_votes[2];
|
||||
bool m_shouldUseDoubleFormat;
|
||||
};
|
||||
|
||||
} } // namespace JSC::DFG
|
||||
|
||||
#endif // DFGVariableAccessData_h
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef DataFormat_h
|
||||
#define DataFormat_h
|
||||
|
||||
#include <wtf/Assertions.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// === DataFormat ===
|
||||
//
|
||||
// This enum tracks the current representation in which a value is being held.
|
||||
// Values may be unboxed primitives (int32, double, or cell), or boxed as a JSValue.
|
||||
// For boxed values, we may know the type of boxing that has taken place.
|
||||
// (May also need bool, array, object, string types!)
|
||||
enum DataFormat {
|
||||
DataFormatNone = 0,
|
||||
DataFormatInteger = 1,
|
||||
DataFormatDouble = 2,
|
||||
DataFormatBoolean = 3,
|
||||
DataFormatCell = 4,
|
||||
DataFormatStorage = 5,
|
||||
DataFormatJS = 8,
|
||||
DataFormatJSInteger = DataFormatJS | DataFormatInteger,
|
||||
DataFormatJSDouble = DataFormatJS | DataFormatDouble,
|
||||
DataFormatJSCell = DataFormatJS | DataFormatCell,
|
||||
DataFormatJSBoolean = DataFormatJS | DataFormatBoolean
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
inline const char* dataFormatToString(DataFormat dataFormat)
|
||||
{
|
||||
switch (dataFormat) {
|
||||
case DataFormatNone:
|
||||
return "None";
|
||||
case DataFormatInteger:
|
||||
return "Integer";
|
||||
case DataFormatDouble:
|
||||
return "Double";
|
||||
case DataFormatCell:
|
||||
return "Cell";
|
||||
case DataFormatBoolean:
|
||||
return "Boolean";
|
||||
case DataFormatStorage:
|
||||
return "Storage";
|
||||
case DataFormatJS:
|
||||
return "JS";
|
||||
case DataFormatJSInteger:
|
||||
return "JSInteger";
|
||||
case DataFormatJSDouble:
|
||||
return "JSDouble";
|
||||
case DataFormatJSCell:
|
||||
return "JSCell";
|
||||
case DataFormatJSBoolean:
|
||||
return "JSBoolean";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE(JSVALUE64)
|
||||
inline bool needDataFormatConversion(DataFormat from, DataFormat to)
|
||||
{
|
||||
ASSERT(from != DataFormatNone);
|
||||
ASSERT(to != DataFormatNone);
|
||||
switch (from) {
|
||||
case DataFormatInteger:
|
||||
case DataFormatDouble:
|
||||
return to != from;
|
||||
case DataFormatCell:
|
||||
case DataFormatJS:
|
||||
case DataFormatJSInteger:
|
||||
case DataFormatJSDouble:
|
||||
case DataFormatJSCell:
|
||||
case DataFormatJSBoolean:
|
||||
switch (to) {
|
||||
case DataFormatInteger:
|
||||
case DataFormatDouble:
|
||||
return true;
|
||||
case DataFormatCell:
|
||||
case DataFormatJS:
|
||||
case DataFormatJSInteger:
|
||||
case DataFormatJSDouble:
|
||||
case DataFormatJSCell:
|
||||
case DataFormatJSBoolean:
|
||||
return false;
|
||||
default:
|
||||
// This captures DataFormatBoolean, which is currently unused.
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
case DataFormatStorage:
|
||||
ASSERT(to == DataFormatStorage);
|
||||
return false;
|
||||
default:
|
||||
// This captures DataFormatBoolean, which is currently unused.
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif USE(JSVALUE32_64)
|
||||
inline bool needDataFormatConversion(DataFormat from, DataFormat to)
|
||||
{
|
||||
ASSERT(from != DataFormatNone);
|
||||
ASSERT(to != DataFormatNone);
|
||||
switch (from) {
|
||||
case DataFormatInteger:
|
||||
case DataFormatCell:
|
||||
case DataFormatBoolean:
|
||||
return ((to & DataFormatJS) || to == DataFormatDouble);
|
||||
case DataFormatDouble:
|
||||
case DataFormatJSDouble:
|
||||
return (to != DataFormatDouble && to != DataFormatJSDouble);
|
||||
case DataFormatJS:
|
||||
case DataFormatJSInteger:
|
||||
case DataFormatJSCell:
|
||||
case DataFormatJSBoolean:
|
||||
return (!(to & DataFormatJS) || to == DataFormatJSDouble);
|
||||
case DataFormatStorage:
|
||||
ASSERT(to == DataFormatStorage);
|
||||
return false;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool isJSFormat(DataFormat format, DataFormat expectedFormat)
|
||||
{
|
||||
ASSERT(expectedFormat & DataFormatJS);
|
||||
return (format | DataFormatJS) == expectedFormat;
|
||||
}
|
||||
|
||||
inline bool isJSInteger(DataFormat format)
|
||||
{
|
||||
return isJSFormat(format, DataFormatJSInteger);
|
||||
}
|
||||
|
||||
inline bool isJSDouble(DataFormat format)
|
||||
{
|
||||
return isJSFormat(format, DataFormatJSDouble);
|
||||
}
|
||||
|
||||
inline bool isJSCell(DataFormat format)
|
||||
{
|
||||
return isJSFormat(format, DataFormatJSCell);
|
||||
}
|
||||
|
||||
inline bool isJSBoolean(DataFormat format)
|
||||
{
|
||||
return isJSFormat(format, DataFormatJSBoolean);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // DataFormat_h
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DateInstance_h
|
||||
#define DateInstance_h
|
||||
|
||||
#include "JSWrapperObject.h"
|
||||
|
||||
namespace WTF {
|
||||
struct GregorianDateTime;
|
||||
}
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class DateInstance : public JSWrapperObject {
|
||||
protected:
|
||||
JS_EXPORT_PRIVATE DateInstance(ExecState*, Structure*);
|
||||
void finishCreation(JSGlobalData&);
|
||||
JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, double);
|
||||
|
||||
static void destroy(JSCell*);
|
||||
|
||||
public:
|
||||
typedef JSWrapperObject Base;
|
||||
|
||||
static DateInstance* create(ExecState* exec, Structure* structure, double date)
|
||||
{
|
||||
DateInstance* instance = new (NotNull, allocateCell<DateInstance>(*exec->heap())) DateInstance(exec, structure);
|
||||
instance->finishCreation(exec->globalData(), date);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static DateInstance* create(ExecState* exec, Structure* structure)
|
||||
{
|
||||
DateInstance* instance = new (NotNull, allocateCell<DateInstance>(*exec->heap())) DateInstance(exec, structure);
|
||||
instance->finishCreation(exec->globalData());
|
||||
return instance;
|
||||
}
|
||||
|
||||
double internalNumber() const { return internalValue().asNumber(); }
|
||||
|
||||
static JS_EXPORTDATA const ClassInfo s_info;
|
||||
|
||||
const GregorianDateTime* gregorianDateTime(ExecState* exec) const
|
||||
{
|
||||
if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber())
|
||||
return &m_data->m_cachedGregorianDateTime;
|
||||
return calculateGregorianDateTime(exec);
|
||||
}
|
||||
|
||||
const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const
|
||||
{
|
||||
if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber())
|
||||
return &m_data->m_cachedGregorianDateTimeUTC;
|
||||
return calculateGregorianDateTimeUTC(exec);
|
||||
}
|
||||
|
||||
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
|
||||
{
|
||||
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
|
||||
}
|
||||
|
||||
private:
|
||||
const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
|
||||
const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
|
||||
|
||||
mutable RefPtr<DateInstanceData> m_data;
|
||||
};
|
||||
|
||||
DateInstance* asDateInstance(JSValue);
|
||||
|
||||
inline DateInstance* asDateInstance(JSValue value)
|
||||
{
|
||||
ASSERT(asObject(value)->inherits(&DateInstance::s_info));
|
||||
return static_cast<DateInstance*>(asObject(value));
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // DateInstance_h
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef DateInstanceCache_h
|
||||
#define DateInstanceCache_h
|
||||
|
||||
#include "JSDateMath.h"
|
||||
#include <wtf/FixedArray.h>
|
||||
#include <wtf/HashFunctions.h>
|
||||
#include <wtf/PassRefPtr.h>
|
||||
#include <wtf/RefCounted.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class DateInstanceData : public RefCounted<DateInstanceData> {
|
||||
public:
|
||||
static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }
|
||||
|
||||
double m_gregorianDateTimeCachedForMS;
|
||||
GregorianDateTime m_cachedGregorianDateTime;
|
||||
double m_gregorianDateTimeUTCCachedForMS;
|
||||
GregorianDateTime m_cachedGregorianDateTimeUTC;
|
||||
|
||||
private:
|
||||
DateInstanceData()
|
||||
: m_gregorianDateTimeCachedForMS(std::numeric_limits<double>::quiet_NaN())
|
||||
, m_gregorianDateTimeUTCCachedForMS(std::numeric_limits<double>::quiet_NaN())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DateInstanceCache {
|
||||
public:
|
||||
DateInstanceCache()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
for (size_t i = 0; i < cacheSize; ++i)
|
||||
m_cache[i].key = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
DateInstanceData* add(double d)
|
||||
{
|
||||
CacheEntry& entry = lookup(d);
|
||||
if (d == entry.key)
|
||||
return entry.value.get();
|
||||
|
||||
entry.key = d;
|
||||
entry.value = DateInstanceData::create();
|
||||
return entry.value.get();
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t cacheSize = 16;
|
||||
|
||||
struct CacheEntry {
|
||||
double key;
|
||||
RefPtr<DateInstanceData> value;
|
||||
};
|
||||
|
||||
CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
|
||||
|
||||
FixedArray<CacheEntry, cacheSize> m_cache;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // DateInstanceCache_h
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2009 Google Inc. All rights reserved.
|
||||
* Copyright (C) 2010 Research In Motion Limited. All rights reserved.
|
||||
*
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DateMath_h
|
||||
#define DateMath_h
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <wtf/CurrentTime.h>
|
||||
#include <wtf/Noncopyable.h>
|
||||
#include <wtf/OwnArrayPtr.h>
|
||||
#include <wtf/PassOwnArrayPtr.h>
|
||||
#include <wtf/text/WTFString.h>
|
||||
#include <wtf/UnusedParam.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
void initializeDates();
|
||||
int equivalentYearForDST(int year);
|
||||
|
||||
// Not really math related, but this is currently the only shared place to put these.
|
||||
double parseES5DateFromNullTerminatedCharacters(const char* dateString);
|
||||
WTF_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(const char* dateString);
|
||||
double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset);
|
||||
double timeClip(double);
|
||||
// dayOfWeek: [0, 6] 0 being Monday, day: [1, 31], month: [0, 11], year: ex: 2011, hours: [0, 23], minutes: [0, 59], seconds: [0, 59], utcOffset: [-720,720].
|
||||
String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, unsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset);
|
||||
|
||||
inline double jsCurrentTime()
|
||||
{
|
||||
// JavaScript doesn't recognize fractions of a millisecond.
|
||||
return floor(WTF::currentTimeMS());
|
||||
}
|
||||
|
||||
const char* const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
|
||||
const char* const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
const double hoursPerDay = 24.0;
|
||||
const double minutesPerHour = 60.0;
|
||||
const double secondsPerHour = 60.0 * 60.0;
|
||||
const double secondsPerMinute = 60.0;
|
||||
const double msPerSecond = 1000.0;
|
||||
const double msPerMinute = 60.0 * 1000.0;
|
||||
const double msPerHour = 60.0 * 60.0 * 1000.0;
|
||||
const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
|
||||
const double msPerMonth = 2592000000.0;
|
||||
|
||||
bool isLeapYear(int year);
|
||||
|
||||
// Returns the number of days from 1970-01-01 to the specified date.
|
||||
WTF_EXPORT_PRIVATE double dateToDaysFrom1970(int year, int month, int day);
|
||||
WTF_EXPORT_PRIVATE int msToYear(double ms);
|
||||
double msToDays(double ms);
|
||||
int msToMinutes(double ms);
|
||||
int msToHours(double ms);
|
||||
WTF_EXPORT_PRIVATE int dayInYear(double ms, int year);
|
||||
WTF_EXPORT_PRIVATE int monthFromDayInYear(int dayInYear, bool leapYear);
|
||||
WTF_EXPORT_PRIVATE int dayInMonthFromDayInYear(int dayInYear, bool leapYear);
|
||||
|
||||
// Returns offset milliseconds for UTC and DST.
|
||||
WTF_EXPORT_PRIVATE int32_t calculateUTCOffset();
|
||||
WTF_EXPORT_PRIVATE double calculateDSTOffset(double ms, double utcOffset);
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::isLeapYear;
|
||||
using WTF::dateToDaysFrom1970;
|
||||
using WTF::dayInMonthFromDayInYear;
|
||||
using WTF::dayInYear;
|
||||
using WTF::minutesPerHour;
|
||||
using WTF::monthFromDayInYear;
|
||||
using WTF::msPerDay;
|
||||
using WTF::msPerMinute;
|
||||
using WTF::msPerSecond;
|
||||
using WTF::msToYear;
|
||||
using WTF::msToDays;
|
||||
using WTF::msToMinutes;
|
||||
using WTF::msToHours;
|
||||
using WTF::secondsPerMinute;
|
||||
using WTF::parseDateFromNullTerminatedCharacters;
|
||||
using WTF::makeRFC2822DateString;
|
||||
using WTF::calculateUTCOffset;
|
||||
using WTF::calculateDSTOffset;
|
||||
|
||||
#endif // DateMath_h
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
|
||||
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef Debugger_h
|
||||
#define Debugger_h
|
||||
|
||||
#include <wtf/HashSet.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class DebuggerCallFrame;
|
||||
class ExecState;
|
||||
class JSGlobalData;
|
||||
class JSGlobalObject;
|
||||
class JSValue;
|
||||
class SourceProvider;
|
||||
class UString;
|
||||
|
||||
class JS_EXPORT_PRIVATE Debugger {
|
||||
public:
|
||||
virtual ~Debugger();
|
||||
|
||||
void attach(JSGlobalObject*);
|
||||
virtual void detach(JSGlobalObject*);
|
||||
|
||||
virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const UString& errorMessage) = 0;
|
||||
virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, bool hasHandler) = 0;
|
||||
virtual void atStatement(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
|
||||
virtual void callEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
|
||||
virtual void returnEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
|
||||
|
||||
virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
|
||||
virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
|
||||
virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
|
||||
|
||||
void recompileAllJSFunctions(JSGlobalData*);
|
||||
|
||||
private:
|
||||
HashSet<JSGlobalObject*> m_globalObjects;
|
||||
};
|
||||
|
||||
// This function exists only for backwards compatibility with existing WebScriptDebugger clients.
|
||||
JS_EXPORT_PRIVATE JSValue evaluateInGlobalCallFrame(const UString&, JSValue& exception, JSGlobalObject*);
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // Debugger_h
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008, 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef DebuggerActivation_h
|
||||
#define DebuggerActivation_h
|
||||
|
||||
#include "JSObject.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class DebuggerActivation : public JSNonFinalObject {
|
||||
public:
|
||||
typedef JSNonFinalObject Base;
|
||||
|
||||
static DebuggerActivation* create(JSGlobalData& globalData, JSObject* object)
|
||||
{
|
||||
DebuggerActivation* activation = new (NotNull, allocateCell<DebuggerActivation>(globalData.heap)) DebuggerActivation(globalData);
|
||||
activation->finishCreation(globalData, object);
|
||||
return activation;
|
||||
}
|
||||
|
||||
static void visitChildren(JSCell*, SlotVisitor&);
|
||||
static UString className(const JSObject*);
|
||||
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&);
|
||||
static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
|
||||
static void putDirectVirtual(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
|
||||
static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
|
||||
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
|
||||
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
|
||||
static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes);
|
||||
static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes);
|
||||
|
||||
JS_EXPORTDATA static const ClassInfo s_info;
|
||||
|
||||
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
|
||||
{
|
||||
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
|
||||
}
|
||||
|
||||
protected:
|
||||
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | JSObject::StructureFlags;
|
||||
|
||||
JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, JSObject* activation);
|
||||
|
||||
private:
|
||||
JS_EXPORT_PRIVATE DebuggerActivation(JSGlobalData&);
|
||||
WriteBarrier<JSActivation> m_activation;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // DebuggerActivation_h
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef DebuggerCallFrame_h
|
||||
#define DebuggerCallFrame_h
|
||||
|
||||
#include "CallFrame.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class DebuggerCallFrame {
|
||||
public:
|
||||
enum Type { ProgramType, FunctionType };
|
||||
|
||||
DebuggerCallFrame(CallFrame* callFrame)
|
||||
: m_callFrame(callFrame)
|
||||
{
|
||||
}
|
||||
|
||||
DebuggerCallFrame(CallFrame* callFrame, JSValue exception)
|
||||
: m_callFrame(callFrame)
|
||||
, m_exception(exception)
|
||||
{
|
||||
}
|
||||
|
||||
JSGlobalObject* dynamicGlobalObject() const { return m_callFrame->dynamicGlobalObject(); }
|
||||
ScopeChainNode* scopeChain() const { return m_callFrame->scopeChain(); }
|
||||
JS_EXPORT_PRIVATE const UString* functionName() const;
|
||||
JS_EXPORT_PRIVATE UString calculatedFunctionName() const;
|
||||
JS_EXPORT_PRIVATE Type type() const;
|
||||
JS_EXPORT_PRIVATE JSObject* thisObject() const;
|
||||
JS_EXPORT_PRIVATE JSValue evaluate(const UString&, JSValue& exception) const;
|
||||
JSValue exception() const { return m_exception; }
|
||||
|
||||
private:
|
||||
CallFrame* m_callFrame;
|
||||
JSValue m_exception;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // DebuggerCallFrame_h
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef DecimalNumber_h
|
||||
#define DecimalNumber_h
|
||||
|
||||
#include <math.h>
|
||||
#include <wtf/dtoa.h>
|
||||
#include <wtf/MathExtras.h>
|
||||
#include <wtf/text/WTFString.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
enum RoundingSignificantFiguresType { RoundingSignificantFigures };
|
||||
enum RoundingDecimalPlacesType { RoundingDecimalPlaces };
|
||||
|
||||
class DecimalNumber {
|
||||
public:
|
||||
DecimalNumber(double d)
|
||||
{
|
||||
ASSERT(isfinite(d));
|
||||
dtoa(m_significand, d, m_sign, m_exponent, m_precision);
|
||||
|
||||
ASSERT(m_precision);
|
||||
// Zero should always have exponent 0.
|
||||
ASSERT(m_significand[0] != '0' || !m_exponent);
|
||||
// No values other than zero should have a leading zero.
|
||||
ASSERT(m_significand[0] != '0' || m_precision == 1);
|
||||
// No values other than zero should have trailing zeros.
|
||||
ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0');
|
||||
}
|
||||
|
||||
DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
|
||||
{
|
||||
ASSERT(isfinite(d));
|
||||
dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
|
||||
|
||||
ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer));
|
||||
while (m_precision < significantFigures)
|
||||
m_significand[m_precision++] = '0';
|
||||
|
||||
ASSERT(m_precision);
|
||||
// Zero should always have exponent 0.
|
||||
ASSERT(m_significand[0] != '0' || !m_exponent);
|
||||
}
|
||||
|
||||
DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
|
||||
{
|
||||
ASSERT(isfinite(d));
|
||||
dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
|
||||
|
||||
unsigned significantFigures = 1 + m_exponent + decimalPlaces;
|
||||
ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer));
|
||||
while (m_precision < significantFigures)
|
||||
m_significand[m_precision++] = '0';
|
||||
|
||||
ASSERT(m_precision);
|
||||
// Zero should always have exponent 0.
|
||||
ASSERT(m_significand[0] != '0' || !m_exponent);
|
||||
}
|
||||
|
||||
WTF_EXPORT_PRIVATE unsigned bufferLengthForStringDecimal() const;
|
||||
WTF_EXPORT_PRIVATE unsigned bufferLengthForStringExponential() const;
|
||||
|
||||
WTF_EXPORT_PRIVATE unsigned toStringDecimal(UChar* buffer, unsigned bufferLength) const;
|
||||
WTF_EXPORT_PRIVATE unsigned toStringExponential(UChar* buffer, unsigned bufferLength) const;
|
||||
|
||||
bool sign() const { return m_sign; }
|
||||
int exponent() const { return m_exponent; }
|
||||
const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
|
||||
unsigned precision() const { return m_precision; }
|
||||
|
||||
private:
|
||||
bool m_sign;
|
||||
int m_exponent;
|
||||
DtoaBuffer m_significand;
|
||||
unsigned m_precision;
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::DecimalNumber;
|
||||
using WTF::RoundingSignificantFigures;
|
||||
using WTF::RoundingDecimalPlaces;
|
||||
|
||||
#endif // DecimalNumber_h
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef Decoder_h
|
||||
#define Decoder_h
|
||||
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class String;
|
||||
|
||||
class Decoder {
|
||||
protected:
|
||||
Decoder() { }
|
||||
virtual ~Decoder() { }
|
||||
|
||||
public:
|
||||
virtual bool decodeBytes(Vector<uint8_t>&) = 0;
|
||||
|
||||
virtual bool decodeBool(bool&) = 0;
|
||||
virtual bool decodeUInt32(uint32_t&) = 0;
|
||||
virtual bool decodeUInt64(uint64_t&) = 0;
|
||||
virtual bool decodeInt32(int32_t&) = 0;
|
||||
virtual bool decodeInt64(int64_t&) = 0;
|
||||
virtual bool decodeFloat(float&) = 0;
|
||||
virtual bool decodeDouble(double&) = 0;
|
||||
virtual bool decodeString(String&) = 0;
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::Decoder;
|
||||
|
||||
#endif // Decoder_h
|
||||
@@ -1,690 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2009 Google 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_Deque_h
|
||||
#define WTF_Deque_h
|
||||
|
||||
// FIXME: Could move what Vector and Deque share into a separate file.
|
||||
// Deque doesn't actually use Vector.
|
||||
|
||||
#include "PassTraits.h"
|
||||
#include "Vector.h"
|
||||
|
||||
namespace WTF {
|
||||
|
||||
template<typename T, size_t inlineCapacity> class DequeIteratorBase;
|
||||
template<typename T, size_t inlineCapacity> class DequeIterator;
|
||||
template<typename T, size_t inlineCapacity> class DequeConstIterator;
|
||||
template<typename T, size_t inlineCapacity> class DequeReverseIterator;
|
||||
template<typename T, size_t inlineCapacity> class DequeConstReverseIterator;
|
||||
|
||||
template<typename T, size_t inlineCapacity = 0>
|
||||
class Deque {
|
||||
WTF_MAKE_FAST_ALLOCATED;
|
||||
public:
|
||||
typedef DequeIterator<T, inlineCapacity> iterator;
|
||||
typedef DequeConstIterator<T, inlineCapacity> const_iterator;
|
||||
typedef DequeReverseIterator<T, inlineCapacity> reverse_iterator;
|
||||
typedef DequeConstReverseIterator<T, inlineCapacity> const_reverse_iterator;
|
||||
typedef PassTraits<T> Pass;
|
||||
typedef typename PassTraits<T>::PassType PassType;
|
||||
|
||||
Deque();
|
||||
Deque(const Deque<T, inlineCapacity>&);
|
||||
Deque& operator=(const Deque<T, inlineCapacity>&);
|
||||
~Deque();
|
||||
|
||||
void swap(Deque<T, inlineCapacity>&);
|
||||
|
||||
size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; }
|
||||
bool isEmpty() const { return m_start == m_end; }
|
||||
|
||||
iterator begin() { return iterator(this, m_start); }
|
||||
iterator end() { return iterator(this, m_end); }
|
||||
const_iterator begin() const { return const_iterator(this, m_start); }
|
||||
const_iterator end() const { return const_iterator(this, m_end); }
|
||||
reverse_iterator rbegin() { return reverse_iterator(this, m_end); }
|
||||
reverse_iterator rend() { return reverse_iterator(this, m_start); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(this, m_end); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(this, m_start); }
|
||||
|
||||
T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
|
||||
const T& first() const { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
|
||||
PassType takeFirst();
|
||||
|
||||
T& last() { ASSERT(m_start != m_end); return *(--end()); }
|
||||
const T& last() const { ASSERT(m_start != m_end); return *(--end()); }
|
||||
|
||||
template<typename U> void append(const U&);
|
||||
template<typename U> void prepend(const U&);
|
||||
void removeFirst();
|
||||
void remove(iterator&);
|
||||
void remove(const_iterator&);
|
||||
|
||||
void clear();
|
||||
|
||||
template<typename Predicate>
|
||||
iterator findIf(Predicate&);
|
||||
|
||||
private:
|
||||
friend class DequeIteratorBase<T, inlineCapacity>;
|
||||
|
||||
typedef VectorBuffer<T, inlineCapacity> Buffer;
|
||||
typedef VectorTypeOperations<T> TypeOperations;
|
||||
typedef DequeIteratorBase<T, inlineCapacity> IteratorBase;
|
||||
|
||||
void remove(size_t position);
|
||||
void invalidateIterators();
|
||||
void destroyAll();
|
||||
void checkValidity() const;
|
||||
void checkIndexValidity(size_t) const;
|
||||
void expandCapacityIfNeeded();
|
||||
void expandCapacity();
|
||||
|
||||
size_t m_start;
|
||||
size_t m_end;
|
||||
Buffer m_buffer;
|
||||
#ifndef NDEBUG
|
||||
mutable IteratorBase* m_iterators;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T, size_t inlineCapacity = 0>
|
||||
class DequeIteratorBase {
|
||||
private:
|
||||
typedef DequeIteratorBase<T, inlineCapacity> Base;
|
||||
|
||||
protected:
|
||||
DequeIteratorBase();
|
||||
DequeIteratorBase(const Deque<T, inlineCapacity>*, size_t);
|
||||
DequeIteratorBase(const Base&);
|
||||
Base& operator=(const Base&);
|
||||
~DequeIteratorBase();
|
||||
|
||||
void assign(const Base& other) { *this = other; }
|
||||
|
||||
void increment();
|
||||
void decrement();
|
||||
|
||||
T* before() const;
|
||||
T* after() const;
|
||||
|
||||
bool isEqual(const Base&) const;
|
||||
|
||||
private:
|
||||
void addToIteratorsList();
|
||||
void removeFromIteratorsList();
|
||||
void checkValidity() const;
|
||||
void checkValidity(const Base&) const;
|
||||
|
||||
Deque<T, inlineCapacity>* m_deque;
|
||||
size_t m_index;
|
||||
|
||||
friend class Deque<T, inlineCapacity>;
|
||||
|
||||
#ifndef NDEBUG
|
||||
mutable DequeIteratorBase* m_next;
|
||||
mutable DequeIteratorBase* m_previous;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T, size_t inlineCapacity = 0>
|
||||
class DequeIterator : public DequeIteratorBase<T, inlineCapacity> {
|
||||
private:
|
||||
typedef DequeIteratorBase<T, inlineCapacity> Base;
|
||||
typedef DequeIterator<T, inlineCapacity> Iterator;
|
||||
|
||||
public:
|
||||
DequeIterator(Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
|
||||
|
||||
DequeIterator(const Iterator& other) : Base(other) { }
|
||||
DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
|
||||
|
||||
T& operator*() const { return *Base::after(); }
|
||||
T* operator->() const { return Base::after(); }
|
||||
|
||||
bool operator==(const Iterator& other) const { return Base::isEqual(other); }
|
||||
bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
|
||||
|
||||
Iterator& operator++() { Base::increment(); return *this; }
|
||||
// postfix ++ intentionally omitted
|
||||
Iterator& operator--() { Base::decrement(); return *this; }
|
||||
// postfix -- intentionally omitted
|
||||
};
|
||||
|
||||
template<typename T, size_t inlineCapacity = 0>
|
||||
class DequeConstIterator : public DequeIteratorBase<T, inlineCapacity> {
|
||||
private:
|
||||
typedef DequeIteratorBase<T, inlineCapacity> Base;
|
||||
typedef DequeConstIterator<T, inlineCapacity> Iterator;
|
||||
typedef DequeIterator<T, inlineCapacity> NonConstIterator;
|
||||
|
||||
public:
|
||||
DequeConstIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
|
||||
|
||||
DequeConstIterator(const Iterator& other) : Base(other) { }
|
||||
DequeConstIterator(const NonConstIterator& other) : Base(other) { }
|
||||
DequeConstIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
|
||||
DequeConstIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }
|
||||
|
||||
const T& operator*() const { return *Base::after(); }
|
||||
const T* operator->() const { return Base::after(); }
|
||||
|
||||
bool operator==(const Iterator& other) const { return Base::isEqual(other); }
|
||||
bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
|
||||
|
||||
Iterator& operator++() { Base::increment(); return *this; }
|
||||
// postfix ++ intentionally omitted
|
||||
Iterator& operator--() { Base::decrement(); return *this; }
|
||||
// postfix -- intentionally omitted
|
||||
};
|
||||
|
||||
template<typename T, size_t inlineCapacity = 0>
|
||||
class DequeReverseIterator : public DequeIteratorBase<T, inlineCapacity> {
|
||||
private:
|
||||
typedef DequeIteratorBase<T, inlineCapacity> Base;
|
||||
typedef DequeReverseIterator<T, inlineCapacity> Iterator;
|
||||
|
||||
public:
|
||||
DequeReverseIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
|
||||
|
||||
DequeReverseIterator(const Iterator& other) : Base(other) { }
|
||||
DequeReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
|
||||
|
||||
T& operator*() const { return *Base::before(); }
|
||||
T* operator->() const { return Base::before(); }
|
||||
|
||||
bool operator==(const Iterator& other) const { return Base::isEqual(other); }
|
||||
bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
|
||||
|
||||
Iterator& operator++() { Base::decrement(); return *this; }
|
||||
// postfix ++ intentionally omitted
|
||||
Iterator& operator--() { Base::increment(); return *this; }
|
||||
// postfix -- intentionally omitted
|
||||
};
|
||||
|
||||
template<typename T, size_t inlineCapacity = 0>
|
||||
class DequeConstReverseIterator : public DequeIteratorBase<T, inlineCapacity> {
|
||||
private:
|
||||
typedef DequeIteratorBase<T, inlineCapacity> Base;
|
||||
typedef DequeConstReverseIterator<T, inlineCapacity> Iterator;
|
||||
typedef DequeReverseIterator<T, inlineCapacity> NonConstIterator;
|
||||
|
||||
public:
|
||||
DequeConstReverseIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
|
||||
|
||||
DequeConstReverseIterator(const Iterator& other) : Base(other) { }
|
||||
DequeConstReverseIterator(const NonConstIterator& other) : Base(other) { }
|
||||
DequeConstReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
|
||||
DequeConstReverseIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }
|
||||
|
||||
const T& operator*() const { return *Base::before(); }
|
||||
const T* operator->() const { return Base::before(); }
|
||||
|
||||
bool operator==(const Iterator& other) const { return Base::isEqual(other); }
|
||||
bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
|
||||
|
||||
Iterator& operator++() { Base::decrement(); return *this; }
|
||||
// postfix ++ intentionally omitted
|
||||
Iterator& operator--() { Base::increment(); return *this; }
|
||||
// postfix -- intentionally omitted
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkValidity() const { }
|
||||
template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkIndexValidity(size_t) const { }
|
||||
template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::invalidateIterators() { }
|
||||
#else
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void Deque<T, inlineCapacity>::checkValidity() const
|
||||
{
|
||||
// In this implementation a capacity of 1 would confuse append() and
|
||||
// other places that assume the index after capacity - 1 is 0.
|
||||
ASSERT(m_buffer.capacity() != 1);
|
||||
|
||||
if (!m_buffer.capacity()) {
|
||||
ASSERT(!m_start);
|
||||
ASSERT(!m_end);
|
||||
} else {
|
||||
ASSERT(m_start < m_buffer.capacity());
|
||||
ASSERT(m_end < m_buffer.capacity());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void Deque<T, inlineCapacity>::checkIndexValidity(size_t index) const
|
||||
{
|
||||
ASSERT_UNUSED(index, index <= m_buffer.capacity());
|
||||
if (m_start <= m_end) {
|
||||
ASSERT(index >= m_start);
|
||||
ASSERT(index <= m_end);
|
||||
} else {
|
||||
ASSERT(index >= m_start || index <= m_end);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void Deque<T, inlineCapacity>::invalidateIterators()
|
||||
{
|
||||
IteratorBase* next;
|
||||
for (IteratorBase* p = m_iterators; p; p = next) {
|
||||
next = p->m_next;
|
||||
p->m_deque = 0;
|
||||
p->m_next = 0;
|
||||
p->m_previous = 0;
|
||||
}
|
||||
m_iterators = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline Deque<T, inlineCapacity>::Deque()
|
||||
: m_start(0)
|
||||
, m_end(0)
|
||||
#ifndef NDEBUG
|
||||
, m_iterators(0)
|
||||
#endif
|
||||
{
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline Deque<T, inlineCapacity>::Deque(const Deque<T, inlineCapacity>& other)
|
||||
: m_start(other.m_start)
|
||||
, m_end(other.m_end)
|
||||
, m_buffer(other.m_buffer.capacity())
|
||||
#ifndef NDEBUG
|
||||
, m_iterators(0)
|
||||
#endif
|
||||
{
|
||||
const T* otherBuffer = other.m_buffer.buffer();
|
||||
if (m_start <= m_end)
|
||||
TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, m_buffer.buffer() + m_start);
|
||||
else {
|
||||
TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, m_buffer.buffer());
|
||||
TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_buffer.capacity(), m_buffer.buffer() + m_start);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void deleteAllValues(const Deque<T, inlineCapacity>& collection)
|
||||
{
|
||||
typedef typename Deque<T, inlineCapacity>::const_iterator iterator;
|
||||
iterator end = collection.end();
|
||||
for (iterator it = collection.begin(); it != end; ++it)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline Deque<T, inlineCapacity>& Deque<T, inlineCapacity>::operator=(const Deque<T, inlineCapacity>& other)
|
||||
{
|
||||
// FIXME: This is inefficient if we're using an inline buffer and T is
|
||||
// expensive to copy since it will copy the buffer twice instead of once.
|
||||
Deque<T> copy(other);
|
||||
swap(copy);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::destroyAll()
|
||||
{
|
||||
if (m_start <= m_end)
|
||||
TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end);
|
||||
else {
|
||||
TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_end);
|
||||
TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_buffer.capacity());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline Deque<T, inlineCapacity>::~Deque()
|
||||
{
|
||||
checkValidity();
|
||||
invalidateIterators();
|
||||
destroyAll();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::swap(Deque<T, inlineCapacity>& other)
|
||||
{
|
||||
checkValidity();
|
||||
other.checkValidity();
|
||||
invalidateIterators();
|
||||
std::swap(m_start, other.m_start);
|
||||
std::swap(m_end, other.m_end);
|
||||
m_buffer.swap(other.m_buffer);
|
||||
checkValidity();
|
||||
other.checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::clear()
|
||||
{
|
||||
checkValidity();
|
||||
invalidateIterators();
|
||||
destroyAll();
|
||||
m_start = 0;
|
||||
m_end = 0;
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
template<typename Predicate>
|
||||
inline DequeIterator<T, inlineCapacity> Deque<T, inlineCapacity>::findIf(Predicate& predicate)
|
||||
{
|
||||
iterator end_iterator = end();
|
||||
for (iterator it = begin(); it != end_iterator; ++it) {
|
||||
if (predicate(*it))
|
||||
return it;
|
||||
}
|
||||
return end_iterator;
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::expandCapacityIfNeeded()
|
||||
{
|
||||
if (m_start) {
|
||||
if (m_end + 1 != m_start)
|
||||
return;
|
||||
} else if (m_end) {
|
||||
if (m_end != m_buffer.capacity() - 1)
|
||||
return;
|
||||
} else if (m_buffer.capacity())
|
||||
return;
|
||||
|
||||
expandCapacity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void Deque<T, inlineCapacity>::expandCapacity()
|
||||
{
|
||||
checkValidity();
|
||||
size_t oldCapacity = m_buffer.capacity();
|
||||
size_t newCapacity = max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1);
|
||||
T* oldBuffer = m_buffer.buffer();
|
||||
m_buffer.allocateBuffer(newCapacity);
|
||||
if (m_start <= m_end)
|
||||
TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffer.buffer() + m_start);
|
||||
else {
|
||||
TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer());
|
||||
size_t newStart = newCapacity - (oldCapacity - m_start);
|
||||
TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m_buffer.buffer() + newStart);
|
||||
m_start = newStart;
|
||||
}
|
||||
m_buffer.deallocateBuffer(oldBuffer);
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline typename Deque<T, inlineCapacity>::PassType Deque<T, inlineCapacity>::takeFirst()
|
||||
{
|
||||
T oldFirst = Pass::transfer(first());
|
||||
removeFirst();
|
||||
return Pass::transfer(oldFirst);
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity> template<typename U>
|
||||
inline void Deque<T, inlineCapacity>::append(const U& value)
|
||||
{
|
||||
checkValidity();
|
||||
expandCapacityIfNeeded();
|
||||
new (NotNull, &m_buffer.buffer()[m_end]) T(value);
|
||||
if (m_end == m_buffer.capacity() - 1)
|
||||
m_end = 0;
|
||||
else
|
||||
++m_end;
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity> template<typename U>
|
||||
inline void Deque<T, inlineCapacity>::prepend(const U& value)
|
||||
{
|
||||
checkValidity();
|
||||
expandCapacityIfNeeded();
|
||||
if (!m_start)
|
||||
m_start = m_buffer.capacity() - 1;
|
||||
else
|
||||
--m_start;
|
||||
new (NotNull, &m_buffer.buffer()[m_start]) T(value);
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::removeFirst()
|
||||
{
|
||||
checkValidity();
|
||||
invalidateIterators();
|
||||
ASSERT(!isEmpty());
|
||||
TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer()[m_start + 1]);
|
||||
if (m_start == m_buffer.capacity() - 1)
|
||||
m_start = 0;
|
||||
else
|
||||
++m_start;
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::remove(iterator& it)
|
||||
{
|
||||
it.checkValidity();
|
||||
remove(it.m_index);
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::remove(const_iterator& it)
|
||||
{
|
||||
it.checkValidity();
|
||||
remove(it.m_index);
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void Deque<T, inlineCapacity>::remove(size_t position)
|
||||
{
|
||||
if (position == m_end)
|
||||
return;
|
||||
|
||||
checkValidity();
|
||||
invalidateIterators();
|
||||
|
||||
T* buffer = m_buffer.buffer();
|
||||
TypeOperations::destruct(&buffer[position], &buffer[position + 1]);
|
||||
|
||||
// Find which segment of the circular buffer contained the remove element, and only move elements in that part.
|
||||
if (position >= m_start) {
|
||||
TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1);
|
||||
m_start = (m_start + 1) % m_buffer.capacity();
|
||||
} else {
|
||||
TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position);
|
||||
m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity();
|
||||
}
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity() const { }
|
||||
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase<T, inlineCapacity>&) const { }
|
||||
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList() { }
|
||||
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList() { }
|
||||
#else
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void DequeIteratorBase<T, inlineCapacity>::checkValidity() const
|
||||
{
|
||||
ASSERT(m_deque);
|
||||
m_deque->checkIndexValidity(m_index);
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void DequeIteratorBase<T, inlineCapacity>::checkValidity(const Base& other) const
|
||||
{
|
||||
checkValidity();
|
||||
other.checkValidity();
|
||||
ASSERT(m_deque == other.m_deque);
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList()
|
||||
{
|
||||
if (!m_deque)
|
||||
m_next = 0;
|
||||
else {
|
||||
m_next = m_deque->m_iterators;
|
||||
m_deque->m_iterators = this;
|
||||
if (m_next)
|
||||
m_next->m_previous = this;
|
||||
}
|
||||
m_previous = 0;
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList()
|
||||
{
|
||||
if (!m_deque) {
|
||||
ASSERT(!m_next);
|
||||
ASSERT(!m_previous);
|
||||
} else {
|
||||
if (m_next) {
|
||||
ASSERT(m_next->m_previous == this);
|
||||
m_next->m_previous = m_previous;
|
||||
}
|
||||
if (m_previous) {
|
||||
ASSERT(m_deque->m_iterators != this);
|
||||
ASSERT(m_previous->m_next == this);
|
||||
m_previous->m_next = m_next;
|
||||
} else {
|
||||
ASSERT(m_deque->m_iterators == this);
|
||||
m_deque->m_iterators = m_next;
|
||||
}
|
||||
}
|
||||
m_next = 0;
|
||||
m_previous = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase()
|
||||
: m_deque(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Deque<T, inlineCapacity>* deque, size_t index)
|
||||
: m_deque(const_cast<Deque<T, inlineCapacity>*>(deque))
|
||||
, m_index(index)
|
||||
{
|
||||
addToIteratorsList();
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Base& other)
|
||||
: m_deque(other.m_deque)
|
||||
, m_index(other.m_index)
|
||||
{
|
||||
addToIteratorsList();
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline DequeIteratorBase<T, inlineCapacity>& DequeIteratorBase<T, inlineCapacity>::operator=(const Base& other)
|
||||
{
|
||||
other.checkValidity();
|
||||
removeFromIteratorsList();
|
||||
|
||||
m_deque = other.m_deque;
|
||||
m_index = other.m_index;
|
||||
addToIteratorsList();
|
||||
checkValidity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline DequeIteratorBase<T, inlineCapacity>::~DequeIteratorBase()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
removeFromIteratorsList();
|
||||
m_deque = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline bool DequeIteratorBase<T, inlineCapacity>::isEqual(const Base& other) const
|
||||
{
|
||||
checkValidity(other);
|
||||
return m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void DequeIteratorBase<T, inlineCapacity>::increment()
|
||||
{
|
||||
checkValidity();
|
||||
ASSERT(m_index != m_deque->m_end);
|
||||
ASSERT(m_deque->m_buffer.capacity());
|
||||
if (m_index == m_deque->m_buffer.capacity() - 1)
|
||||
m_index = 0;
|
||||
else
|
||||
++m_index;
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline void DequeIteratorBase<T, inlineCapacity>::decrement()
|
||||
{
|
||||
checkValidity();
|
||||
ASSERT(m_index != m_deque->m_start);
|
||||
ASSERT(m_deque->m_buffer.capacity());
|
||||
if (!m_index)
|
||||
m_index = m_deque->m_buffer.capacity() - 1;
|
||||
else
|
||||
--m_index;
|
||||
checkValidity();
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline T* DequeIteratorBase<T, inlineCapacity>::after() const
|
||||
{
|
||||
checkValidity();
|
||||
ASSERT(m_index != m_deque->m_end);
|
||||
return &m_deque->m_buffer.buffer()[m_index];
|
||||
}
|
||||
|
||||
template<typename T, size_t inlineCapacity>
|
||||
inline T* DequeIteratorBase<T, inlineCapacity>::before() const
|
||||
{
|
||||
checkValidity();
|
||||
ASSERT(m_index != m_deque->m_start);
|
||||
if (!m_index)
|
||||
return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1];
|
||||
return &m_deque->m_buffer.buffer()[m_index - 1];
|
||||
}
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::Deque;
|
||||
|
||||
#endif // WTF_Deque_h
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 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.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_DisallowCType_h
|
||||
#define WTF_DisallowCType_h
|
||||
|
||||
// The behavior of many of the functions in the <ctype.h> header is dependent
|
||||
// on the current locale. But almost all uses of these functions are for
|
||||
// locale-independent, ASCII-specific purposes. In WebKit code we use our own
|
||||
// ASCII-specific functions instead. This header makes sure we get a compile-time
|
||||
// error if we use one of the <ctype.h> functions by accident.
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#undef isalnum
|
||||
#undef isalpha
|
||||
#undef isascii
|
||||
#undef isblank
|
||||
#undef iscntrl
|
||||
#undef isdigit
|
||||
#undef isgraph
|
||||
#undef islower
|
||||
#undef isprint
|
||||
#undef ispunct
|
||||
#undef isspace
|
||||
#undef isupper
|
||||
#undef isxdigit
|
||||
#undef toascii
|
||||
#undef tolower
|
||||
#undef toupper
|
||||
|
||||
#define isalnum isalnum_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isalpha isalpha_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isascii isascii_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isblank isblank_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define iscntrl iscntrl_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isdigit isdigit_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isgraph isgraph_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define islower islower_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isprint isprint_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define ispunct ispunct_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isspace isspace_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isupper isupper_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define isxdigit isxdigit_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define toascii toascii_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define tolower tolower_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
#define toupper toupper_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h
|
||||
|
||||
#endif
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
||||
*/
|
||||
|
||||
#ifndef DoublyLinkedList_h
|
||||
#define DoublyLinkedList_h
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// This class allows nodes to share code without dictating data member layout.
|
||||
template<typename T> class DoublyLinkedListNode {
|
||||
public:
|
||||
DoublyLinkedListNode();
|
||||
|
||||
void setPrev(T*);
|
||||
void setNext(T*);
|
||||
|
||||
T* prev() const;
|
||||
T* next() const;
|
||||
};
|
||||
|
||||
template<typename T> inline DoublyLinkedListNode<T>::DoublyLinkedListNode()
|
||||
{
|
||||
setPrev(0);
|
||||
setNext(0);
|
||||
}
|
||||
|
||||
template<typename T> inline void DoublyLinkedListNode<T>::setPrev(T* prev)
|
||||
{
|
||||
static_cast<T*>(this)->m_prev = prev;
|
||||
}
|
||||
|
||||
template<typename T> inline void DoublyLinkedListNode<T>::setNext(T* next)
|
||||
{
|
||||
static_cast<T*>(this)->m_next = next;
|
||||
}
|
||||
|
||||
template<typename T> inline T* DoublyLinkedListNode<T>::prev() const
|
||||
{
|
||||
return static_cast<const T*>(this)->m_prev;
|
||||
}
|
||||
|
||||
template<typename T> inline T* DoublyLinkedListNode<T>::next() const
|
||||
{
|
||||
return static_cast<const T*>(this)->m_next;
|
||||
}
|
||||
|
||||
template<typename T> class DoublyLinkedList {
|
||||
public:
|
||||
DoublyLinkedList();
|
||||
|
||||
bool isEmpty() const;
|
||||
size_t size() const; // This is O(n).
|
||||
void clear();
|
||||
|
||||
T* head() const;
|
||||
T* removeHead();
|
||||
|
||||
void push(T*);
|
||||
void append(T*);
|
||||
void remove(T*);
|
||||
|
||||
private:
|
||||
T* m_head;
|
||||
T* m_tail;
|
||||
};
|
||||
|
||||
template<typename T> inline DoublyLinkedList<T>::DoublyLinkedList()
|
||||
: m_head(0)
|
||||
, m_tail(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T> inline bool DoublyLinkedList<T>::isEmpty() const
|
||||
{
|
||||
return !m_head;
|
||||
}
|
||||
|
||||
template<typename T> inline size_t DoublyLinkedList<T>::size() const
|
||||
{
|
||||
size_t size = 0;
|
||||
for (T* node = m_head; node; node = node->next())
|
||||
++size;
|
||||
return size;
|
||||
}
|
||||
|
||||
template<typename T> inline void DoublyLinkedList<T>::clear()
|
||||
{
|
||||
m_head = 0;
|
||||
m_tail = 0;
|
||||
}
|
||||
|
||||
template<typename T> inline T* DoublyLinkedList<T>::head() const
|
||||
{
|
||||
return m_head;
|
||||
}
|
||||
|
||||
template<typename T> inline void DoublyLinkedList<T>::push(T* node)
|
||||
{
|
||||
if (!m_head) {
|
||||
ASSERT(!m_tail);
|
||||
m_head = node;
|
||||
m_tail = node;
|
||||
node->setPrev(0);
|
||||
node->setNext(0);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(m_tail);
|
||||
m_head->setPrev(node);
|
||||
node->setNext(m_head);
|
||||
node->setPrev(0);
|
||||
m_head = node;
|
||||
}
|
||||
|
||||
template<typename T> inline void DoublyLinkedList<T>::append(T* node)
|
||||
{
|
||||
if (!m_tail) {
|
||||
ASSERT(!m_head);
|
||||
m_head = node;
|
||||
m_tail = node;
|
||||
node->setPrev(0);
|
||||
node->setNext(0);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(m_head);
|
||||
m_tail->setNext(node);
|
||||
node->setPrev(m_tail);
|
||||
node->setNext(0);
|
||||
m_tail = node;
|
||||
}
|
||||
|
||||
template<typename T> inline void DoublyLinkedList<T>::remove(T* node)
|
||||
{
|
||||
if (node->prev()) {
|
||||
ASSERT(node != m_head);
|
||||
node->prev()->setNext(node->next());
|
||||
} else {
|
||||
ASSERT(node == m_head);
|
||||
m_head = node->next();
|
||||
}
|
||||
|
||||
if (node->next()) {
|
||||
ASSERT(node != m_tail);
|
||||
node->next()->setPrev(node->prev());
|
||||
} else {
|
||||
ASSERT(node == m_tail);
|
||||
m_tail = node->prev();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline T* DoublyLinkedList<T>::removeHead()
|
||||
{
|
||||
T* node = head();
|
||||
if (node)
|
||||
remove(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::DoublyLinkedListNode;
|
||||
using WTF::DoublyLinkedList;
|
||||
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 THE COPYRIGHT
|
||||
* OWNER 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.
|
||||
*/
|
||||
|
||||
#ifndef WTF_DynamicAnnotations_h
|
||||
#define WTF_DynamicAnnotations_h
|
||||
|
||||
/* This file defines dynamic annotations for use with dynamic analysis
|
||||
* tool such as ThreadSanitizer, Valgrind, etc.
|
||||
*
|
||||
* Dynamic annotation is a source code annotation that affects
|
||||
* the generated code (that is, the annotation is not a comment).
|
||||
* Each such annotation is attached to a particular
|
||||
* instruction and/or to a particular object (address) in the program.
|
||||
*
|
||||
* By using dynamic annotations a developer can give more details to the dynamic
|
||||
* analysis tool to improve its precision.
|
||||
*
|
||||
* In C/C++ program the annotations are represented as C macros.
|
||||
* With the default build flags, these macros are empty, hence don't affect
|
||||
* performance of a compiled binary.
|
||||
* If dynamic annotations are enabled, they just call no-op functions.
|
||||
* The dynamic analysis tools can intercept these functions and replace them
|
||||
* with their own implementations.
|
||||
*
|
||||
* See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations for more information.
|
||||
*/
|
||||
|
||||
#if USE(DYNAMIC_ANNOTATIONS)
|
||||
/* Tell data race detector that we're not interested in reports on the given address range. */
|
||||
#define WTF_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) WTFAnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
|
||||
#define WTF_ANNOTATE_BENIGN_RACE(pointer, description) WTFAnnotateBenignRaceSized(__FILE__, __LINE__, pointer, sizeof(*(pointer)), description)
|
||||
|
||||
/* Annotations for user-defined synchronization mechanisms.
|
||||
* These annotations can be used to define happens-before arcs in user-defined
|
||||
* synchronization mechanisms: the race detector will infer an arc from
|
||||
* the former to the latter when they share the same argument pointer.
|
||||
*
|
||||
* The most common case requiring annotations is atomic reference counting:
|
||||
* bool deref() {
|
||||
* ANNOTATE_HAPPENS_BEFORE(&m_refCount);
|
||||
* if (!atomicDecrement(&m_refCount)) {
|
||||
* // m_refCount is now 0
|
||||
* ANNOTATE_HAPPENS_AFTER(&m_refCount);
|
||||
* // "return true; happens-after each atomicDecrement of m_refCount"
|
||||
* return true;
|
||||
* }
|
||||
* return false;
|
||||
* }
|
||||
*/
|
||||
#define WTF_ANNOTATE_HAPPENS_BEFORE(address) WTFAnnotateHappensBefore(__FILE__, __LINE__, address)
|
||||
#define WTF_ANNOTATE_HAPPENS_AFTER(address) WTFAnnotateHappensAfter(__FILE__, __LINE__, address)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Don't use these directly, use the above macros instead. */
|
||||
void WTFAnnotateBenignRaceSized(const char* file, int line, const volatile void* memory, long size, const char* description);
|
||||
void WTFAnnotateHappensBefore(const char* file, int line, const volatile void* address);
|
||||
void WTFAnnotateHappensAfter(const char* file, int line, const volatile void* address);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#else // USE(DYNAMIC_ANNOTATIONS)
|
||||
/* These macros are empty when dynamic annotations are not enabled so you can
|
||||
* use them without affecting the performance of release binaries. */
|
||||
#define WTF_ANNOTATE_BENIGN_RACE_SIZED(address, size, description)
|
||||
#define WTF_ANNOTATE_BENIGN_RACE(pointer, description)
|
||||
#define WTF_ANNOTATE_HAPPENS_BEFORE(address)
|
||||
#define WTF_ANNOTATE_HAPPENS_AFTER(address)
|
||||
#endif // USE(DYNAMIC_ANNOTATIONS)
|
||||
|
||||
#endif // WTF_DynamicAnnotations_h
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef Encoder_h
|
||||
#define Encoder_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace WTF {
|
||||
|
||||
class String;
|
||||
|
||||
class Encoder {
|
||||
protected:
|
||||
Encoder() { }
|
||||
virtual ~Encoder() { }
|
||||
|
||||
public:
|
||||
virtual void encodeBytes(const uint8_t*, size_t) = 0;
|
||||
|
||||
virtual void encodeBool(bool) = 0;
|
||||
virtual void encodeUInt32(uint32_t) = 0;
|
||||
virtual void encodeUInt64(uint64_t) = 0;
|
||||
virtual void encodeInt32(int32_t) = 0;
|
||||
virtual void encodeInt64(int64_t) = 0;
|
||||
virtual void encodeFloat(float) = 0;
|
||||
virtual void encodeDouble(double) = 0;
|
||||
virtual void encodeString(const String&) = 0;
|
||||
};
|
||||
|
||||
} // namespace WTF
|
||||
|
||||
using WTF::Encoder;
|
||||
|
||||
#endif // Encoder_h
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||||
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
|
||||
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef Error_h
|
||||
#define Error_h
|
||||
|
||||
#include "InternalFunction.h"
|
||||
#include "Interpreter.h"
|
||||
#include "JSObject.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace JSC {
|
||||
|
||||
class ExecState;
|
||||
class JSGlobalData;
|
||||
class JSGlobalObject;
|
||||
class JSObject;
|
||||
class SourceCode;
|
||||
class Structure;
|
||||
class UString;
|
||||
|
||||
// Methods to create a range of internal errors.
|
||||
JSObject* createError(JSGlobalObject*, const UString&);
|
||||
JSObject* createEvalError(JSGlobalObject*, const UString&);
|
||||
JSObject* createRangeError(JSGlobalObject*, const UString&);
|
||||
JSObject* createReferenceError(JSGlobalObject*, const UString&);
|
||||
JSObject* createSyntaxError(JSGlobalObject*, const UString&);
|
||||
JSObject* createTypeError(JSGlobalObject*, const UString&);
|
||||
JSObject* createURIError(JSGlobalObject*, const UString&);
|
||||
// ExecState wrappers.
|
||||
JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const UString&);
|
||||
JSObject* createEvalError(ExecState*, const UString&);
|
||||
JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const UString&);
|
||||
JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const UString&);
|
||||
JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const UString&);
|
||||
JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const UString&);
|
||||
JSObject* createURIError(ExecState*, const UString&);
|
||||
|
||||
// Methods to add
|
||||
bool hasErrorInfo(ExecState*, JSObject* error);
|
||||
JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&, const Vector<StackFrame>&);
|
||||
// ExecState wrappers.
|
||||
JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&, const Vector<StackFrame>&);
|
||||
|
||||
// Methods to throw Errors.
|
||||
JS_EXPORT_PRIVATE JSValue throwError(ExecState*, JSValue);
|
||||
JS_EXPORT_PRIVATE JSObject* throwError(ExecState*, JSObject*);
|
||||
|
||||
// Convenience wrappers, create an throw an exception with a default message.
|
||||
JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
|
||||
JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
|
||||
|
||||
// Convenience wrappers, wrap result as an EncodedJSValue.
|
||||
inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(throwError(exec, error)); }
|
||||
inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
|
||||
|
||||
class StrictModeTypeErrorFunction : public InternalFunction {
|
||||
private:
|
||||
StrictModeTypeErrorFunction(JSGlobalObject* globalObject, Structure* structure, const UString& message)
|
||||
: InternalFunction(globalObject, structure)
|
||||
, m_message(message)
|
||||
{
|
||||
}
|
||||
|
||||
static void destroy(JSCell*);
|
||||
|
||||
public:
|
||||
typedef InternalFunction Base;
|
||||
|
||||
static StrictModeTypeErrorFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const UString& message)
|
||||
{
|
||||
StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(*exec->heap())) StrictModeTypeErrorFunction(globalObject, structure, message);
|
||||
function->finishCreation(exec->globalData(), exec->globalData().propertyNames->emptyIdentifier);
|
||||
return function;
|
||||
}
|
||||
|
||||
static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
|
||||
{
|
||||
throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
static ConstructType getConstructData(JSCell*, ConstructData& constructData)
|
||||
{
|
||||
constructData.native.function = constructThrowTypeError;
|
||||
return ConstructTypeHost;
|
||||
}
|
||||
|
||||
static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
|
||||
{
|
||||
throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
static CallType getCallData(JSCell*, CallData& callData)
|
||||
{
|
||||
callData.native.function = callThrowTypeError;
|
||||
return CallTypeHost;
|
||||
}
|
||||
|
||||
static const ClassInfo s_info;
|
||||
|
||||
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
|
||||
{
|
||||
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
|
||||
}
|
||||
|
||||
private:
|
||||
UString m_message;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // Error_h
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user