michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef yarr_wtfbridge_h michael@0: #define yarr_wtfbridge_h michael@0: michael@0: /* michael@0: * WTF compatibility layer. This file provides various type and data michael@0: * definitions for use by Yarr. michael@0: */ michael@0: michael@0: #include michael@0: #include michael@0: #include "jscntxt.h" michael@0: #include "jsstr.h" michael@0: #include "vm/String.h" michael@0: #include "assembler/wtf/Platform.h" michael@0: #include "assembler/jit/ExecutableAllocator.h" michael@0: #include "yarr/CheckedArithmetic.h" michael@0: michael@0: namespace JSC { namespace Yarr { michael@0: michael@0: /* michael@0: * Basic type definitions. michael@0: */ michael@0: michael@0: typedef char LChar; michael@0: typedef jschar UChar; michael@0: typedef JSLinearString UString; michael@0: typedef JSLinearString String; michael@0: michael@0: michael@0: class Unicode { michael@0: public: michael@0: static UChar toUpper(UChar c) { return js::unicode::ToUpperCase(c); } michael@0: static UChar toLower(UChar c) { return js::unicode::ToLowerCase(c); } michael@0: }; michael@0: michael@0: /* michael@0: * Do-nothing smart pointer classes. These have a compatible interface michael@0: * with the smart pointers used by Yarr, but they don't actually do michael@0: * reference counting. michael@0: */ michael@0: template michael@0: class RefCounted { michael@0: }; michael@0: michael@0: template michael@0: class RefPtr { michael@0: T *ptr; michael@0: public: michael@0: RefPtr(T *p) { ptr = p; } michael@0: operator bool() const { return ptr != NULL; } michael@0: const T *operator ->() const { return ptr; } michael@0: T *get() { return ptr; } michael@0: }; michael@0: michael@0: template michael@0: class PassRefPtr { michael@0: T *ptr; michael@0: public: michael@0: PassRefPtr(T *p) { ptr = p; } michael@0: operator T*() { return ptr; } michael@0: }; michael@0: michael@0: template michael@0: class PassOwnPtr { michael@0: T *ptr; michael@0: public: michael@0: PassOwnPtr(T *p) { ptr = p; } michael@0: michael@0: T *get() { return ptr; } michael@0: }; michael@0: michael@0: template michael@0: class OwnPtr { michael@0: T *ptr; michael@0: public: michael@0: OwnPtr() : ptr(NULL) { } michael@0: OwnPtr(PassOwnPtr p) : ptr(p.get()) { } michael@0: michael@0: ~OwnPtr() { michael@0: js_delete(ptr); michael@0: } michael@0: michael@0: OwnPtr &operator=(PassOwnPtr p) { michael@0: ptr = p.get(); michael@0: return *this; michael@0: } michael@0: michael@0: T *operator ->() { return ptr; } michael@0: michael@0: T *get() { return ptr; } michael@0: michael@0: T *release() { michael@0: T *result = ptr; michael@0: ptr = NULL; michael@0: return result; michael@0: } michael@0: }; michael@0: michael@0: template michael@0: PassRefPtr adoptRef(T *p) { return PassRefPtr(p); } michael@0: michael@0: template michael@0: PassOwnPtr adoptPtr(T *p) { return PassOwnPtr(p); } michael@0: michael@0: // Dummy wrapper. michael@0: #define WTF_MAKE_FAST_ALLOCATED void make_fast_allocated_() michael@0: michael@0: template michael@0: class Ref { michael@0: T &val; michael@0: public: michael@0: Ref(T &val) : val(val) { } michael@0: operator T&() const { return val; } michael@0: }; michael@0: michael@0: /* michael@0: * Vector class for Yarr. This wraps js::Vector and provides all michael@0: * the API method signatures used by Yarr. michael@0: */ michael@0: template michael@0: class Vector { michael@0: public: michael@0: js::Vector impl; michael@0: public: michael@0: Vector() {} michael@0: michael@0: Vector(const Vector &v) { michael@0: append(v); michael@0: } michael@0: michael@0: size_t size() const { michael@0: return impl.length(); michael@0: } michael@0: michael@0: T &operator[](size_t i) { michael@0: return impl[i]; michael@0: } michael@0: michael@0: const T &operator[](size_t i) const { michael@0: return impl[i]; michael@0: } michael@0: michael@0: T &at(size_t i) { michael@0: return impl[i]; michael@0: } michael@0: michael@0: const T *begin() const { michael@0: return impl.begin(); michael@0: } michael@0: michael@0: T &last() { michael@0: return impl.back(); michael@0: } michael@0: michael@0: bool isEmpty() const { michael@0: return impl.empty(); michael@0: } michael@0: michael@0: template michael@0: void append(const U &u) { michael@0: if (!impl.append(static_cast(u))) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: } michael@0: michael@0: template michael@0: void append(const Vector &v) { michael@0: if (!impl.appendAll(v.impl)) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: } michael@0: michael@0: void insert(size_t i, const T& t) { michael@0: if (!impl.insert(&impl[i], t)) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: } michael@0: michael@0: void remove(size_t i) { michael@0: impl.erase(&impl[i]); michael@0: } michael@0: michael@0: void clear() { michael@0: return impl.clear(); michael@0: } michael@0: michael@0: void shrink(size_t newLength) { michael@0: JS_ASSERT(newLength <= impl.length()); michael@0: if (!impl.resize(newLength)) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: } michael@0: michael@0: void swap(Vector &other) { michael@0: impl.swap(other.impl); michael@0: } michael@0: michael@0: void deleteAllValues() { michael@0: for (T *p = impl.begin(); p != impl.end(); ++p) michael@0: js_delete(*p); michael@0: } michael@0: michael@0: bool reserve(size_t capacity) { michael@0: return impl.reserve(capacity); michael@0: } michael@0: }; michael@0: michael@0: template michael@0: class Vector > { michael@0: public: michael@0: js::Vector impl; michael@0: public: michael@0: Vector() {} michael@0: michael@0: size_t size() const { michael@0: return impl.length(); michael@0: } michael@0: michael@0: void append(T *t) { michael@0: if (!impl.append(t)) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: } michael@0: michael@0: PassOwnPtr operator[](size_t i) { michael@0: return PassOwnPtr(impl[i]); michael@0: } michael@0: michael@0: void clear() { michael@0: for (T **p = impl.begin(); p != impl.end(); ++p) michael@0: delete_(*p); michael@0: return impl.clear(); michael@0: } michael@0: michael@0: void reserve(size_t capacity) { michael@0: if (!impl.reserve(capacity)) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: } michael@0: }; michael@0: michael@0: template michael@0: inline void michael@0: deleteAllValues(Vector &v) { michael@0: v.deleteAllValues(); michael@0: } michael@0: michael@0: static inline void michael@0: dataLogF(const char *fmt, ...) michael@0: { michael@0: va_list ap; michael@0: va_start(ap, fmt); michael@0: vfprintf(stderr, fmt, ap); michael@0: va_end(ap); michael@0: } michael@0: michael@0: #if ENABLE_YARR_JIT michael@0: michael@0: /* michael@0: * Minimal JSGlobalData. This used by Yarr to get the allocator. michael@0: */ michael@0: class JSGlobalData { michael@0: public: michael@0: ExecutableAllocator *regexAllocator; michael@0: michael@0: JSGlobalData(ExecutableAllocator *regexAllocator) michael@0: : regexAllocator(regexAllocator) { } michael@0: }; michael@0: michael@0: #endif michael@0: michael@0: /* michael@0: * Do-nothing version of a macro used by WTF to avoid unused michael@0: * parameter warnings. michael@0: */ michael@0: #define UNUSED_PARAM(e) michael@0: michael@0: /* michael@0: * Like SpiderMonkey's allocation templates, but with more crashing. michael@0: */ michael@0: template michael@0: T *newOrCrash() michael@0: { michael@0: T *t = js_new(); michael@0: if (!t) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: return t; michael@0: } michael@0: michael@0: template michael@0: T *newOrCrash(P1 &&p1) michael@0: { michael@0: T *t = js_new(mozilla::Forward(p1)); michael@0: if (!t) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: return t; michael@0: } michael@0: michael@0: template michael@0: T *newOrCrash(P1 &&p1, P2 &&p2) michael@0: { michael@0: T *t = js_new(mozilla::Forward(p1), mozilla::Forward(p2)); michael@0: if (!t) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: return t; michael@0: } michael@0: michael@0: template michael@0: T *newOrCrash(P1 &&p1, P2 &&p2, P3 &&p3) michael@0: { michael@0: T *t = js_new(mozilla::Forward(p1), mozilla::Forward(p2), mozilla::Forward(p3)); michael@0: if (!t) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: return t; michael@0: } michael@0: michael@0: template michael@0: T *newOrCrash(P1 &&p1, P2 &&p2, P3 &&p3, P4 &&p4) michael@0: { michael@0: T *t = js_new(mozilla::Forward(p1), michael@0: mozilla::Forward(p2), michael@0: mozilla::Forward(p3), michael@0: mozilla::Forward(p4)); michael@0: if (!t) michael@0: js::CrashAtUnhandlableOOM("Yarr"); michael@0: return t; michael@0: } michael@0: michael@0: } /* namespace Yarr */ michael@0: michael@0: /* michael@0: * Replacements for std:: functions used in Yarr. We put them in michael@0: * namespace JSC::std so that they can still be called as std::X michael@0: * in Yarr. michael@0: */ michael@0: namespace std { michael@0: michael@0: /* michael@0: * windows.h defines a 'min' macro that would mangle the function michael@0: * name. michael@0: */ michael@0: #if WTF_COMPILER_MSVC michael@0: # undef min michael@0: # undef max michael@0: #endif michael@0: michael@0: #define NO_RETURN_DUE_TO_ASSERT michael@0: michael@0: template michael@0: inline T michael@0: min(T t1, T t2) michael@0: { michael@0: return js::Min(t1, t2); michael@0: } michael@0: michael@0: template michael@0: inline T michael@0: max(T t1, T t2) michael@0: { michael@0: return js::Max(t1, t2); michael@0: } michael@0: michael@0: template michael@0: inline void michael@0: swap(T &t1, T &t2) michael@0: { michael@0: T tmp = t1; michael@0: t1 = t2; michael@0: t2 = tmp; michael@0: } michael@0: } /* namespace std */ michael@0: michael@0: } /* namespace JSC */ michael@0: michael@0: namespace WTF { michael@0: michael@0: /* michael@0: * Sentinel value used in Yarr. michael@0: */ michael@0: const size_t notFound = size_t(-1); michael@0: michael@0: } michael@0: michael@0: #define JS_EXPORT_PRIVATE michael@0: michael@0: #endif /* yarr_wtfbridge_h */