From 6143c512fa8e105ff9aafb3f5aed958afdfe3ca8 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 3 Oct 2013 15:41:22 -0700 Subject: [PATCH 001/144] Add AppCode project files to ignorelist --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 321ce706a4..ed3c0b5afa 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,9 @@ build/ xcuserdata/ DerivedData/ +# Ignore files built by AppCode +.idea/ + # Ignore files built by bada .Simulator-Debug/ .Target-Debug/ From a2c254694202cbe51a0ece8bd610aede39501750 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 4 Oct 2013 10:07:39 -0700 Subject: [PATCH 002/144] Implement MouseWheel Event, also fix a typo in EventListener interface --- .../project.pbxproj.REMOVED.git-id | 2 +- .../event_dispatcher/CCEventDispatcher.cpp | 4 +- cocos2dx/event_dispatcher/CCEventListener.cpp | 2 +- cocos2dx/event_dispatcher/CCEventListener.h | 2 +- .../CCEventListenerAcceleration.cpp | 2 +- .../CCEventListenerAcceleration.h | 2 +- .../CCEventListenerCustom.cpp | 4 +- .../event_dispatcher/CCEventListenerCustom.h | 2 +- .../CCEventListenerKeyboard.cpp | 2 +- .../CCEventListenerKeyboard.h | 2 +- .../event_dispatcher/CCEventListenerMouse.cpp | 100 ++++++++++++++++++ .../event_dispatcher/CCEventListenerMouse.h | 57 ++++++++++ .../event_dispatcher/CCEventListenerTouch.cpp | 2 +- .../event_dispatcher/CCEventListenerTouch.h | 2 +- cocos2dx/event_dispatcher/CCEventMouse.cpp | 32 ++++++ cocos2dx/event_dispatcher/CCEventMouse.h | 75 +++++++++++++ cocos2dx/include/cocos2d.h | 2 + cocos2dx/platform/mac/CCEGLView.mm | 12 ++- samples/Cpp/TestCpp/Classes/controller.cpp | 28 +++++ samples/Cpp/TestCpp/Classes/controller.h | 2 + 20 files changed, 321 insertions(+), 15 deletions(-) create mode 100644 cocos2dx/event_dispatcher/CCEventListenerMouse.cpp create mode 100644 cocos2dx/event_dispatcher/CCEventListenerMouse.h create mode 100644 cocos2dx/event_dispatcher/CCEventMouse.cpp create mode 100644 cocos2dx/event_dispatcher/CCEventMouse.h diff --git a/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 48555d6a5d..3e16069aaa 100644 --- a/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3959af89b6bbc8fb982769d22d2591991107d6e5 \ No newline at end of file +a62d231c7569e0d3691fffaeed9f8ed41f11070d \ No newline at end of file diff --git a/cocos2dx/event_dispatcher/CCEventDispatcher.cpp b/cocos2dx/event_dispatcher/CCEventDispatcher.cpp index 468db2f39b..c8901f2b8a 100644 --- a/cocos2dx/event_dispatcher/CCEventDispatcher.cpp +++ b/cocos2dx/event_dispatcher/CCEventDispatcher.cpp @@ -125,7 +125,7 @@ void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* list CCASSERT(listener && node, "Invalid parameters."); CCASSERT(!listener->_isRegistered, "The listener has been registered."); - if (!listener->checkAvaiable()) + if (!listener->checkAvailable()) return; auto item = new EventListenerItem(); @@ -147,7 +147,7 @@ void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, CCASSERT(!listener->_isRegistered, "The listener has been registered."); CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority."); - if (!listener->checkAvaiable()) + if (!listener->checkAvailable()) return; auto item = new EventListenerItem(); diff --git a/cocos2dx/event_dispatcher/CCEventListener.cpp b/cocos2dx/event_dispatcher/CCEventListener.cpp index ce3c787883..451be9a8c8 100644 --- a/cocos2dx/event_dispatcher/CCEventListener.cpp +++ b/cocos2dx/event_dispatcher/CCEventListener.cpp @@ -44,7 +44,7 @@ bool EventListener::init(const std::string& t, std::function callb return true; } -bool EventListener::checkAvaiable() +bool EventListener::checkAvailable() { return (_onEvent != nullptr); } diff --git a/cocos2dx/event_dispatcher/CCEventListener.h b/cocos2dx/event_dispatcher/CCEventListener.h index 156d644f17..6ef486d8e2 100644 --- a/cocos2dx/event_dispatcher/CCEventListener.h +++ b/cocos2dx/event_dispatcher/CCEventListener.h @@ -54,7 +54,7 @@ public: virtual ~EventListener(); /** Checks whether the listener is available. */ - virtual bool checkAvaiable() = 0; + virtual bool checkAvailable() = 0; /** Clones the listener, its subclasses have to override this method. */ virtual EventListener* clone() = 0; diff --git a/cocos2dx/event_dispatcher/CCEventListenerAcceleration.cpp b/cocos2dx/event_dispatcher/CCEventListenerAcceleration.cpp index e7e1f6055b..d8b01fc4ce 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerAcceleration.cpp +++ b/cocos2dx/event_dispatcher/CCEventListenerAcceleration.cpp @@ -84,7 +84,7 @@ EventListenerAcceleration* EventListenerAcceleration::clone() return ret; } -bool EventListenerAcceleration::checkAvaiable() +bool EventListenerAcceleration::checkAvailable() { CCASSERT(onAccelerationEvent, ""); diff --git a/cocos2dx/event_dispatcher/CCEventListenerAcceleration.h b/cocos2dx/event_dispatcher/CCEventListenerAcceleration.h index 1fb9536be7..2905df9486 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerAcceleration.h +++ b/cocos2dx/event_dispatcher/CCEventListenerAcceleration.h @@ -38,7 +38,7 @@ public: /// Overrides virtual EventListenerAcceleration* clone() override; - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; private: EventListenerAcceleration(); diff --git a/cocos2dx/event_dispatcher/CCEventListenerCustom.cpp b/cocos2dx/event_dispatcher/CCEventListenerCustom.cpp index 7be79b9dcb..abe4153198 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerCustom.cpp +++ b/cocos2dx/event_dispatcher/CCEventListenerCustom.cpp @@ -80,10 +80,10 @@ EventListenerCustom* EventListenerCustom::clone() return ret; } -bool EventListenerCustom::checkAvaiable() +bool EventListenerCustom::checkAvailable() { bool ret = false; - if (EventListener::checkAvaiable() && _onCustomEvent != nullptr) + if (EventListener::checkAvailable() && _onCustomEvent != nullptr) { ret = true; } diff --git a/cocos2dx/event_dispatcher/CCEventListenerCustom.h b/cocos2dx/event_dispatcher/CCEventListenerCustom.h index 190ed63f95..a823d4a4ba 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerCustom.h +++ b/cocos2dx/event_dispatcher/CCEventListenerCustom.h @@ -59,7 +59,7 @@ public: static EventListenerCustom* create(const std::string& eventName, std::function callback); /// Overrides - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; virtual EventListenerCustom* clone() override; protected: diff --git a/cocos2dx/event_dispatcher/CCEventListenerKeyboard.cpp b/cocos2dx/event_dispatcher/CCEventListenerKeyboard.cpp index 80709f8cef..a6e3b617ae 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerKeyboard.cpp +++ b/cocos2dx/event_dispatcher/CCEventListenerKeyboard.cpp @@ -29,7 +29,7 @@ NS_CC_BEGIN -bool EventListenerKeyboard::checkAvaiable() +bool EventListenerKeyboard::checkAvailable() { CCASSERT(onKeyPressed && onKeyReleased, ""); diff --git a/cocos2dx/event_dispatcher/CCEventListenerKeyboard.h b/cocos2dx/event_dispatcher/CCEventListenerKeyboard.h index f7b4c288d9..dd223da533 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerKeyboard.h +++ b/cocos2dx/event_dispatcher/CCEventListenerKeyboard.h @@ -40,7 +40,7 @@ public: /// Overrides virtual EventListenerKeyboard* clone() override; - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; std::function onKeyPressed; std::function onKeyReleased; diff --git a/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp b/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp new file mode 100644 index 0000000000..d747a720b4 --- /dev/null +++ b/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + ****************************************************************************/ + +#include "CCEventListenerMouse.h" + +NS_CC_BEGIN + +bool EventListenerMouse::checkAvailable() +{ + return true; +} + +EventListenerMouse* EventListenerMouse::create() +{ + auto ret = new EventListenerMouse(); + if (ret && ret->init()) + { + ret->autorelease(); + } + else + { + CC_SAFE_DELETE(ret); + } + return ret; +} + +EventListenerMouse* EventListenerMouse::clone() +{ + auto ret = new EventListenerMouse(); + if (ret && ret->init()) + { + ret->autorelease(); + ret->onMouseUp = onMouseUp; + ret->onMouseDown = onMouseDown; + ret->onMouseMove = onMouseMove; + ret->onMouseScroll = onMouseScroll; + } + else + { + CC_SAFE_DELETE(ret); + } + return ret; +} + +EventListenerMouse::EventListenerMouse() +: onMouseUp(nullptr) +, onMouseDown(nullptr) +, onMouseMove(nullptr) +, onMouseScroll(nullptr) +{ +} + +bool EventListenerMouse::init() +{ + auto listener = [this](Event* event){ + auto mouseEvent = static_cast(event); + switch (mouseEvent->_mouseEventType) + { + case EventMouse::MouseEventType::MOUSE_SCROLL: + { + if(onMouseScroll != nullptr) + onMouseScroll(event); + break; + } + default: + break; + } + }; + + if (EventListener::init(EventMouse::EVENT_TYPE, listener)) + { + return true; + } + + return false; +} + +NS_CC_END \ No newline at end of file diff --git a/cocos2dx/event_dispatcher/CCEventListenerMouse.h b/cocos2dx/event_dispatcher/CCEventListenerMouse.h new file mode 100644 index 0000000000..360d46128a --- /dev/null +++ b/cocos2dx/event_dispatcher/CCEventListenerMouse.h @@ -0,0 +1,57 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + ****************************************************************************/ + +#include "CCEventListener.h" +#include "CCEventMouse.h" + +#ifndef __cocos2d_libs__CCMouseEventListener__ +#define __cocos2d_libs__CCMouseEventListener__ + +NS_CC_BEGIN + +class Event; + +class EventListenerMouse : public EventListener +{ +public: + static EventListenerMouse* create(); + + /// Overrides + virtual EventListenerMouse* clone() override; + virtual bool checkAvailable() override; + + std::function onMouseDown; + std::function onMouseUp; + std::function onMouseMove; + std::function onMouseScroll; + +private: + EventListenerMouse(); + bool init(); +}; + +NS_CC_END + +#endif /* defined(__cocos2d_libs__CCMouseEventListener__) */ diff --git a/cocos2dx/event_dispatcher/CCEventListenerTouch.cpp b/cocos2dx/event_dispatcher/CCEventListenerTouch.cpp index ec418c2949..80e9f0b011 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerTouch.cpp +++ b/cocos2dx/event_dispatcher/CCEventListenerTouch.cpp @@ -80,7 +80,7 @@ EventListenerTouch* EventListenerTouch::create(Touch::DispatchMode mode) return ret; } -bool EventListenerTouch::checkAvaiable() +bool EventListenerTouch::checkAvailable() { if (_dispatchMode == Touch::DispatchMode::ALL_AT_ONCE) { diff --git a/cocos2dx/event_dispatcher/CCEventListenerTouch.h b/cocos2dx/event_dispatcher/CCEventListenerTouch.h index 62cd4c3e6d..bfe04d9785 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerTouch.h +++ b/cocos2dx/event_dispatcher/CCEventListenerTouch.h @@ -40,7 +40,7 @@ public: /// Overrides virtual EventListenerTouch* clone() override; - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; virtual ~EventListenerTouch(); diff --git a/cocos2dx/event_dispatcher/CCEventMouse.cpp b/cocos2dx/event_dispatcher/CCEventMouse.cpp new file mode 100644 index 0000000000..abb1ce5518 --- /dev/null +++ b/cocos2dx/event_dispatcher/CCEventMouse.cpp @@ -0,0 +1,32 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + ****************************************************************************/ + +#include "CCEventMouse.h" + +NS_CC_BEGIN + +const char* EventMouse::EVENT_TYPE = "MouseEvent"; + +NS_CC_END \ No newline at end of file diff --git a/cocos2dx/event_dispatcher/CCEventMouse.h b/cocos2dx/event_dispatcher/CCEventMouse.h new file mode 100644 index 0000000000..28df2b409a --- /dev/null +++ b/cocos2dx/event_dispatcher/CCEventMouse.h @@ -0,0 +1,75 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + ****************************************************************************/ + +#ifndef __cocos2d_libs__CCMouseEvent__ +#define __cocos2d_libs__CCMouseEvent__ + +#include "CCEvent.h" + +NS_CC_BEGIN + +class EventMouse : public Event +{ +public: + /** + * Different types of MouseEvent + */ + enum class MouseEventType + { + MOUSE_NONE, +// todo: support other mouse events +// MOUSE_DOWN, +// MOUSE_UP, +// MOUSE_MOVE, + MOUSE_SCROLL, + }; + + static const char* EVENT_TYPE; + + EventMouse(MouseEventType mouseEventCode) + : Event(EVENT_TYPE) + , _mouseEventType(mouseEventCode) + {}; + + /** Set mouse scroll data */ + inline void setScrollData(float scrollX, float scrollY) { _scrollX = scrollX; _scrollY = scrollY; }; + + inline float getScrollX() { return _scrollX; }; + inline float getScrollY() { return _scrollY; }; + +private: + MouseEventType _mouseEventType; + int _mouseButton; + bool _isPressed; +// Point _position; + float _scrollX; + float _scrollY; + + friend class EventListenerMouse; +}; + +NS_CC_END + +#endif /* defined(__cocos2d_libs__CCMouseEvent__) */ diff --git a/cocos2dx/include/cocos2d.h b/cocos2dx/include/cocos2d.h index 2280067cfc..94301dcf68 100644 --- a/cocos2dx/include/cocos2d.h +++ b/cocos2dx/include/cocos2d.h @@ -269,6 +269,8 @@ THE SOFTWARE. #include "event_dispatcher/CCEventListenerAcceleration.h" #include "event_dispatcher/CCEventCustom.h" #include "event_dispatcher/CCEventListenerCustom.h" +#include "event_dispatcher/CCEventListenerMouse.h" +#include "event_dispatcher/CCEventMouse.h" // root #include "CCCamera.h" diff --git a/cocos2dx/platform/mac/CCEGLView.mm b/cocos2dx/platform/mac/CCEGLView.mm index 3c371b2457..7248877a70 100644 --- a/cocos2dx/platform/mac/CCEGLView.mm +++ b/cocos2dx/platform/mac/CCEGLView.mm @@ -28,6 +28,7 @@ #include "event_dispatcher/CCTouch.h" #include "event_dispatcher/CCEventDispatcher.h" #include "event_dispatcher/CCEventKeyboard.h" +#include "event_dispatcher/CCEventMouse.h" #include "CCIMEDispatcher.h" NS_CC_BEGIN @@ -175,6 +176,7 @@ public: static void OnGLFWError(int errorID, const char* errorDesc); static void OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify); static void OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y); + static void OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y); static void OnGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); static void OnGLFWCharCallback(GLFWwindow* window, unsigned int character); static void OnGLFWWindowPosCallback(GLFWwindow* windows, int x, int y); @@ -236,6 +238,13 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, } } +void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) +{ + EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); + event.setScrollData((float)x, (float)y); + EventDispatcher::getInstance()->dispatchEvent(&event); +} + void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); @@ -300,10 +309,11 @@ bool EGLView::init(const char *viewName, float width, float height, float frameZ glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack); glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack); + glfwSetScrollCallback(_mainWindow, EGLViewEventHandler::OnGLFWMouseScrollCallback); glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback); glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback); glfwSetWindowPosCallback(_mainWindow, EGLViewEventHandler::OnGLFWWindowPosCallback); - + // check OpenGL version at first const GLubyte* glVersion = glGetString(GL_VERSION); diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index f78fb2c9af..2f4059469a 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -132,6 +132,10 @@ TestController::TestController() listener->onTouchMoved = CC_CALLBACK_2(TestController::onTouchMoved, this); EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + + auto mouseListener = EventListenerMouse::create(); + mouseListener->onMouseScroll = CC_CALLBACK_1(TestController::onMouseScroll, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(mouseListener, this); } TestController::~TestController() @@ -195,3 +199,27 @@ void TestController::onTouchMoved(Touch* touch, Event *event) _beginPos = touchLocation; s_tCurPos = nextPos; } + +void TestController::onMouseScroll(Event *event) +{ + auto mouseEvent = static_cast(event); + float nMoveY = -mouseEvent->getScrollY(); + + auto curPos = _itemMenu->getPosition(); + auto nextPos = Point(curPos.x, curPos.y + nMoveY); + + if (nextPos.y < 0.0f) + { + _itemMenu->setPosition(Point::ZERO); + return; + } + + if (nextPos.y > ((g_testCount + 1)* LINE_SPACE - VisibleRect::getVisibleRect().size.height)) + { + _itemMenu->setPosition(Point(0, ((g_testCount + 1)* LINE_SPACE - VisibleRect::getVisibleRect().size.height))); + return; + } + + _itemMenu->setPosition(nextPos); + s_tCurPos = nextPos; +} \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/controller.h b/samples/Cpp/TestCpp/Classes/controller.h index 50126dbceb..19947f20d5 100644 --- a/samples/Cpp/TestCpp/Classes/controller.h +++ b/samples/Cpp/TestCpp/Classes/controller.h @@ -17,6 +17,8 @@ public: bool onTouchBegan(Touch* touches, Event *event); void onTouchMoved(Touch* touches, Event *event); + void onMouseScroll(Event *event); + private: Point _beginPos; Menu* _itemMenu; From e19957136e12a9dd90479e36ea5a896f44136d21 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 4 Oct 2013 16:14:52 -0700 Subject: [PATCH 003/144] Implement Mouse_up Mouse_down and Mouse_Move --- .../event_dispatcher/CCEventListenerMouse.cpp | 14 +++++++++++-- cocos2dx/event_dispatcher/CCEventMouse.h | 20 ++++++++++++------- cocos2dx/platform/mac/CCEGLView.mm | 14 +++++++++++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp b/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp index d747a720b4..24f8a167ab 100644 --- a/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp +++ b/cocos2dx/event_dispatcher/CCEventListenerMouse.cpp @@ -78,12 +78,22 @@ bool EventListenerMouse::init() auto mouseEvent = static_cast(event); switch (mouseEvent->_mouseEventType) { + case EventMouse::MouseEventType::MOUSE_DOWN: + if(onMouseDown != nullptr) + onMouseDown(event); + break; + case EventMouse::MouseEventType::MOUSE_UP: + if(onMouseUp != nullptr) + onMouseUp(event); + break; + case EventMouse::MouseEventType::MOUSE_MOVE: + if(onMouseMove != nullptr) + onMouseMove(event); + break; case EventMouse::MouseEventType::MOUSE_SCROLL: - { if(onMouseScroll != nullptr) onMouseScroll(event); break; - } default: break; } diff --git a/cocos2dx/event_dispatcher/CCEventMouse.h b/cocos2dx/event_dispatcher/CCEventMouse.h index 28df2b409a..b44d6d4aca 100644 --- a/cocos2dx/event_dispatcher/CCEventMouse.h +++ b/cocos2dx/event_dispatcher/CCEventMouse.h @@ -39,10 +39,9 @@ public: enum class MouseEventType { MOUSE_NONE, -// todo: support other mouse events -// MOUSE_DOWN, -// MOUSE_UP, -// MOUSE_MOVE, + MOUSE_DOWN, + MOUSE_UP, + MOUSE_MOVE, MOUSE_SCROLL, }; @@ -51,19 +50,26 @@ public: EventMouse(MouseEventType mouseEventCode) : Event(EVENT_TYPE) , _mouseEventType(mouseEventCode) + , _x(0.0f) + , _y(0.0f) + , _scrollX(0.0f) + , _scrollY(0.0f) {}; /** Set mouse scroll data */ inline void setScrollData(float scrollX, float scrollY) { _scrollX = scrollX; _scrollY = scrollY; }; - inline float getScrollX() { return _scrollX; }; inline float getScrollY() { return _scrollY; }; + inline void setCursorPosition(float x, float y) { _x = x; _y = y; }; + inline float getCursorX() { return _x; }; + inline float getCursorY() { return _y; }; + private: MouseEventType _mouseEventType; int _mouseButton; - bool _isPressed; -// Point _position; + float _x; + float _y; float _scrollX; float _scrollY; diff --git a/cocos2dx/platform/mac/CCEGLView.mm b/cocos2dx/platform/mac/CCEGLView.mm index 7248877a70..83d020cef1 100644 --- a/cocos2dx/platform/mac/CCEGLView.mm +++ b/cocos2dx/platform/mac/CCEGLView.mm @@ -195,6 +195,7 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in { EGLView* eglView = EGLView::getInstance(); if(nullptr == eglView) return; + if(GLFW_MOUSE_BUTTON_LEFT == button) { if(GLFW_PRESS == action) @@ -204,6 +205,10 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in { int id = 0; eglView->handleTouchesBegin(1, &id, &s_mouseX, &s_mouseY); + + EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); + event.setCursorPosition(s_mouseX, s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); } } else if(GLFW_RELEASE == action) @@ -213,6 +218,10 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in { int id = 0; eglView->handleTouchesEnd(1, &id, &s_mouseX, &s_mouseY); + + EventMouse event(EventMouse::MouseEventType::MOUSE_UP); + event.setCursorPosition(s_mouseX, s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); } } } @@ -236,12 +245,17 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, eglView->handleTouchesMove(1, &id, &s_mouseX, &s_mouseY); } } + + EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE); + event.setCursorPosition(s_mouseX, s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) { EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); event.setScrollData((float)x, (float)y); + event.setCursorPosition(s_mouseX, s_mouseY); EventDispatcher::getInstance()->dispatchEvent(&event); } From 09c0e23b5d98e5a89d894943db0a8a8c93e05087 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 11 Oct 2013 14:35:38 -0700 Subject: [PATCH 004/144] Mouse working on mac --- cocos2dx/event_dispatcher/CCEventMouse.h | 12 +++ cocos2dx/platform/mac/CCEGLView.mm | 36 +++++--- .../TestCpp/Classes/InputTest/MouseTest.cpp | 84 +++++++++++++++++++ .../Cpp/TestCpp/Classes/InputTest/MouseTest.h | 30 +++++++ samples/Cpp/TestCpp/Classes/controller.cpp | 1 + samples/Cpp/TestCpp/Classes/tests.h | 1 + .../project.pbxproj.REMOVED.git-id | 2 +- 7 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 samples/Cpp/TestCpp/Classes/InputTest/MouseTest.cpp create mode 100644 samples/Cpp/TestCpp/Classes/InputTest/MouseTest.h diff --git a/cocos2dx/event_dispatcher/CCEventMouse.h b/cocos2dx/event_dispatcher/CCEventMouse.h index b44d6d4aca..1a9ea971e0 100644 --- a/cocos2dx/event_dispatcher/CCEventMouse.h +++ b/cocos2dx/event_dispatcher/CCEventMouse.h @@ -28,6 +28,15 @@ #include "CCEvent.h" +#define MOUSE_BUTTON_LEFT 0 +#define MOUSE_BUTTON_RIGHT 1 +#define MOUSE_BUTTON_MIDDLE 2 +#define MOUSE_BUTTON_4 3 +#define MOUSE_BUTTON_5 4 +#define MOUSE_BUTTON_6 5 +#define MOUSE_BUTTON_7 6 +#define MOUSE_BUTTON_8 7 + NS_CC_BEGIN class EventMouse : public Event @@ -50,6 +59,7 @@ public: EventMouse(MouseEventType mouseEventCode) : Event(EVENT_TYPE) , _mouseEventType(mouseEventCode) + , _mouseButton(0) , _x(0.0f) , _y(0.0f) , _scrollX(0.0f) @@ -62,6 +72,8 @@ public: inline float getScrollY() { return _scrollY; }; inline void setCursorPosition(float x, float y) { _x = x; _y = y; }; + inline void setMouseButton(int button) { _mouseButton = button; }; + inline int getMouseButton() { return _mouseButton; }; inline float getCursorX() { return _x; }; inline float getCursorY() { return _y; }; diff --git a/cocos2dx/platform/mac/CCEGLView.mm b/cocos2dx/platform/mac/CCEGLView.mm index 83d020cef1..b431a18c41 100644 --- a/cocos2dx/platform/mac/CCEGLView.mm +++ b/cocos2dx/platform/mac/CCEGLView.mm @@ -205,10 +205,6 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in { int id = 0; eglView->handleTouchesBegin(1, &id, &s_mouseX, &s_mouseY); - - EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); - event.setCursorPosition(s_mouseX, s_mouseY); - EventDispatcher::getInstance()->dispatchEvent(&event); } } else if(GLFW_RELEASE == action) @@ -218,22 +214,33 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in { int id = 0; eglView->handleTouchesEnd(1, &id, &s_mouseX, &s_mouseY); - - EventMouse event(EventMouse::MouseEventType::MOUSE_UP); - event.setCursorPosition(s_mouseX, s_mouseY); - EventDispatcher::getInstance()->dispatchEvent(&event); } } } + + if(GLFW_PRESS == action) + { + EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + event.setMouseButton(button); + EventDispatcher::getInstance()->dispatchEvent(&event); + } + else if(GLFW_RELEASE == action) + { + EventMouse event(EventMouse::MouseEventType::MOUSE_UP); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + event.setMouseButton(button); + EventDispatcher::getInstance()->dispatchEvent(&event); + } } void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) { - s_mouseX = (float)x; - s_mouseY = (float)y; EGLView* eglView = EGLView::getInstance(); if(nullptr == eglView) return; - + s_mouseX = (float)x; + s_mouseY = (float)y; + s_mouseX /= eglView->getFrameZoomFactor(); s_mouseY /= eglView->getFrameZoomFactor(); @@ -247,15 +254,18 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, } EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE); - event.setCursorPosition(s_mouseX, s_mouseY); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); EventDispatcher::getInstance()->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) { + EGLView* eglView = EGLView::getInstance(); + if(nullptr == eglView) return; + EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); event.setScrollData((float)x, (float)y); - event.setCursorPosition(s_mouseX, s_mouseY); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); EventDispatcher::getInstance()->dispatchEvent(&event); } diff --git a/samples/Cpp/TestCpp/Classes/InputTest/MouseTest.cpp b/samples/Cpp/TestCpp/Classes/InputTest/MouseTest.cpp new file mode 100644 index 0000000000..dd3dfaf1b1 --- /dev/null +++ b/samples/Cpp/TestCpp/Classes/InputTest/MouseTest.cpp @@ -0,0 +1,84 @@ +#include "MouseTest.h" + +MouseTest::MouseTest() +{ + auto s = Director::getInstance()->getWinSize(); + auto title = LabelTTF::create("Mouse Test", "Arial", 28); + addChild(title, 0); + title->setPosition( Point(s.width/2, s.height-50) ); + + //Create a label to display the mouse action + _labelAction = LabelTTF::create("Click mouse button and see this change", "Arial", 22); + _labelAction->setPosition(Point(s.width/2, s.height*2/3)); + addChild(_labelAction, 0); + + //Create a label to display the mouse position + _labelPosition = LabelTTF::create("Mouse not supported on this device", "Arial", 22); + _labelPosition->setPosition(Point(s.width/2, s.height/3)); + addChild(_labelPosition); + + + _mouseListener = EventListenerMouse::create(); + _mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this); + _mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this); + _mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this); + _mouseListener->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(_mouseListener, this); + + _labelAction->retain(); + _labelPosition->retain(); + + this->setTouchEnabled(true); +} + +MouseTest::~MouseTest() +{ + EventDispatcher::getInstance()->removeEventListener(_mouseListener); + + _labelAction->release(); + _labelPosition->release(); +} + +template string tostr(const T& t) { ostringstream os; os<getMouseButton()); + _labelAction->setString(str.c_str()); +} + +void MouseTest::onMouseUp(Event *event) +{ + EventMouse* e = (EventMouse*)event; + string str = "Mouse Up detected, Key: "; + str += tostr(e->getMouseButton()); + _labelAction->setString(str.c_str()); +} + +void MouseTest::onMouseMove(Event *event) +{ + EventMouse* e = (EventMouse*)event; + string str = "MousePosition X:"; + str = str + tostr(e->getCursorX()) + " Y:" + tostr(e->getCursorY()); + _labelPosition->setString(str.c_str()); +} + +void MouseTest::onMouseScroll(Event *event) +{ + EventMouse* e = (EventMouse*)event; + string str = "Mouse Scroll detected, X: "; + str = str + tostr(e->getScrollX()) + " Y: " + tostr(e->getScrollY()); + _labelAction->setString(str.c_str()); +} + +void MouseTestScene::runThisTest() +{ + auto layer = new MouseTest(); + addChild(layer); + + Director::getInstance()->replaceScene(this); + layer->release(); +} \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/InputTest/MouseTest.h b/samples/Cpp/TestCpp/Classes/InputTest/MouseTest.h new file mode 100644 index 0000000000..8be1bd270d --- /dev/null +++ b/samples/Cpp/TestCpp/Classes/InputTest/MouseTest.h @@ -0,0 +1,30 @@ +#ifndef __MOUSE_TEST_H_ +#define __MOUSE_TEST_H_ + +#include "cocos2d.h" +#include "../testBasic.h" + +class MouseTest : public Layer +{ +public: + MouseTest(); + ~MouseTest(); + + void onMouseDown(Event* event); + void onMouseUp(Event* event); + void onMouseMove(Event* event); + void onMouseScroll(Event* event); + +private: + LabelTTF* _labelAction; + LabelTTF* _labelPosition; + EventListenerMouse* _mouseListener; +}; + +class MouseTestScene : public TestScene +{ +public: + virtual void runThisTest(); +}; + +#endif diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index 2f4059469a..587758fe02 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -50,6 +50,7 @@ struct { { "FontTest", []() { return new FontTestScene(); } }, { "IntervalTest", [](){return new IntervalTestScene(); } }, { "KeyboardTest", []() { return new KeyboardTestScene(); } }, + { "MouseTest", []() { return new MouseTestScene(); } }, #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA) { "KeypadTest", []() { return new KeypadTestScene(); } }, #endif diff --git a/samples/Cpp/TestCpp/Classes/tests.h b/samples/Cpp/TestCpp/Classes/tests.h index b119f69de1..d613fe542e 100644 --- a/samples/Cpp/TestCpp/Classes/tests.h +++ b/samples/Cpp/TestCpp/Classes/tests.h @@ -32,6 +32,7 @@ #include "AccelerometerTest/AccelerometerTest.h" #include "KeypadTest/KeypadTest.h" #include "KeyboardTest/KeyboardTest.h" +#include "InputTest/MouseTest.h" #include "PerformanceTest/PerformanceTest.h" #include "ZwoptexTest/ZwoptexTest.h" #include "CocosDenshionTest/CocosDenshionTest.h" diff --git a/samples/samples.xcodeproj/project.pbxproj.REMOVED.git-id b/samples/samples.xcodeproj/project.pbxproj.REMOVED.git-id index efbf8806ae..06123eec12 100644 --- a/samples/samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/samples/samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b759f56a07f242b20e9c96f2a6cd49c4b5c9dc9b \ No newline at end of file +3275ac270645139eb273b2a47c215f39bcb0e0d5 \ No newline at end of file From ddf21e8bd1a86cfa746a005015938b9c1942e174 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 11 Oct 2013 16:33:49 -0700 Subject: [PATCH 005/144] Implement mouse callback for windows --- cocos2dx/platform/win32/CCEGLView.cpp | 37 ++++++++++++++++++- cocos2dx/proj.win32/cocos2d.vcxproj | 4 ++ cocos2dx/proj.win32/cocos2d.vcxproj.filters | 12 ++++++ samples/Cpp/TestCpp/Classes/controller.cpp | 2 +- .../Cpp/TestCpp/proj.win32/TestCpp.vcxproj | 2 + .../proj.win32/TestCpp.vcxproj.filters | 9 +++++ 6 files changed, 64 insertions(+), 2 deletions(-) diff --git a/cocos2dx/platform/win32/CCEGLView.cpp b/cocos2dx/platform/win32/CCEGLView.cpp index cefcc9f038..f923d811a7 100644 --- a/cocos2dx/platform/win32/CCEGLView.cpp +++ b/cocos2dx/platform/win32/CCEGLView.cpp @@ -31,7 +31,7 @@ THE SOFTWARE. #include "event_dispatcher/CCTouch.h" #include "event_dispatcher/CCEventDispatcher.h" #include "event_dispatcher/CCEventKeyboard.h" - +#include "event_dispatcher/CCEventMouse.h" NS_CC_BEGIN @@ -277,6 +277,7 @@ public: static void OnGLFWError(int errorID, const char* errorDesc); static void OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify); static void OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y); + static void OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y); static void OnGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); static void OnGLFWCharCallback(GLFWwindow* window, unsigned int character); static void OnGLFWWindowPosCallback(GLFWwindow* windows, int x, int y); @@ -316,6 +317,21 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in } } } + + if(GLFW_PRESS == action) + { + EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + event.setMouseButton(button); + EventDispatcher::getInstance()->dispatchEvent(&event); + } + else if(GLFW_RELEASE == action) + { + EventMouse event(EventMouse::MouseEventType::MOUSE_UP); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + event.setMouseButton(button); + EventDispatcher::getInstance()->dispatchEvent(&event); + } } void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) @@ -336,6 +352,23 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, eglView->handleTouchesMove(1, &id, &s_mouseX, &s_mouseY); } } + + EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE); + //Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); +} + +void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) +{ + EGLView* eglView = EGLView::getInstance(); + if(nullptr == eglView) return; + + EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); + //Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here + event.setScrollData((float)x, -(float)y); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) @@ -405,8 +438,10 @@ bool EGLView::init(const char* viewName, float width, float height, float frameZ glfwGetFramebufferSize(_mainWindow, &_frameBufferSize[0], &_frameBufferSize[1]); glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack); glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack); + glfwSetScrollCallback(_mainWindow, EGLViewEventHandler::OnGLFWMouseScrollCallback); glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback); glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback); + glfwSetWindowPosCallback(_mainWindow, EGLViewEventHandler::OnGLFWWindowPosCallback); // check OpenGL version at first const GLubyte* glVersion = glGetString(GL_VERSION); diff --git a/cocos2dx/proj.win32/cocos2d.vcxproj b/cocos2dx/proj.win32/cocos2d.vcxproj index 46a695d1e2..ad7af4b674 100644 --- a/cocos2dx/proj.win32/cocos2d.vcxproj +++ b/cocos2dx/proj.win32/cocos2d.vcxproj @@ -182,7 +182,9 @@ xcopy /Y /Q "$(ProjectDir)..\platform\third_party\win32\libraries\*.*" "$(OutDir + + @@ -344,7 +346,9 @@ xcopy /Y /Q "$(ProjectDir)..\platform\third_party\win32\libraries\*.*" "$(OutDir + + diff --git a/cocos2dx/proj.win32/cocos2d.vcxproj.filters b/cocos2dx/proj.win32/cocos2d.vcxproj.filters index 391517347c..31d943f9ab 100644 --- a/cocos2dx/proj.win32/cocos2d.vcxproj.filters +++ b/cocos2dx/proj.win32/cocos2d.vcxproj.filters @@ -572,6 +572,12 @@ event_dispatcher + + event_dispatcher + + + event_dispatcher + @@ -1155,5 +1161,11 @@ event_dispatcher + + event_dispatcher + + + event_dispatcher + \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index 587758fe02..2842e154ae 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -204,7 +204,7 @@ void TestController::onTouchMoved(Touch* touch, Event *event) void TestController::onMouseScroll(Event *event) { auto mouseEvent = static_cast(event); - float nMoveY = -mouseEvent->getScrollY(); + float nMoveY = mouseEvent->getScrollY() * 6; auto curPos = _itemMenu->getPosition(); auto nextPos = Point(curPos.x, curPos.y + nMoveY); diff --git a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj index 35d8f4f57b..d50dce3455 100644 --- a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj +++ b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj @@ -177,6 +177,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\libwebsockets\win32\lib\*.*" "$(O + @@ -313,6 +314,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\libwebsockets\win32\lib\*.*" "$(O + diff --git a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters index bb78e048cd..b51716ad85 100644 --- a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters +++ b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters @@ -301,6 +301,9 @@ {8d7d37cd-5cc2-4a7d-9bd2-7b5c928adbb5} + + {8e8124bd-adb2-4a8f-8727-9868a9c42d80} + @@ -697,6 +700,9 @@ Classes\KeyboardTest + + Classes\InputTest + @@ -1270,5 +1276,8 @@ Classes\KeyboardTest + + Classes\InputTest + \ No newline at end of file From 292d0d74ad9d4d910b4adb91041d99d0f0c6339a Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 11 Oct 2013 16:39:54 -0700 Subject: [PATCH 006/144] Add some comments for mouse scorlling function --- cocos2dx/platform/mac/CCEGLView.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cocos2dx/platform/mac/CCEGLView.mm b/cocos2dx/platform/mac/CCEGLView.mm index b431a18c41..aade8a24cb 100644 --- a/cocos2dx/platform/mac/CCEGLView.mm +++ b/cocos2dx/platform/mac/CCEGLView.mm @@ -221,6 +221,7 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in if(GLFW_PRESS == action) { EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); + //Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); event.setMouseButton(button); EventDispatcher::getInstance()->dispatchEvent(&event); @@ -228,6 +229,7 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in else if(GLFW_RELEASE == action) { EventMouse event(EventMouse::MouseEventType::MOUSE_UP); + //Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); event.setMouseButton(button); EventDispatcher::getInstance()->dispatchEvent(&event); @@ -254,6 +256,7 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, } EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE); + //Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); EventDispatcher::getInstance()->dispatchEvent(&event); } @@ -264,7 +267,8 @@ void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x if(nullptr == eglView) return; EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); - event.setScrollData((float)x, (float)y); + //Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here + event.setScrollData((float)x, -(float)y); event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); EventDispatcher::getInstance()->dispatchEvent(&event); } From d72d8e93d2043b4839d25f9ff892cba1b7b20283 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 16 Oct 2013 22:36:00 -0700 Subject: [PATCH 007/144] Add mouse support to linux --- cocos2dx/platform/linux/CCEGLView.cpp | 35 +++++++++++++++++++++++++ cocos2dx/proj.linux/Makefile | 2 ++ samples/Cpp/TestCpp/proj.linux/Makefile | 1 + 3 files changed, 38 insertions(+) diff --git a/cocos2dx/platform/linux/CCEGLView.cpp b/cocos2dx/platform/linux/CCEGLView.cpp index 384bd05796..51ec0550b2 100644 --- a/cocos2dx/platform/linux/CCEGLView.cpp +++ b/cocos2dx/platform/linux/CCEGLView.cpp @@ -13,6 +13,7 @@ #include "text_input_node/CCIMEDispatcher.h" #include "event_dispatcher/CCEventDispatcher.h" #include "event_dispatcher/CCEventKeyboard.h" +#include "event_dispatcher/CCEventMouse.h" #include NS_CC_BEGIN @@ -159,6 +160,7 @@ public: static void OnGLFWError(int errorID, const char* errorDesc); static void OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify); static void OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y); + static void OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y); static void OnGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); static void OnGLFWCharCallback(GLFWwindow* window, unsigned int character); static void OnGLFWWindowPosCallback(GLFWwindow* windows, int x, int y); @@ -198,6 +200,21 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in } } } + + if(GLFW_PRESS == action) + { + EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + event.setMouseButton(button); + EventDispatcher::getInstance()->dispatchEvent(&event); + } + else if(GLFW_RELEASE == action) + { + EventMouse event(EventMouse::MouseEventType::MOUSE_UP); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + event.setMouseButton(button); + EventDispatcher::getInstance()->dispatchEvent(&event); + } } void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) @@ -218,6 +235,23 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, eglView->handleTouchesMove(1, &id, &s_mouseX, &s_mouseY); } } + + EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE); + //Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); +} + +void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) +{ + EGLView* eglView = EGLView::getInstance(); + if(nullptr == eglView) return; + + EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); + //Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here + event.setScrollData((float)x, -(float)y); + event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY); + EventDispatcher::getInstance()->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) @@ -282,6 +316,7 @@ bool EGLView::init(const char* viewName, float width, float height, float frameZ glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack); glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack); + glfwSetScrollCallback(_mainWindow, EGLViewEventHandler::OnGLFWMouseScrollCallback); glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback); glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback); glfwSetWindowPosCallback(_mainWindow, EGLViewEventHandler::OnGLFWWindowPosCallback); diff --git a/cocos2dx/proj.linux/Makefile b/cocos2dx/proj.linux/Makefile index fa3d1cb659..8f72b33a0d 100644 --- a/cocos2dx/proj.linux/Makefile +++ b/cocos2dx/proj.linux/Makefile @@ -46,6 +46,8 @@ SOURCES = ../actions/CCAction.cpp \ ../event_dispatcher/CCEventListener.cpp \ ../event_dispatcher/CCEventKeyboard.cpp \ ../event_dispatcher/CCEventListenerKeyboard.cpp \ +../event_dispatcher/CCEventMouse.cpp \ +../event_dispatcher/CCEventListenerMouse.cpp \ ../event_dispatcher/CCTouch.cpp \ ../event_dispatcher/CCEventTouch.cpp \ ../event_dispatcher/CCEventListenerTouch.cpp \ diff --git a/samples/Cpp/TestCpp/proj.linux/Makefile b/samples/Cpp/TestCpp/proj.linux/Makefile index b066e6606f..1e0c9492bb 100644 --- a/samples/Cpp/TestCpp/proj.linux/Makefile +++ b/samples/Cpp/TestCpp/proj.linux/Makefile @@ -85,6 +85,7 @@ SOURCES = ../Classes/AccelerometerTest/AccelerometerTest.cpp \ ../Classes/FontTest/FontTest.cpp \ ../Classes/IntervalTest/IntervalTest.cpp \ ../Classes/KeyboardTest/KeyboardTest.cpp \ + ../Classes/InputTest/MouseTest.cpp \ ../Classes/KeypadTest/KeypadTest.cpp \ ../Classes/LabelTest/LabelTest.cpp \ ../Classes/LabelTest/LabelTestNew.cpp \ From c6f9f0e4061ef3c0c05b86d19ce2a82cb5b02cd7 Mon Sep 17 00:00:00 2001 From: lite3 Date: Tue, 22 Oct 2013 11:30:53 +0800 Subject: [PATCH 008/144] do not change anchor point of child. --- extensions/GUI/CCScrollView/CCScrollView.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/extensions/GUI/CCScrollView/CCScrollView.cpp b/extensions/GUI/CCScrollView/CCScrollView.cpp index 95b9c48c51..ee6a416310 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.cpp +++ b/extensions/GUI/CCScrollView/CCScrollView.cpp @@ -469,8 +469,6 @@ void ScrollView::updateInset() */ void ScrollView::addChild(Node * child, int zOrder, int tag) { - child->ignoreAnchorPointForPosition(false); - child->setAnchorPoint(Point(0.0f, 0.0f)); if (_container != child) { _container->addChild(child, zOrder, tag); } else { From be1f17ca0ff8aefb5117eeb14b0c89db35e84d16 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 22 Oct 2013 16:14:49 +0800 Subject: [PATCH 009/144] issue #3037:Add assetsmananger lua binding and a releated test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCScriptSupport.h | 1 + cocos/scripting/lua/bindings/CCLuaEngine.cpp | 48 +++++ cocos/scripting/lua/bindings/CCLuaEngine.h | 1 + .../lua/bindings/LuaScriptHandlerMgr.h | 4 + .../lua_assetsmanager_test_sample.cpp | 164 ++++++++++++++++++ .../bindings/lua_assetsmanager_test_sample.h | 17 ++ .../lua_cocos2dx_extension_manual.cpp | 120 +++++++++++++ .../bindings/lua_cocos2dx_extension_manual.h | 11 ++ .../scripting/lua/script/Cocos2dConstants.lua | 10 ++ extensions/assets-manager/AssetsManager.h | 6 + samples/Lua/TestLua/Classes/AppDelegate.cpp | 7 + .../AssetsManagerTest/AssetsManagerModule.lua | 43 +++++ .../AssetsManagerTest/AssetsManagerTest.lua | 161 +++++++++++++++++ .../TestLua/Resources/luaScript/mainMenu.lua | 2 + tools/tojs/cocos2dx_extension.ini | 2 +- tools/tolua/cocos2dx_extension.ini | 6 +- 17 files changed, 601 insertions(+), 4 deletions(-) create mode 100644 cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.cpp create mode 100644 cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.h create mode 100644 samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerModule.lua create mode 100644 samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 18265b616b..627e8dbf20 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -1c487d29bdc2d80516e86e2ee93b1664e9f7df2f \ No newline at end of file +486af7c751cc94ff5dc25748cdb4bcb183be5dd2 \ No newline at end of file diff --git a/cocos/2d/CCScriptSupport.h b/cocos/2d/CCScriptSupport.h index 0c7f502a8b..f5803f4cb7 100644 --- a/cocos/2d/CCScriptSupport.h +++ b/cocos/2d/CCScriptSupport.h @@ -211,6 +211,7 @@ enum ScriptEventType kControlEvent, kCommonEvent, kTableViewEvent,//Now it's only used in LuaBinding + kAssetsManagerEvent,//Now it's only used in Lua Binding }; struct BasicScriptData diff --git a/cocos/scripting/lua/bindings/CCLuaEngine.cpp b/cocos/scripting/lua/bindings/CCLuaEngine.cpp index 558b68acb1..dfbf607e84 100644 --- a/cocos/scripting/lua/bindings/CCLuaEngine.cpp +++ b/cocos/scripting/lua/bindings/CCLuaEngine.cpp @@ -252,6 +252,11 @@ int LuaEngine::sendEvent(ScriptEvent* evt) return handleTableViewEvent(evt->data); } break; + case kAssetsManagerEvent: + { + return handleAssetsManagerEvent(evt->data); + } + break; default: break; } @@ -770,4 +775,47 @@ int LuaEngine::handleTableViewEventReturnArray(void* data,int numResults,Array& return ret; } + +int LuaEngine::handleAssetsManagerEvent(void* data) +{ + if (nullptr == data) + return 0; + + BasicScriptData* eventData = static_cast(data); + if (nullptr == eventData->nativeObject || nullptr == eventData->value) + return 0; + + LuaAssetsManagerEventData* assetsManagerEventData = static_cast(eventData->value); + if (assetsManagerEventData->handlerType < ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS || assetsManagerEventData->handlerType > ScriptHandlerMgr::HandlerType::ASSETSMANAGER_ERROR ) + return 0; + + int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)eventData->nativeObject, assetsManagerEventData->handlerType); + + if (0 == handler) + return 0; + + int ret = 0; + switch (assetsManagerEventData->handlerType) + { + case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS: + case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_ERROR: + { + _stack->pushInt(assetsManagerEventData->value); + ret = _stack->executeFunctionByHandler(handler, 1); + } + break; + + case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_SUCCESS: + { + ret = _stack->executeFunctionByHandler(handler, 0); + } + break; + + default: + break; + } + + return ret; +} + NS_CC_END diff --git a/cocos/scripting/lua/bindings/CCLuaEngine.h b/cocos/scripting/lua/bindings/CCLuaEngine.h index 0a1442aaaa..e739103080 100644 --- a/cocos/scripting/lua/bindings/CCLuaEngine.h +++ b/cocos/scripting/lua/bindings/CCLuaEngine.h @@ -141,6 +141,7 @@ private: int handlerControlEvent(void* data); int handleTableViewEvent(void* data); int handleTableViewEventReturnArray(void* data,int numResults,Array& resultArray); + int handleAssetsManagerEvent(void* data); void extendWebsocket(lua_State* lua_S); void extendGLNode(lua_State* lua_S); private: diff --git a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h index 44ea6fa103..d460804cf2 100644 --- a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h +++ b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h @@ -95,6 +95,10 @@ public: TABLECELL_SIZE_FOR_INDEX, TABLECELL_AT_INDEX, TABLEVIEW_NUMS_OF_CELLS, + + ASSETSMANAGER_PROGRESS, + ASSETSMANAGER_SUCCESS, + ASSETSMANAGER_ERROR, }; typedef int Handler; diff --git a/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.cpp b/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.cpp new file mode 100644 index 0000000000..e3d6377f0b --- /dev/null +++ b/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.cpp @@ -0,0 +1,164 @@ +#include "lua_assetsmanager_test_sample.h" + +#ifdef __cplusplus +extern "C" { +#endif +#include "tolua_fix.h" +#ifdef __cplusplus +} +#endif + +#include "cocos2d.h" +#include "cocos-ext.h" + +#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) +#include +#include +#endif + +USING_NS_CC; +USING_NS_CC_EXT; + + +static int lua_cocos2dx_createDownloadDir(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = lua_gettop(L); +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; +#endif + + if (0 == argc) + { + std::string pathToSave = FileUtils::getInstance()->getWritablePath(); + pathToSave += "tmpdir"; + +#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) + DIR *pDir = NULL; + + pDir = opendir (pathToSave.c_str()); + if (! pDir) + { + mkdir(pathToSave.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + } +#else + if ((GetFileAttributesA(pathToSave.c_str())) == INVALID_FILE_ATTRIBUTES) + { + CreateDirectoryA(pathToSave.c_str(), 0); + } +#endif + tolua_pushstring(L, pathToSave.c_str()); + CCLOG("the path to save is %s",pathToSave.c_str()); + return 1; + } + + CCLOG("'createDownloadDir' function wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'createDownloadDir'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_deleteDownloadDir(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = lua_gettop(L); + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; +#endif + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 1, 0, &tolua_err)) goto tolua_lerror; +#endif + std::string pathToSave = tolua_tostring(L, 1, ""); + +#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) + std::string command = "rm -r "; + // Path may include space. + command += "\"" + pathToSave + "\""; + system(command.c_str()); +#else + std::string command = "rd /s /q "; + // Path may include space. + command += "\"" + pathToSave + "\""; + system(command.c_str()); +#endif + return 0; + } + + CCLOG("'resetDownloadDir' function wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'resetDownloadDir'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_addSearchPath(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = lua_gettop(L); + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; +#endif + + + if (2 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 1, 0, &tolua_err) || + !tolua_isboolean(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + std::string pathToSave = tolua_tostring(L, 1, ""); + bool before = tolua_toboolean(L, 2, 0); + std::vector searchPaths = FileUtils::getInstance()->getSearchPaths(); + if (before) + { + searchPaths.insert(searchPaths.begin(), pathToSave); + } + else + { + searchPaths.push_back(pathToSave); + } + + FileUtils::getInstance()->setSearchPaths(searchPaths); + + return 0; + } + CCLOG("'addSearchPath' function wrong number of arguments: %d, was expecting %d\n", argc, 2); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'addSearchPath'.",&tolua_err); + return 0; +#endif +} + +int register_assetsmanager_test_sample(lua_State* L) +{ + tolua_open(L); + tolua_module(L, NULL, 0); + tolua_beginmodule(L, NULL); + tolua_function(L, "createDownloadDir", lua_cocos2dx_createDownloadDir); + tolua_function(L, "deleteDownloadDir", lua_cocos2dx_deleteDownloadDir); + tolua_function(L, "addSearchPath", lua_cocos2dx_addSearchPath); + tolua_endmodule(L); + return 0; +} diff --git a/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.h b/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.h new file mode 100644 index 0000000000..967593de71 --- /dev/null +++ b/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.h @@ -0,0 +1,17 @@ +#ifndef COCOS2DX_COCOS_SCRIPTING_LUA_BINDINGS_LUA_ASSETSMANAGER_TEST_SAMPLE_H +#define COCOS2DX_COCOS_SCRIPTING_LUA_BINDINGS_LUA_ASSETSMANAGER_TEST_SAMPLE_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "tolua++.h" +#ifdef __cplusplus +} +#endif + +/** + * The apis which are bound in this file are temporary for the assetsmanager test sample.After the completion of some systems like fileutils,these apis will be deprecated + */ +TOLUA_API int register_assetsmanager_test_sample(lua_State* tolua_S); + +#endif // #ifndef COCOS2DX_COCOS_SCRIPTING_LUA_BINDINGS_LUA_ASSETSMANAGER_TEST_SAMPLE_H diff --git a/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.cpp b/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.cpp index 0e4582b126..e74dbac377 100644 --- a/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.cpp +++ b/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.cpp @@ -1426,6 +1426,125 @@ static void extendBone(lua_State* L) } } +class LuaAssetsManagerDelegateProtocol:public Object, public AssetsManagerDelegateProtocol +{ +public: + virtual ~LuaAssetsManagerDelegateProtocol() + {} + + virtual void onProgress(int percent) + { + int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS); + if (0 != handler) + { + LuaAssetsManagerEventData eventData(ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS,percent); + BasicScriptData data((void*)this,&eventData); + ScriptEvent event(kAssetsManagerEvent,(void*)&data); + LuaEngine::getInstance()->sendEvent(&event); + } + } + + virtual void onSuccess() + { + int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, ScriptHandlerMgr::HandlerType::ASSETSMANAGER_SUCCESS); + if (0 != handler) + { + LuaAssetsManagerEventData eventData(ScriptHandlerMgr::HandlerType::ASSETSMANAGER_SUCCESS); + BasicScriptData data((void*)this,&eventData); + ScriptEvent event(kAssetsManagerEvent,(void*)&data); + LuaEngine::getInstance()->sendEvent(&event); + } + } + + virtual void onError(AssetsManager::ErrorCode errorCode) + { + int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, ScriptHandlerMgr::HandlerType::ASSETSMANAGER_ERROR); + if (0 != handler) + { + LuaAssetsManagerEventData eventData(ScriptHandlerMgr::HandlerType::ASSETSMANAGER_ERROR, (int)errorCode); + BasicScriptData data((void*)this,&eventData); + ScriptEvent event(kAssetsManagerEvent,(void*)&data); + LuaEngine::getInstance()->sendEvent(&event); + } + } +}; + +static int lua_cocos2dx_AssetsManager_setDelegate(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + AssetsManager* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"AssetsManager",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (AssetsManager*) tolua_tousertype(L,1,0); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_AssetsManager_setDelegate'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (2 == argc) + { + LuaAssetsManagerDelegateProtocol* delegate = dynamic_cast( self->getDelegate()); + if (nullptr == delegate) + { + delegate = new LuaAssetsManagerDelegateProtocol(); + if (nullptr == delegate) + return 0; + + self->setUserObject(delegate); + self->setDelegate(delegate); + delegate->release(); + } + + if (2 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!toluafix_isfunction(L, 2, "LUA_FUNCTION", 0, &tolua_err) || + !tolua_isnumber(L, 3, 0, &tolua_err) ) + { + goto tolua_lerror; + } +#endif + LUA_FUNCTION handler = toluafix_ref_function(L, 2, 0); + ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType) ((int)tolua_tonumber(L,3,0) + (int)ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS); + + ScriptHandlerMgr::getInstance()->addObjectHandler((void*)delegate, handler, handlerType); + return 0; + } + } + + CCLOG("'setDelegate' function of AssetsManager has wrong number of arguments: %d, was expecting %d\n", argc, 2); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setDelegate'.",&tolua_err); + return 0; +#endif +} + +static void extendAssetsManager(lua_State* L) +{ + lua_pushstring(L, "AssetsManager"); + lua_rawget(L, LUA_REGISTRYINDEX); + if (lua_istable(L,-1)) + { + tolua_function(L, "setDelegate", lua_cocos2dx_AssetsManager_setDelegate); + } +} + int register_all_cocos2dx_extension_manual(lua_State* tolua_S) { extendScrollView(tolua_S); @@ -1435,5 +1554,6 @@ int register_all_cocos2dx_extension_manual(lua_State* tolua_S) extendCCBAnimationManager(tolua_S); extendTableView(tolua_S); extendBone(tolua_S); + extendAssetsManager(tolua_S); return 0; } diff --git a/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.h b/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.h index dc7dd1d623..2c8b22eddb 100644 --- a/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.h +++ b/cocos/scripting/lua/bindings/lua_cocos2dx_extension_manual.h @@ -26,4 +26,15 @@ struct LuaTableViewEventData } }; +struct LuaAssetsManagerEventData +{ + cocos2d::ScriptHandlerMgr::HandlerType handlerType; + int value; + + LuaAssetsManagerEventData(cocos2d::ScriptHandlerMgr::HandlerType _handleType, int _value = 0):handlerType(_handleType),value(_value) + { + } +}; + + #endif // #ifndef COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_LUA_COCOS2DX_EXTENSION_MANUAL_H diff --git a/cocos/scripting/lua/script/Cocos2dConstants.lua b/cocos/scripting/lua/script/Cocos2dConstants.lua index 5a8ae27e94..e4dc029c55 100644 --- a/cocos/scripting/lua/script/Cocos2dConstants.lua +++ b/cocos/scripting/lua/script/Cocos2dConstants.lua @@ -272,3 +272,13 @@ cc.WEBSOCKET_STATE_CONNECTING = 0 cc.WEBSOCKET_STATE_OPEN = 1 cc.WEBSOCKET_STATE_CLOSING = 2 cc.WEBSOCKET_STATE_CLOSED = 3 + +cc.ASSETSMANAGER_CREATE_FILE = 0 +cc.ASSETSMANAGER_NETWORK = 1 +cc.ASSETSMANAGER_NO_NEW_VERSION = 2 +cc.ASSETSMANAGER_UNCOMPRESS = 3 + +cc.ASSETSMANAGER_PROTOCOL_PROGRESS = 0 +cc.ASSETSMANAGER_PROTOCOL_SUCCESS = 1 +cc.ASSETSMANAGER_PROTOCOL_ERROR = 2 + diff --git a/extensions/assets-manager/AssetsManager.h b/extensions/assets-manager/AssetsManager.h index 23e1a27774..80f0ae5d81 100644 --- a/extensions/assets-manager/AssetsManager.h +++ b/extensions/assets-manager/AssetsManager.h @@ -141,6 +141,12 @@ public: */ void setDelegate(AssetsManagerDelegateProtocol *delegate); + /** + * @js NA + * @lua NA + */ + AssetsManagerDelegateProtocol* getDelegate() { return _delegate ;} + /** @brief Sets connection time out in seconds */ void setConnectionTimeout(unsigned int timeout); diff --git a/samples/Lua/TestLua/Classes/AppDelegate.cpp b/samples/Lua/TestLua/Classes/AppDelegate.cpp index 6f5f6dedfe..025f938b6b 100644 --- a/samples/Lua/TestLua/Classes/AppDelegate.cpp +++ b/samples/Lua/TestLua/Classes/AppDelegate.cpp @@ -3,6 +3,7 @@ #include "AppDelegate.h" #include "CCLuaEngine.h" #include "SimpleAudioEngine.h" +#include "lua_assetsmanager_test_sample.h" using namespace CocosDenshion; @@ -50,7 +51,13 @@ bool AppDelegate::applicationDidFinishLaunching() LuaEngine* pEngine = LuaEngine::getInstance(); ScriptEngineManager::getInstance()->setScriptEngine(pEngine); +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID ||CC_TARGET_PLATFORM == CC_PLATFORM_IOS) + LuaStack* stack = pEngine->getLuaStack(); + register_assetsmanager_test_sample(stack->getLuaState()); +#endif + std::vector searchPaths = pFileUtils->getSearchPaths(); + searchPaths.insert(searchPaths.begin(), "Images"); searchPaths.insert(searchPaths.begin(), "cocosbuilderRes"); #if CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY diff --git a/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerModule.lua b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerModule.lua new file mode 100644 index 0000000000..ab9b3874a6 --- /dev/null +++ b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerModule.lua @@ -0,0 +1,43 @@ +local AssetManagerModule = {} + +function AssetManagerModule.newScene(backfunc) + + local winSize = cc.Director:getInstance():getWinSize() + + local newScene = cc.Scene:create() + local layer = cc.Layer:create() + + local function backToUpdate() + local scene = backfunc() + if scene ~= nil then + cc.Director:getInstance():replaceScene(scene) + end + end + + --Create BackMneu + cc.MenuItemFont:setFontName("Arial") + cc.MenuItemFont:setFontSize(24) + local backMenuItem = cc.MenuItemFont:create("Back") + backMenuItem:setPosition(cc.p(VisibleRect:rightBottom().x - 50, VisibleRect:rightBottom().y + 25)) + backMenuItem:registerScriptTapHandler(backToUpdate) + + local backMenu = cc.Menu:create() + backMenu:setPosition(0, 0) + backMenu:addChild(backMenuItem) + layer:addChild(backMenu,6) + + local helloLabel = cc.LabelTTF:create("Hello World", "Arial", 38) + helloLabel:setPosition(cc.p(winSize.width / 2, winSize.height - 40)) + layer:addChild(helloLabel, 5) + + local sprite = cc.Sprite:create("background.png") + sprite:setAnchorPoint(cc.p(0.5, 0.5)) + sprite:setPosition(cc.p(winSize.width / 2, winSize.height / 2)) + layer:addChild(sprite, 0) + + newScene:addChild(layer) + cc.Director:getInstance():replaceScene(newScene) +end + + +return AssetManagerModule diff --git a/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua new file mode 100644 index 0000000000..853342a706 --- /dev/null +++ b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua @@ -0,0 +1,161 @@ +local targetPlatform = cc.Application:getInstance():getTargetPlatform() + +local lineSpace = 40 +local itemTagBasic = 1000 +local menuItemNames = +{ + "enter", + "reset", + "update", +} + +local winSize = cc.Director:getInstance():getWinSize() + +local function updateLayer() + + local support = false + if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) + or (cc.PLATFORM_OS_WINDOWS == targetPlatform) or (cc.PLATFORM_OS_ANDROID == targetPlatform) + or (cc.PLATFORM_OS_IPHONE == targetPlatform) then + support = true + end + + if not support then + return nil + end + + local isUpdateItemClicked = false + local assetsManager = nil + local pathToSave = "" + + local layer = cc.Layer:create() + local menu = cc.Menu:create() + menu:setPosition(cc.p(0, 0)) + cc.MenuItemFont:setFontName("Arial") + cc.MenuItemFont:setFontSize(24) + + local progressLable = cc.LabelTTF:create("","Arial",30) + progressLable:setPosition(cc.p(140,50)) + layer:addChild(progressLable) + + pathToSave = createDownloadDir() + + local function onError(errorCode) + if errorCode == cc.ASSETSMANAGER_NO_NEW_VERSION then + progressLable:setString("no new version") + elseif errorCode == cc.ASSETSMANAGER_NETWORK then + progressLable:setString("network error") + end + end + + local function onProgress( percent ) + local progress = string.format("downloading %d%%",percent) + progressLable:setString(progress) + end + + local function onSuccess() + progressLable:setString("downloading ok") + end + + local function getAssetsManager() + if nil == assetsManager then + assetsManager = cc.AssetsManager:new("https://raw.github.com/samuele3hu/AssetsManagerTest/master/package.zip", + "https://raw.github.com/samuele3hu/AssetsManagerTest/master/version", + pathToSave) + assetsManager:retain() + assetsManager:setDelegate(onError, cc.ASSETSMANAGER_PROTOCOL_ERROR ) + assetsManager:setDelegate(onProgress, cc.ASSETSMANAGER_PROTOCOL_PROGRESS) + assetsManager:setDelegate(onSuccess, cc.ASSETSMANAGER_PROTOCOL_SUCCESS ) + assetsManager:setConnectionTimeout(3) + end + + return assetsManager + end + + local function update(sender) + + progressLable:setString("") + + getAssetsManager():update() + + --isUpdateItemClicked = true + + end + + local function reset(sender) + progressLable:setString("") + + deleteDownloadDir(pathToSave) + + getAssetsManager():deleteVersion() + + createDownloadDir() + end + + local function reloadModule( moduleName ) + + package.loaded[moduleName] = nil + + return require(moduleName) + end + + local function enter(sender) + + if not isUpdateItemClicked then + addSearchPath(pathToSave,true) + end + + assetsManagerModule = reloadModule("luaScript/AssetsManagerTest/AssetsManagerModule") + + assetsManagerModule.newScene(AssetsManagerTestMain) + end + + local callbackFuncs = + { + enter, + reset, + update, + } + + local function menuCallback(tag, menuItem) + local scene = nil + local nIdx = menuItem:getZOrder() - itemTagBasic + local ExtensionsTestScene = CreateExtensionsTestScene(nIdx) + if nil ~= ExtensionsTestScene then + cc.Director:getInstance():replaceScene(ExtensionsTestScene) + end + end + + for i = 1, table.getn(menuItemNames) do + local item = cc.MenuItemFont:create(menuItemNames[i]) + item:registerScriptTapHandler(callbackFuncs[i]) + item:setPosition(winSize.width / 2, winSize.height - i * lineSpace) + if not support then + item:setEnabled(false) + end + menu:addChild(item, itemTagBasic + i) + end + + local function onNodeEvent(msgName) + if nil ~= assetsManager then + assetsManager:release() + assetsManager = nil + end + end + + layer:registerScriptHandler(onNodeEvent) + + layer:addChild(menu) + + return layer +end + +------------------------------------- +-- AssetsManager Test +------------------------------------- +function AssetsManagerTestMain() + local scene = cc.Scene:create() + scene:addChild(updateLayer()) + scene:addChild(CreateBackMenuItem()) + return scene +end diff --git a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua index 73d79855d6..1a534252e1 100644 --- a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua +++ b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua @@ -13,6 +13,7 @@ require "luaScript/ActionManagerTest/ActionManagerTest" require "luaScript/ActionsEaseTest/ActionsEaseTest" require "luaScript/ActionsProgressTest/ActionsProgressTest" require "luaScript/ActionsTest/ActionsTest" +require "luaScript/AssetsManagerTest/AssetsManagerTest" require "luaScript/BugsTest/BugsTest" require "luaScript/ClickAndMoveTest/ClickAndMoveTest" require "luaScript/CocosDenshionTest/CocosDenshionTest" @@ -58,6 +59,7 @@ local _allTests = { { isSupported = true, name = "ActionsEaseTest" , create_func = EaseActionsTest }, { isSupported = true, name = "ActionsProgressTest" , create_func = ProgressActionsTest }, { isSupported = true, name = "ActionsTest" , create_func = ActionsTest }, + { isSupported = true, name = "AssetsManagerTest" , create_func = AssetsManagerTestMain }, { isSupported = false, name = "Box2dTest" , create_func= Box2dTestMain }, { isSupported = false, name = "Box2dTestBed" , create_func= Box2dTestBedMain }, { isSupported = true, name = "BugsTest" , create_func= BugsTestMain }, diff --git a/tools/tojs/cocos2dx_extension.ini b/tools/tojs/cocos2dx_extension.ini index 1519b2eb92..c91b2545ea 100644 --- a/tools/tojs/cocos2dx_extension.ini +++ b/tools/tojs/cocos2dx_extension.ini @@ -44,7 +44,7 @@ skip = CCBReader::[^CCBReader$ addOwnerCallbackName isJSControlled readByte getC *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType .*HSV onTouch.* onAcc.* onKey.* onRegisterTouchListener], EditBox::[(g|s)etDelegate ^keyboard.* touchDownAction getScriptEditBoxHandler registerScriptEditBoxHandler unregisterScriptEditBoxHandler], TableView::[create (g|s)etDataSource$ (g|s)etDelegate], - AssetsManager::[setDelegate], + AssetsManager::[(g|s)etDelegate], AssetsManagerDelegateProtocol::[*], Control::[removeHandleOfControlEvent addHandleOfControlEvent], ControlUtils::[*], diff --git a/tools/tolua/cocos2dx_extension.ini b/tools/tolua/cocos2dx_extension.ini index 67d87c51d6..dd5aa433aa 100644 --- a/tools/tolua/cocos2dx_extension.ini +++ b/tools/tolua/cocos2dx_extension.ini @@ -13,7 +13,7 @@ android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include clang_flags = -nostdinc -x c++ -std=c++11 -cocos_headers = -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/gui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath/include -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s +cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/gui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath/include -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT cxxgenerator_headers = @@ -26,7 +26,7 @@ headers = %(cocosdir)s/extensions/cocos-ext.h %(cocosdir)s/cocos/editor-support/ # what classes to produce code for. You can use regular expressions here. When testing the regular # expression, it will be enclosed in "^$", like this: "^Menu*$". -classes = CCBReader.* CCBAnimationManager.* Scale9Sprite Control.* ControlButton.* ScrollView$ TableView$ TableViewCell$ EditBox$ Armature ArmatureAnimation Skin Bone ArmatureDataManager \w+Data$ +classes = AssetsManager.* CCBReader.* CCBAnimationManager.* Scale9Sprite Control.* ControlButton.* ScrollView$ TableView$ TableViewCell$ EditBox$ Armature ArmatureAnimation Skin Bone ArmatureDataManager \w+Data$ # what should we skip? in the format ClassName::[function function] # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also @@ -43,6 +43,8 @@ skip = CCBReader::[^CCBReader$ addOwnerCallbackName isJSControlled readByte getC *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType (g|s)etDelegate .*HSV], EditBox::[(g|s)etDelegate ^keyboard.* touchDownAction getScriptEditBoxHandler registerScriptEditBoxHandler unregisterScriptEditBoxHandler], TableView::[create (g|s)etDataSource$ (g|s)etDelegate], + AssetsManager::[(g|s)etDelegate], + AssetsManagerDelegateProtocol::[*], Control::[removeHandleOfControlEvent addHandleOfControlEvent], ControlUtils::[*], ControlSwitchSprite::[*], From 3305dd1de3a1c6f4ece62865e8ea6fbe8353a10b Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 23 Oct 2013 17:05:27 +0800 Subject: [PATCH 010/144] issues #2905:add miss file --- tools/tojs/cocos2dx_builder.ini | 65 +++++++++++++++++++++++++++++++++ tools/tojs/cocos2dx_studio.ini | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 tools/tojs/cocos2dx_builder.ini create mode 100644 tools/tojs/cocos2dx_studio.ini diff --git a/tools/tojs/cocos2dx_builder.ini b/tools/tojs/cocos2dx_builder.ini new file mode 100644 index 0000000000..15de5f54d8 --- /dev/null +++ b/tools/tojs/cocos2dx_builder.ini @@ -0,0 +1,65 @@ +[cocos2dx_builder] +# the prefix to be added to the generated functions. You might or might not use this in your own +# templates +prefix = cocos2dx_builder + +# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`) +# all classes will be embedded in that namespace +target_namespace = cc + +android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include +android_flags = -D_SIZE_T_DEFINED_ + +clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include +clang_flags = -nostdinc -x c++ -std=c++11 + +cocos_headers = -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/gui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath/include -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s + +cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT + +cxxgenerator_headers = + +# extra arguments for clang +extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s + +# what headers to parse +headers = %(cocosdir)s/cocos/editor-support/cocosbuilder/CocosBuilder.h + +# what classes to produce code for. You can use regular expressions here. When testing the regular +# expression, it will be enclosed in "^$", like this: "^Menu*$". +classes = CCBReader.* CCBAnimationManager.* + +# what should we skip? in the format ClassName::[function function] +# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also +# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just +# add a single "*" as functions. See bellow for several examples. A special class name is "*", which +# will apply to all class names. This is a convenience wildcard to be able to skip similar named +# functions from all classes. + +skip = CCBReader::[^CCBReader$ addOwnerCallbackName isJSControlled readByte getCCBMemberVariableAssigner readFloat getCCBSelectorResolver toLowerCase lastPathComponent deletePathExtension endsWith concat getResolutionScale getAnimatedProperties readBool readInt addOwnerCallbackNode addDocumentCallbackName readCachedString readNodeGraphFromData addDocumentCallbackNode getLoadedSpriteSheet initWithData readFileWithCleanUp getOwner$ readNodeGraphFromFile createSceneWithNodeGraphFromFile getAnimationManagers$ setAnimationManagers], + CCBAnimationManager::[setAnimationCompletedCallback], + .*Delegate::[*], + .*Loader.*::[*], + *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType .*HSV onTouch.* onAcc.* onKey.* onRegisterTouchListener] + +rename_functions = + +rename_classes = CCBReader::_Reader, + CCBAnimationManager::BuilderAnimationManager + +# for all class names, should we remove something when registering in the target VM? +remove_prefix = + +# classes for which there will be no "parent" lookup +classes_have_no_parents = + +# base classes which will be skipped when their sub-classes found them. +base_classes_to_skip = Object + +# classes that create no constructor +# Set is special and we will use a hand-written constructor +abstract_classes = + +# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'. +script_control_cpp = no + diff --git a/tools/tojs/cocos2dx_studio.ini b/tools/tojs/cocos2dx_studio.ini new file mode 100644 index 0000000000..47859dac3f --- /dev/null +++ b/tools/tojs/cocos2dx_studio.ini @@ -0,0 +1,65 @@ +[cocos2dx_studio] +# the prefix to be added to the generated functions. You might or might not use this in your own +# templates +prefix = cocos2dx_studio + +# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`) +# all classes will be embedded in that namespace +target_namespace = cc + +android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include +android_flags = -D_SIZE_T_DEFINED_ + +clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include +clang_flags = -nostdinc -x c++ -std=c++11 + +cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/gui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath/include -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s + +cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT + +cxxgenerator_headers = + +# extra arguments for clang +extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s + +# what headers to parse +headers = %(cocosdir)s/cocos/editor-support/cocostudio/CocoStudio.h + +# what classes to produce code for. You can use regular expressions here. When testing the regular +# expression, it will be enclosed in "^$", like this: "^Menu*$". +classes = Armature ArmatureAnimation Skin Bone ArmatureDataManager + +# what should we skip? in the format ClassName::[function function] +# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also +# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just +# add a single "*" as functions. See bellow for several examples. A special class name is "*", which +# will apply to all class names. This is a convenience wildcard to be able to skip similar named +# functions from all classes. + +skip = .*Delegate::[*], + .*Loader.*::[*], + *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType .*HSV onTouch.* onAcc.* onKey.* onRegisterTouchListener], + Armature::[createBone updateBlendType getBody setBody getShapeList .*BlendFunc], + Skin::[getSkinData setSkinData], + ArmatureAnimation::[updateHandler updateFrameData frameEvent] + +rename_functions = + +rename_classes = + +# for all class names, should we remove something when registering in the target VM? +remove_prefix = + +# classes for which there will be no "parent" lookup +classes_have_no_parents = + +# base classes which will be skipped when their sub-classes found them. +base_classes_to_skip = Object ProcessBase + +# classes that create no constructor +# Set is special and we will use a hand-written constructor +abstract_classes = ArmatureDataManager + +# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'. +script_control_cpp = no + From 899f720efa299637abbc41a10f33a33419ed4d86 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Wed, 23 Oct 2013 17:28:23 +0800 Subject: [PATCH 011/144] issue #2771: implement getShapeAtPoint and getShapesAtPoint --- cocos/physics/CCPhysicsJoint.cpp | 21 ++++++---- cocos/physics/CCPhysicsWorld.cpp | 33 ++++++++++++++- cocos/physics/CCPhysicsWorld.h | 1 + .../Classes/PhysicsTest/PhysicsTest.cpp | 41 +++++++++++++------ .../TestCpp/Classes/PhysicsTest/PhysicsTest.h | 12 +++++- 5 files changed, 85 insertions(+), 23 deletions(-) diff --git a/cocos/physics/CCPhysicsJoint.cpp b/cocos/physics/CCPhysicsJoint.cpp index 09b1de36dd..6631599f71 100644 --- a/cocos/physics/CCPhysicsJoint.cpp +++ b/cocos/physics/CCPhysicsJoint.cpp @@ -70,16 +70,21 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b) { do { - CC_BREAK_IF(a == nullptr || b == nullptr); - CC_BREAK_IF(!(_info = new PhysicsJointInfo(this))); - _bodyA = a; - _bodyA->retain(); - _bodyA->_joints.push_back(this); - _bodyB = b; - _bodyB->retain(); - _bodyB->_joints.push_back(this); + if (a != nullptr) + { + _bodyA = a; + _bodyA->retain(); + _bodyA->_joints.push_back(this); + } + + if (b != nullptr) + { + _bodyB = b; + _bodyB->retain(); + _bodyB->_joints.push_back(this); + } return true; } while (false); diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index ec7514ef6d..44d0fc1f96 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -88,6 +88,7 @@ public: static void collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, PhysicsWorld *world); static void rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect n, RayCastCallbackInfo *info); static void rectQueryCallbackFunc(cpShape *shape, RectQueryCallbackInfo *info); + static void nearestPointQueryFunc(cpShape *shape, cpFloat distance, cpVect point, Array *arr); public: static bool continues; @@ -166,6 +167,15 @@ void PhysicsWorldCallback::rectQueryCallbackFunc(cpShape *shape, RectQueryCallba info->data); } +void PhysicsWorldCallback::nearestPointQueryFunc(cpShape *shape, cpFloat distance, cpVect point, Array *arr) +{ + auto it = PhysicsShapeInfo::map.find(shape); + + CC_ASSERT(it != PhysicsShapeInfo::map.end()); + + arr->addObject(it->second->shape); +} + bool PhysicsWorld::init() { _info = new PhysicsWorldInfo(); @@ -561,9 +571,30 @@ void PhysicsWorld::rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void } } -Array* getShapesAtPoint(Point point) +Array* PhysicsWorld::getShapesAtPoint(Point point) { + Array* arr = Array::create(); + cpSpaceNearestPointQuery(this->_info->space, + PhysicsHelper::point2cpv(point), + 0, + CP_ALL_LAYERS, + CP_NO_GROUP, + (cpSpaceNearestPointQueryFunc)PhysicsWorldCallback::nearestPointQueryFunc, + arr); + return arr; +} + +PhysicsShape* PhysicsWorld::getShapeAtPoint(Point point) +{ + cpShape* shape = cpSpaceNearestPointQueryNearest(this->_info->space, + PhysicsHelper::point2cpv(point), + 0, + CP_ALL_LAYERS, + CP_NO_GROUP, + nullptr); + + return shape == nullptr ? nullptr : PhysicsShapeInfo::map.find(shape)->second->shape; } Array* PhysicsWorld::getAllBody() const diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index 868889b539..63c841cc93 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -98,6 +98,7 @@ public: void rayCast(PhysicsRayCastCallback& callback, Point point1, Point point2, void* data); void rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void* data); Array* getShapesAtPoint(Point point); + PhysicsShape* getShapeAtPoint(Point point); Array* getAllBody() const; /** Register a listener to receive contact callbacks*/ diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 907a0df83a..c92b431716 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -92,6 +92,7 @@ PhysicsDemo::PhysicsDemo() : _scene(nullptr) , _ball(nullptr) , _spriteTexture(nullptr) +, _mouse(nullptr) { } @@ -296,7 +297,8 @@ namespace -25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,127,-64,31,-2,0,15,103,-1,-1,-57,-8,127, -97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,127,-64,15,-8,0,0,55,-1,-1,-121,-8, 127,-97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,63,-64,15,-32,0,0,23,-1,-2,3,-16, - 63,15,-61,-16,0,31,-127,-127,-8,31,-1,-127,-8,31,-128,7,-128,0,0}; + 63,15,-61,-16,0,31,-127,-127,-8,31,-1,-127,-8,31,-128,7,-128,0,0 + }; static inline int get_pixel(int x, int y) { @@ -365,6 +367,31 @@ Sprite* PhysicsDemo::makeTriangle(float x, float y, Size size, PhysicsMaterial m return triangle; } +void PhysicsDemo::onTouchesBegan(const std::vector& touches, Event* event) +{ + for( auto &touch: touches) + { + auto location = touch->getLocation(); + Array* arr = _scene->getPhysicsWorld()->getShapesAtPoint(location); + + PhysicsShape* shape = nullptr; + for (Object* obj : *arr) + { + + } + } +} + +void PhysicsDemo::onTouchesMoved(const std::vector& touches, Event* event) +{ + +} + +void PhysicsDemo::onTouchesEnded(const std::vector& touches, Event* event) +{ + +} + void PhysicsDemoLogoSmash::onEnter() { PhysicsDemo::onEnter(); @@ -687,18 +714,6 @@ void PhysicsDemoJoints::onEnter() } -void PhysicsDemoJoints::onTouchesEnded(const std::vector& touches, Event* event) -{ - //Add a new body/atlas sprite at the touched location - - for( auto &touch: touches) - { - auto location = touch->getLocation(); - - - } -} - std::string PhysicsDemoJoints::title() { return "Joints"; diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index 9df12624de..b915e9d664 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -41,9 +41,14 @@ public: Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = {1.0f, 1.0f, 1.0f}); Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = {1.0f, 1.0f, 1.0f}); + void onTouchesBegan(const std::vector& touches, Event* event) override; + void onTouchesMoved(const std::vector& touches, Event* event) override; + void onTouchesEnded(const std::vector& touches, Event* event) override; + protected: Texture2D* _spriteTexture; // weak ref SpriteBatchNode* _ball; + DrawNode* _mouse; }; class PhysicsDemoClickAdd : public PhysicsDemo @@ -99,10 +104,15 @@ private: class PhysicsDemoJoints : public PhysicsDemo { +public: + PhysicsDemoJoints(); + public: void onEnter() override; std::string title() override; - void onTouchesEnded(const std::vector& touches, Event* event) override; + +private: + PhysicsShape* _touchesShape; }; #endif From a8ddca81bd165d8d06f04f63d22f7d1d17626440 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Wed, 23 Oct 2013 18:52:09 +0800 Subject: [PATCH 012/144] issue #2771: fix some compile error in win32 --- cocos/physics/CCPhysicsBody.h | 2 +- cocos/physics/CCPhysicsShape.h | 18 ++++++++++++------ .../Classes/PhysicsTest/PhysicsTest.cpp | 10 +++++----- .../TestCpp/Classes/PhysicsTest/PhysicsTest.h | 6 +++--- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/cocos/physics/CCPhysicsBody.h b/cocos/physics/CCPhysicsBody.h index 65d9f7318a..f1715b0f1a 100644 --- a/cocos/physics/CCPhysicsBody.h +++ b/cocos/physics/CCPhysicsBody.h @@ -43,7 +43,7 @@ class PhysicsJoint; class PhysicsBodyInfo; -const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT = {1.0f, 1.0f, 1.0f}; +const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT(1.0f, 1.0f, 1.0f); /** * A body affect by physics. diff --git a/cocos/physics/CCPhysicsShape.h b/cocos/physics/CCPhysicsShape.h index ebbe646466..6cd5329f6d 100644 --- a/cocos/physics/CCPhysicsShape.h +++ b/cocos/physics/CCPhysicsShape.h @@ -44,14 +44,20 @@ typedef struct PhysicsMaterial float restitution; float friction; - static PhysicsMaterial make(float density, float restitution, float friction) - { - PhysicsMaterial var = {density, restitution, friction}; - return var; - } + PhysicsMaterial() + : density(0.0f) + , restitution(0.0f) + , friction(0.0f) + {} + + PhysicsMaterial(float density, float restitution, float friction) + : density(density) + , restitution(restitution) + , friction(friction) + {} }PhysicsMaterial; -const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT = {0.0f, 1.0f, 1.0f}; +const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT(0.0f, 1.0f, 1.0f); /** * @brief A shape for body. You do not create PhysicsWorld objects directly, instead, you can view PhysicsBody to see how to create it. diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index c92b431716..f0ceb3553c 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -50,7 +50,7 @@ namespace return layer; } - static const Color4F STATIC_COLOR = {1.0f, 0.0f, 0.0f, 1.0f}; + static const Color4F STATIC_COLOR(1.0f, 0.0f, 0.0f, 1.0f); } @@ -411,7 +411,7 @@ void PhysicsDemoLogoSmash::onEnter() Node* ball = makeBall(2*(x - logo_width/2 + x_jitter) + VisibleRect::getVisibleRect().size.width/2, 2*(logo_height-y + y_jitter) + VisibleRect::getVisibleRect().size.height/2 - logo_height/2, - 0.95f, PhysicsMaterial::make(1.0f, 0.0f, 0.0f)); + 0.95f, PhysicsMaterial(1.0f, 0.0f, 0.0f)); ball->getPhysicsBody()->setMass(1.0); ball->getPhysicsBody()->setMoment(PHYSICS_INFINITY); @@ -423,7 +423,7 @@ void PhysicsDemoLogoSmash::onEnter() } - auto bullet = makeBall(400, 0, 10, PhysicsMaterial::make(PHYSICS_INFINITY, 0, 0)); + auto bullet = makeBall(400, 0, 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0)); bullet->getPhysicsBody()->setVelocity(Point(400, 0)); bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2)); @@ -454,7 +454,7 @@ void PhysicsDemoPyramidStack::onEnter() { for(int j=0; j<=i; j++) { - addGrossiniAtPosition(VisibleRect::bottom() + Point((i/2 - j) * 11, (14 - i) * 23 + 100), 0.2); + addGrossiniAtPosition(VisibleRect::bottom() + Point((i/2 - j) * 11, (14 - i) * 23 + 100), 0.2f); } } } @@ -671,7 +671,7 @@ void PhysicsDemoRayCast::update(float delta) break; } - _angle += 0.25f * M_PI / 180.0f; + _angle += 0.25f * (float)M_PI / 180.0f; } void PhysicsDemoRayCast::onTouchesEnded(const std::vector& touches, Event* event) diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index b915e9d664..0c685ef98e 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -37,9 +37,9 @@ public: void toggleDebugCallback(Object* sender); void addGrossiniAtPosition(Point p, float scale = 1.0); - Sprite* makeBall(float x, float y, float radius, PhysicsMaterial material = {1.0f, 1.0f, 1.0f}); - Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = {1.0f, 1.0f, 1.0f}); - Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = {1.0f, 1.0f, 1.0f}); + Sprite* makeBall(float x, float y, float radius, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f)); + Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f)); + Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f)); void onTouchesBegan(const std::vector& touches, Event* event) override; void onTouchesMoved(const std::vector& touches, Event* event) override; From d7689073e0c91c342ed551614ddef050cf537d7c Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 24 Oct 2013 11:12:21 +0800 Subject: [PATCH 013/144] issue #3049:Add XMLHttpRequest lua binding and corresponding test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- .../lua/bindings/lua_xml_http_request.cpp | 922 ++++++++++++++++++ .../lua/bindings/lua_xml_http_request.h | 94 ++ 3 files changed, 1017 insertions(+), 1 deletion(-) create mode 100644 cocos/scripting/lua/bindings/lua_xml_http_request.cpp create mode 100644 cocos/scripting/lua/bindings/lua_xml_http_request.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 18265b616b..b62768a5e8 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -1c487d29bdc2d80516e86e2ee93b1664e9f7df2f \ No newline at end of file +fcdf6af61b7c3ac52b92590b16090335bd26b169 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp new file mode 100644 index 0000000000..eaf2202ba0 --- /dev/null +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp @@ -0,0 +1,922 @@ + +#include "lua_xml_http_request.h" + +extern "C" +{ +#include "tolua_fix.h" +} + +#include + +using namespace std; + +LuaMinXmlHttpRequest::LuaMinXmlHttpRequest():_isNetwork(true) +{ + _httpHeader.clear(); + _requestHeader.clear(); + _withCredentialsValue = true; + _httpRequest = new network::HttpRequest(); +} + +LuaMinXmlHttpRequest::~LuaMinXmlHttpRequest() +{ + _httpHeader.clear(); + _requestHeader.clear(); +} + +/** + * @brief Implementation for header retrieving. + * @param header + */ +void LuaMinXmlHttpRequest::_gotHeader(string header) +{ + // Get Header and Set StatusText + // Split String into Tokens + char * cstr = new char [header.length()+1]; + + // check for colon. + unsigned found_header_field = header.find_first_of(":"); + + if (found_header_field != std::string::npos) + { + // Found a header field. + string http_field; + string http_value; + + http_field = header.substr(0,found_header_field); + http_value = header.substr(found_header_field+1, header.length()); + + // Get rid of all \n + if (!http_value.empty() && http_value[http_value.size() - 1] == '\n') { + http_value.erase(http_value.size() - 1); + } + + _httpHeader[http_field] = http_value; + + } + else + { + // Seems like we have the response Code! Parse it and check for it. + char * pch; + strcpy(cstr, header.c_str()); + + pch = strtok(cstr," "); + while (pch != NULL) + { + + stringstream ss; + string val; + + ss << pch; + val = ss.str(); + unsigned found_http = val.find("HTTP"); + + // Check for HTTP Header to set statusText + if (found_http != std::string::npos) { + + stringstream mystream; + + // Get Response Status + pch = strtok (NULL, " "); + mystream << pch; + + pch = strtok (NULL, " "); + mystream << " " << pch; + + _statusText = mystream.str(); + + } + + pch = strtok (NULL, " "); + } + } + + CC_SAFE_DELETE_ARRAY(cstr); +} + +/** + * @brief Set Request header for next call. + * @param field Name of the Header to be set. + * @param value Value of the Headerfield + */ +void LuaMinXmlHttpRequest::setRequestHeader(const char* field, const char* value) +{ + stringstream header_s; + stringstream value_s; + string header; + + map::iterator iter = _requestHeader.find(field); + + // Concatenate values when header exists. + if (iter != _requestHeader.end()) + { + value_s << iter->second << "," << value; + } + else + { + value_s << value; + } + + _requestHeader[field] = value_s.str(); +} + +/** + * @brief If headers has been set, pass them to curl. + * + */ +void LuaMinXmlHttpRequest::_setHttpRequestHeader() +{ + std::vector header; + + for (auto it = _requestHeader.begin(); it != _requestHeader.end(); ++it) + { + const char* first = it->first.c_str(); + const char* second = it->second.c_str(); + size_t len = sizeof(char) * (strlen(first) + 3 + strlen(second)); + char* test = (char*) malloc(len); + memset(test, 0,len); + + strcpy(test, first); + strcpy(test + strlen(first) , ": "); + strcpy(test + strlen(first) + 2, second); + + header.push_back(test); + + free(test); + + } + + if (!header.empty()) + { + _httpRequest->setHeaders(header); + } + +} + +/** + * @brief Send out request and fire callback when done. + */ +void LuaMinXmlHttpRequest::_sendRequest() +{ + _httpRequest->setResponseCallback(this, httpresponse_selector(LuaMinXmlHttpRequest::handle_requestResponse)); + network::HttpClient::getInstance()->send(_httpRequest); + _httpRequest->release(); +} + + +/** + * @brief Callback for HTTPRequest. Handles the response and invokes Callback. + * @param sender Object which initialized callback + * @param respone Response object + * @js NA + */ +void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, network::HttpResponse *response) +{ + if (0 != strlen(response->getHttpRequest()->getTag())) + { + CCLOG("%s completed", response->getHttpRequest()->getTag()); + } + + int statusCode = response->getResponseCode(); + char statusString[64] = {}; + sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag()); + + if (!response->isSucceed()) + { + CCLOG("response failed"); + CCLOG("error buffer: %s", response->getErrorBuffer()); + return; + } + + // set header + std::vector *headers = response->getResponseHeader(); + + char* concatHeader = (char*) malloc(headers->size() + 1); + std::string header(headers->begin(), headers->end()); + strcpy(concatHeader, header.c_str()); + + std::istringstream stream(concatHeader); + std::string line; + while(std::getline(stream, line)) { + _gotHeader(line); + } + + /** get the response data **/ + std::vector *buffer = response->getResponseData(); + char* concatenated = (char*) malloc(buffer->size() + 1); + std::string s2(buffer->begin(), buffer->end()); + + strcpy(concatenated, s2.c_str()); + + if (statusCode == 200) + { + //Succeeded + _status = 200; + _readyState = DONE; + _data << concatenated; + _dataSize = buffer->size(); + } + else + { + _status = 0; + } + // Free Memory. + free((void*) concatHeader); + free((void*) concatenated); + + // call back lua function --TODO + int handler = 0; +} + +/* function to regType */ +static void lua_reg_xml_http_request(lua_State* L) +{ + tolua_usertype(L, "XMLHttpRequest"); +} + +static int lua_collect_xml_http_request (lua_State* L) +{ + LuaMinXmlHttpRequest* self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); + Mtolua_delete(self); + return 0; +} + +static int lua_cocos2dx_XMLHttpRequest_constructor(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; +#endif + + argc = lua_gettop(L)-1; + if (argc == 0) + { + self = new LuaMinXmlHttpRequest(); + self->autorelease(); + int ID = self? (int)self->_ID : -1; + int* luaID = self? &self->_luaID : NULL; + toluafix_pushusertype_ccobject(L, ID, luaID, (void*)self, "XMLHttpRequest"); + } + + CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "XMLHttpRequest",argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_constructor'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_responseType(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_responseType'\n", nullptr); + return 0; + } +#endif + + tolua_pushnumber(L, (lua_Number)self->getResponseType()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_responseType'.",&tolua_err); + return 0; +#endif +} + +static int lua_set_XMLHttpRequest_responseType(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_set_XMLHttpRequest_responseType'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isnumber(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + int responseType = (int)tolua_tonumber(L,2,0); + + self->setResponseType((LuaMinXmlHttpRequest::ResponseType)responseType); + + return 0; + } + + CCLOG("'setResponseType' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_set_XMLHttpRequest_responseType'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_withCredentials(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_withCredentials'\n", nullptr); + return 0; + } +#endif + + tolua_pushboolean(L, self->getWithCredentialsValue()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_withCredentials'.",&tolua_err); + return 0; +#endif +} + +static int lua_set_XMLHttpRequest_withCredentials(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_set_XMLHttpRequest_withCredentials'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + self->setWithCredentialsValue((bool)tolua_toboolean(L, 2, 0)); + return 0; + } + + CCLOG("'setWithCredentials' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_set_XMLHttpRequest_withCredentials'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_timeout(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_timeout'\n", nullptr); + return 0; + } +#endif + + tolua_pushnumber(L, (lua_Number)self->getTimeout()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_timeout'.",&tolua_err); + return 0; +#endif +} + +static int lua_set_XMLHttpRequest_timeout(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_set_XMLHttpRequest_timeout'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isnumber(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + self->setTimeout((unsigned)tolua_tonumber(L, 2, 0)); + return 0; + } + + CCLOG("'setTimeout' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_set_XMLHttpRequest_timeout'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_readyState(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_readyState'\n", nullptr); + return 0; + } +#endif + + lua_pushinteger(L, (lua_Integer)self->getReadyState()); + + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_readyState'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_status(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_status'\n", nullptr); + return 0; + } +#endif + + lua_pushinteger(L, (lua_Integer)self->getStatus()); + + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_status'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_statusText(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_statusText'\n", nullptr); + return 0; + } +#endif + + lua_pushstring(L, self->getStatusText().c_str()); + + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_statusText'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_response(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_response'\n", nullptr); + return 0; + } +#endif + + if (self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::JSON) + { + //TODO + return 0; + } + else if(self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::ARRAY_BUFFER) + { + //TODO + return 0; + } + else + { + lua_pushstring(L, self->getStatusText().c_str()); + return 1; + } + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_response'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_open(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_open'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( argc >= 2) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err) || + !tolua_isstring(L, 3, 0, &tolua_err)) + goto tolua_lerror; +#endif + + std::string method = tolua_tostring(L, 2, ""); + std::string url = tolua_tostring(L, 3, ""); + bool async = true; + if (argc > 2) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 4, 0, &tolua_err) ) + goto tolua_lerror; +#endif + async = tolua_toboolean(L, 4, 0); + } + + self->setUrl(url); + self->setMethod(method); + self->setReadyState(1); + self->setAsync(async); + + if (url.length() > 5 && url.compare(url.length() - 5, 5, ".json") == 0 ) + { + self->setResponseType(LuaMinXmlHttpRequest::ResponseType::JSON); + } + + if (nullptr != self->getHttpRequest()) + { + if (method.compare("post") == 0 || method.compare("POST") == 0) + { + self->getHttpRequest()->setRequestType(network::HttpRequest::Type::POST); + } + else + { + self->getHttpRequest()->setRequestType(network::HttpRequest::Type::GET); + } + + self->getHttpRequest()->setUrl(url.c_str()); + + } + + self->setIsNetWork(true); + self->setReadyState(LuaMinXmlHttpRequest::OPENED); + + return 0; + } + + CCLOG("'open' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 2); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_open'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + std::string data = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_send'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 1 == argc ) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + data = tolua_tostring(L, 2, ""); + } + + if (data.length() > 0 && + (self->getMethod().compare("post") == 0 || self->getMethod().compare("POST") == 0) && + nullptr != self->getHttpRequest()) + { + self->getHttpRequest()->setRequestData(data.c_str(), data.length()); + } + + self->_setHttpRequestHeader(); + self->_sendRequest(); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_send'.",&tolua_err); + return 0; +#endif +} + +/** + * @brief abort function Placeholder! + */ +static int lua_cocos2dx_XMLHttpRequest_abort(lua_State* L) +{ + return 0; +} + +static int lua_cocos2dx_XMLHttpRequest_setRequestHeader(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + const char* field = ""; + const char* value = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_setRequestHeader'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 2 == argc ) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err) || + !tolua_isstring(L, 3, 0, &tolua_err) ) + goto tolua_lerror; +#endif + + field = tolua_tostring(L, 2, ""); + value = tolua_tostring(L, 3, ""); + self->setRequestHeader(field, value); + return 0; + } + + CCLOG("'setRequestHeader' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 2); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_setRequestHeader'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + stringstream responseheaders; + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 0 == argc ) + { + map httpHeader = self->getHttpHeader(); + + for (auto it = httpHeader.begin(); it != httpHeader.end(); ++it) + { + responseheaders << it->first << ": "<< it->second << "\n"; + } + + responseheader = responseheaders.str(); + tolua_pushstring(L, responseheader.c_str()); + return 1; + } + + CCLOG("'getAllResponseHeaders' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_getResponseHeader(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 1 == argc ) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err) ) + goto tolua_lerror; +#endif + responseheader = tolua_tostring(L, 2, ""); + + stringstream streamData; + streamData << responseheader; + + string value = streamData.str(); + + + auto iter = self->getHttpHeader().find(value); + if (iter != self->getHttpHeader().end()) + { + tolua_pushstring(L, (iter->second).c_str()); + return 1; + } + } + + CCLOG("'getResponseHeader' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'.",&tolua_err); + return 0; +#endif +} + +TOLUA_API int lua_xml_http_request_open(lua_State* L) +{ + tolua_open(L); + lua_reg_xml_http_request(L); + tolua_module(L,NULL,0); + tolua_beginmodule(L,NULL); + tolua_cclass(L,"XMLHttpRequest","XMLHttpRequest","",lua_collect_xml_http_request); + tolua_beginmodule(L,"XMLHttpRequest"); + tolua_variable(L, "responseType", lua_get_XMLHttpRequest_responseType, lua_set_XMLHttpRequest_responseType); + tolua_variable(L, "withCredentials", lua_get_XMLHttpRequest_withCredentials, lua_set_XMLHttpRequest_withCredentials); + tolua_variable(L, "timeout", lua_get_XMLHttpRequest_timeout, lua_set_XMLHttpRequest_timeout); + tolua_variable(L, "readyState", lua_get_XMLHttpRequest_readyState, nullptr); + tolua_variable(L, "status",lua_get_XMLHttpRequest_status,nullptr); + tolua_variable(L, "statusText", lua_get_XMLHttpRequest_statusText, nullptr); + tolua_variable(L, "response", lua_get_XMLHttpRequest_response, nullptr); + tolua_function(L, "new", lua_cocos2dx_XMLHttpRequest_constructor); + tolua_function(L, "open", lua_cocos2dx_XMLHttpRequest_open); + tolua_function(L, "send", lua_cocos2dx_XMLHttpRequest_send); + tolua_function(L, "abort", lua_cocos2dx_XMLHttpRequest_abort); + tolua_function(L, "setRequestHeader", lua_cocos2dx_XMLHttpRequest_setRequestHeader); + tolua_function(L, "getAllResponseHeaders", lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders); + tolua_function(L, "getResponseHeader", lua_cocos2dx_XMLHttpRequest_getResponseHeader); + tolua_endmodule(L); + tolua_endmodule(L); + return 1; +} diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.h b/cocos/scripting/lua/bindings/lua_xml_http_request.h new file mode 100644 index 0000000000..2b5a3a2f17 --- /dev/null +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.h @@ -0,0 +1,94 @@ +#ifndef __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ +#define __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "tolua++.h" +#ifdef __cplusplus +} +#endif + + +#include "network/HttpClient.h" + +class LuaMinXmlHttpRequest : public cocos2d::Object +{ +public: + enum class ResponseType + { + STRING, + ARRAY_BUFFER, + BLOB, + DOCUMENT, + JSON + }; + + // Ready States (http://www.w3.org/TR/XMLHttpRequest/#interface-xmlhttprequest) + static const unsigned short UNSENT = 0; + static const unsigned short OPENED = 1; + static const unsigned short HEADERS_RECEIVED = 2; + static const unsigned short LOADING = 3; + static const unsigned short DONE = 4; + + LuaMinXmlHttpRequest(); + ~LuaMinXmlHttpRequest(); + + void handle_requestResponse(network::HttpClient *sender, network::HttpResponse *response); + + inline void setResponseType(ResponseType type) { _responseType = type; } + inline ResponseType getResponseType() {return _responseType; } + + inline void setWithCredentialsValue(bool value) { _withCredentialsValue = value; } + inline bool getWithCredentialsValue() {return _withCredentialsValue; } + + inline void setTimeout(unsigned timeOut) {_timeout = timeOut; } + inline unsigned getTimeout() { return _timeout;} + + inline void setReadyState(int readyState) { _readyState = readyState; } + inline int getReadyState() { return _readyState ;} + + inline network::HttpRequest* getHttpRequest() { return _httpRequest; } + inline int getStatus() { return _status; } + inline std::string getStatusText() { return _statusText ;} + + inline std::string getUrl(){return _url;} + inline void setUrl(std::string url) { _url = url ;} + + inline std::string getMethod(){return _meth;} + inline void setMethod(std::string meth) { _meth = meth ; } + + inline void setAsync(bool isAsync){ _isAsync = isAsync; } + inline void setIsNetWork(bool isNetWork) {_isNetwork = isNetWork; } + + void _setHttpRequestHeader(); + void _sendRequest(); + void setRequestHeader(const char* field, const char* value); + + std::map getHttpHeader() { return _httpHeader ;} +private: + void _gotHeader(std::string header); + + + + std::string _url; + std::string _meth; + std::string _type; + std::stringstream _data; + size_t _dataSize; + int _readyState; + int _status; + std::string _statusText; + ResponseType _responseType; + unsigned _timeout; + bool _isAsync; + network::HttpRequest* _httpRequest; + bool _isNetwork; + bool _withCredentialsValue; + std::map _httpHeader; + std::map _requestHeader; +}; + +TOLUA_API int lua_xml_http_request_open(lua_State* L); + +#endif //#ifndef __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ From fd993e2fa210ab7c4c2a274518ffc72d6f4b532c Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Thu, 24 Oct 2013 17:54:57 +0800 Subject: [PATCH 014/144] issues #2905:split jsbinding module --- .../scripting/javascript/bindings/Android.mk | 43 +++---------------- .../javascript/bindings/chipmunk/Android.mk | 33 ++++++++++++++ .../bindings/cocosbuilder/Android.mk | 29 +++++++++++++ .../javascript/bindings/cocostudio/Android.mk | 30 +++++++++++++ .../javascript/bindings/extension/Android.mk | 30 +++++++++++++ .../bindings/localstorage/Android.mk | 29 +++++++++++++ .../javascript/bindings/network/Android.mk | 30 +++++++++++++ .../proj.android/jni/Android.mk | 13 ++++++ 8 files changed, 200 insertions(+), 37 deletions(-) create mode 100644 cocos/scripting/javascript/bindings/chipmunk/Android.mk create mode 100644 cocos/scripting/javascript/bindings/cocosbuilder/Android.mk create mode 100644 cocos/scripting/javascript/bindings/cocostudio/Android.mk create mode 100644 cocos/scripting/javascript/bindings/extension/Android.mk create mode 100644 cocos/scripting/javascript/bindings/localstorage/Android.mk create mode 100644 cocos/scripting/javascript/bindings/network/Android.mk diff --git a/cocos/scripting/javascript/bindings/Android.mk b/cocos/scripting/javascript/bindings/Android.mk index 5689684060..8195fde121 100644 --- a/cocos/scripting/javascript/bindings/Android.mk +++ b/cocos/scripting/javascript/bindings/Android.mk @@ -8,65 +8,34 @@ LOCAL_MODULE_FILENAME := libcocos2dxjsb LOCAL_SRC_FILES := ScriptingCore.cpp \ cocos2d_specifics.cpp \ - jsb_cocos2dx_extension_manual.cpp \ js_manual_conversions.cpp \ cocosjs_manual_conversions.cpp \ - js_bindings_chipmunk_manual.cpp \ - js_bindings_chipmunk_functions.cpp \ - js_bindings_chipmunk_auto_classes.cpp \ - js_bindings_chipmunk_registration.cpp \ - js_bindings_system_functions.cpp \ - js_bindings_system_registration.cpp \ - js_bindings_ccbreader.cpp \ js_bindings_core.cpp \ js_bindings_opengl.cpp \ jsb_opengl_functions.cpp \ jsb_opengl_manual.cpp \ jsb_opengl_registration.cpp \ - ../../auto-generated/js-bindings/jsb_cocos2dx_auto.cpp \ - ../../auto-generated/js-bindings/jsb_cocos2dx_extension_auto.cpp \ - XMLHTTPRequest.cpp \ - jsb_websocket.cpp + ../../auto-generated/js-bindings/jsb_cocos2dx_auto.cpp LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT LOCAL_C_INCLUDES := $(LOCAL_PATH) \ - $(LOCAL_PATH)/../../../CocosDenshion/include \ + $(LOCAL_PATH)/../../../audio/include \ + $(LOCAL_PATH)/../../../storage \ $(LOCAL_PATH)/../../auto-generated/js-bindings \ - $(LOCAL_PATH)/../../../../extensions \ - $(LOCAL_PATH)/../../../editor-support/cocostudio \ - $(LOCAL_PATH)/../../../editor-support/cocosbuilder + $(LOCAL_PATH)/../../../../extensions LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \ - $(LOCAL_PATH)/../../auto-generated/js-bindings + $(LOCAL_PATH)/../../auto-generated/js-bindings \ + $(LOCAL_PATH)/../../../audio/include LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static LOCAL_WHOLE_STATIC_LIBRARIES += spidermonkey_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static -LOCAL_WHOLE_STATIC_LIBRARIES += spine_static LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static -LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocos_localstorage_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static -LOCAL_WHOLE_STATIC_LIBRARIES += websockets_static - -LOCAL_LDLIBS := -landroid -LOCAL_LDLIBS += -llog include $(BUILD_STATIC_LIBRARY) $(call import-module,spidermonkey/prebuilt/android) -$(call import-module,extensions) $(call import-module,2d) -$(call import-module,extensions) -$(call import-module,editor-support/cocosbuilder) -$(call import-module,editor-support/spine) -$(call import-module,network) -$(call import-module,chipmunk) -$(call import-module,storage/local-storage) -$(call import-module,editor-support/cocostudio) -$(call import-module,websockets/prebuilt/android) diff --git a/cocos/scripting/javascript/bindings/chipmunk/Android.mk b/cocos/scripting/javascript/bindings/chipmunk/Android.mk new file mode 100644 index 0000000000..ae7b615b57 --- /dev/null +++ b/cocos/scripting/javascript/bindings/chipmunk/Android.mk @@ -0,0 +1,33 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jsb_chipmunk_static + +LOCAL_MODULE_FILENAME := libcocos2dxjsbchipmunk + +LOCAL_SRC_FILES := js_bindings_chipmunk_manual.cpp \ + js_bindings_chipmunk_functions.cpp \ + js_bindings_chipmunk_auto_classes.cpp \ + js_bindings_chipmunk_registration.cpp + +LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../../.. + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_WHOLE_STATIC_LIBRARIES := spidermonkey_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static + +include $(BUILD_STATIC_LIBRARY) + +$(call import-module,spidermonkey/prebuilt/android) +$(call import-module,scripting/javascript/bindings) +$(call import-module,extensions) +$(call import-module,chipmunk) diff --git a/cocos/scripting/javascript/bindings/cocosbuilder/Android.mk b/cocos/scripting/javascript/bindings/cocosbuilder/Android.mk new file mode 100644 index 0000000000..be5e73de8f --- /dev/null +++ b/cocos/scripting/javascript/bindings/cocosbuilder/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jsb_builder_static + +LOCAL_MODULE_FILENAME := libcocos2dxjsbbuilder + +LOCAL_SRC_FILES := js_bindings_ccbreader.cpp \ + ../../../auto-generated/js-bindings/jsb_cocos2dx_builder_auto.cpp + +LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../../editor-support/cocosbuilder + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_WHOLE_STATIC_LIBRARIES := spidermonkey_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static + +include $(BUILD_STATIC_LIBRARY) + +$(call import-module,spidermonkey/prebuilt/android) +$(call import-module,scripting/javascript/bindings) +$(call import-module,editor-support/cocosbuilder) diff --git a/cocos/scripting/javascript/bindings/cocostudio/Android.mk b/cocos/scripting/javascript/bindings/cocostudio/Android.mk new file mode 100644 index 0000000000..ca0eb1939f --- /dev/null +++ b/cocos/scripting/javascript/bindings/cocostudio/Android.mk @@ -0,0 +1,30 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jsb_studio_static + +LOCAL_MODULE_FILENAME := libcocos2dxjsbstudio + +LOCAL_SRC_FILES := jsb_cocos2dx_studio_manual.cpp \ + ../../../auto-generated/js-bindings/jsb_cocos2dx_studio_auto.cpp + +LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../../../extensions \ + $(LOCAL_PATH)/../../../../editor-support/cocostudio + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_WHOLE_STATIC_LIBRARIES := spidermonkey_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static + +include $(BUILD_STATIC_LIBRARY) + +$(call import-module,spidermonkey/prebuilt/android) +$(call import-module,scripting/javascript/bindings) +$(call import-module,editor-support/cocostudio) diff --git a/cocos/scripting/javascript/bindings/extension/Android.mk b/cocos/scripting/javascript/bindings/extension/Android.mk new file mode 100644 index 0000000000..871a5c1cf5 --- /dev/null +++ b/cocos/scripting/javascript/bindings/extension/Android.mk @@ -0,0 +1,30 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jsb_extension_static + +LOCAL_MODULE_FILENAME := libcocos2dxjsbextension + +LOCAL_SRC_FILES := jsb_cocos2dx_extension_manual.cpp \ + ../../../auto-generated/js-bindings/jsb_cocos2dx_extension_auto.cpp + +LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../../../extensions + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../../../ + +LOCAL_WHOLE_STATIC_LIBRARIES := spidermonkey_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static + +include $(BUILD_STATIC_LIBRARY) + +$(call import-module,spidermonkey/prebuilt/android) +$(call import-module,scripting/javascript/bindings) +$(call import-module,extensions) diff --git a/cocos/scripting/javascript/bindings/localstorage/Android.mk b/cocos/scripting/javascript/bindings/localstorage/Android.mk new file mode 100644 index 0000000000..e13104f94c --- /dev/null +++ b/cocos/scripting/javascript/bindings/localstorage/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jsb_localstorage_static + +LOCAL_MODULE_FILENAME := libcocos2dxjsblocalstorage + +LOCAL_SRC_FILES := js_bindings_system_functions.cpp \ + js_bindings_system_registration.cpp + +LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../../../extensions + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_WHOLE_STATIC_LIBRARIES := spidermonkey_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_localstorage_static + +include $(BUILD_STATIC_LIBRARY) + +$(call import-module,spidermonkey/prebuilt/android) +$(call import-module,scripting/javascript/bindings) +$(call import-module,storage/local-storage) diff --git a/cocos/scripting/javascript/bindings/network/Android.mk b/cocos/scripting/javascript/bindings/network/Android.mk new file mode 100644 index 0000000000..6f5c59aa96 --- /dev/null +++ b/cocos/scripting/javascript/bindings/network/Android.mk @@ -0,0 +1,30 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jsb_network_static + +LOCAL_MODULE_FILENAME := libcocos2dxjsbnetwork + +LOCAL_SRC_FILES := XMLHTTPRequest.cpp \ + jsb_websocket.cpp + +LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT + +LOCAL_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_WHOLE_STATIC_LIBRARIES := spidermonkey_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += websockets_static + +include $(BUILD_STATIC_LIBRARY) + +$(call import-module,spidermonkey/prebuilt/android) +$(call import-module,scripting/javascript/bindings) +$(call import-module,network) +$(call import-module,websockets/prebuilt/android) diff --git a/samples/Javascript/TestJavascript/proj.android/jni/Android.mk b/samples/Javascript/TestJavascript/proj.android/jni/Android.mk index 89d17346d0..0a9f023dc3 100644 --- a/samples/Javascript/TestJavascript/proj.android/jni/Android.mk +++ b/samples/Javascript/TestJavascript/proj.android/jni/Android.mk @@ -12,9 +12,22 @@ LOCAL_SRC_FILES := testjavascript/main.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_chipmunk_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_localstorage_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_builder_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_studio_static + LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 include $(BUILD_SHARED_LIBRARY) $(call import-module,scripting/javascript/bindings) +$(call import-module,scripting/javascript/bindings/chipmunk) +$(call import-module,scripting/javascript/bindings/extension) +$(call import-module,scripting/javascript/bindings/localstorage) +$(call import-module,scripting/javascript/bindings/network) +$(call import-module,scripting/javascript/bindings/cocosbuilder) +$(call import-module,scripting/javascript/bindings/cocostudio) From 342003f7b244d68b8ae9a5419a8290fb96b95de3 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 18:03:15 +0800 Subject: [PATCH 015/144] Update AUTHORS --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index 4dff8c12b5..9357213fb6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -627,6 +627,9 @@ Developers: Fixed a bug that CCBReader can't play sequence automatically in JSB. Could not set next animation in CCBAnimationCompleted callback. + lite3 + Fixed a bug that Node's anchor point was changed after being added to ScrollView. + Retired Core Developers: WenSheng Yang Author of windows port, CCTextField, From f2584f973007259760a5135feed1e9267e7d16c0 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 18:04:13 +0800 Subject: [PATCH 016/144] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 7b81c3c5f9..567b572bc1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] Avoid unnecessary object duplication for Scale9Sprite. [FIX] create_project.py does not rename/replace template projects completely. [FIX] Could not set next animation in CCBAnimationCompleted callback. + [FIX] The Node's anchor point was changed after being added to ScrollView. [Android] [FIX] Added EGL_RENDERABLE_TYPE to OpenGL attributes [NEW] Added Cocos2dxHelper.runOnGLThread(Runnable) again From 56ef19714642b4a74b227d1f20b2a034613c19bd Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Thu, 24 Oct 2013 18:36:36 +0800 Subject: [PATCH 017/144] update the reference to cocos2d-x repo. --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index 893da8ccfb..2f3c531665 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit 893da8ccfb4ed7fa754c483a90dc4e5248c36e03 +Subproject commit 2f3c5316657e64ec38b8ed3ea6826eb48c46f32c From b4eb97058905e1790fdf5313159f53d61aa9a228 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 10:50:03 +0800 Subject: [PATCH 018/144] [JSB] Fixing compilation errors for iOS and Mac projects. --- build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 18265b616b..17e0cee1da 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -1c487d29bdc2d80516e86e2ee93b1664e9f7df2f \ No newline at end of file +b695026fc3d856d540590ff09112696f66379c22 \ No newline at end of file From 779e539658687b7ab81a70802a8c65bc6227633e Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 12 Oct 2013 11:25:28 +0800 Subject: [PATCH 019/144] Remove event controller codes from Layer class. HelloCpp works. --- cocos/2d/CCEventDispatcher.cpp | 51 +--- cocos/2d/CCEventListener.cpp | 2 +- cocos/2d/CCEventListener.h | 2 +- cocos/2d/CCEventListenerAcceleration.cpp | 2 +- cocos/2d/CCEventListenerAcceleration.h | 2 +- cocos/2d/CCEventListenerCustom.cpp | 4 +- cocos/2d/CCEventListenerCustom.h | 2 +- cocos/2d/CCEventListenerKeyboard.cpp | 2 +- cocos/2d/CCEventListenerKeyboard.h | 2 +- cocos/2d/CCEventListenerTouch.cpp | 131 +++++--- cocos/2d/CCEventListenerTouch.h | 52 +++- cocos/2d/CCEventTouch.cpp | 3 + cocos/2d/CCEventTouch.h | 5 + cocos/2d/CCLayer.cpp | 365 ----------------------- cocos/2d/CCLayer.h | 76 ----- cocos/2d/CCMenu.cpp | 14 +- cocos/2d/CCMenu.h | 8 +- 17 files changed, 166 insertions(+), 557 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 14be190f68..0e596b788a 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -125,7 +125,7 @@ void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* list CCASSERT(listener && node, "Invalid parameters."); CCASSERT(!listener->_isRegistered, "The listener has been registered."); - if (!listener->checkAvaiable()) + if (!listener->checkAvailable()) return; auto item = new EventListenerItem(); @@ -147,7 +147,7 @@ void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, CCASSERT(!listener->_isRegistered, "The listener has been registered."); CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority."); - if (!listener->checkAvaiable()) + if (!listener->checkAvailable()) return; auto item = new EventListenerItem(); @@ -294,37 +294,14 @@ void EventDispatcher::dispatchEvent(Event* event, bool forceSortListeners) void EventDispatcher::dispatchTouchEvent(EventTouch* event) { - auto touchListeners = getListenerItemsForType(EventTouch::EVENT_TYPE); - if (touchListeners == nullptr) + auto oneByOnelisteners = getListenerItemsForType(EventTouch::MODE_ONE_BY_ONE); + auto allAtOncelisteners = getListenerItemsForType(EventTouch::MODE_ALL_AT_ONCE); + + // If there aren't any touch listeners, return directly. + if (nullptr == oneByOnelisteners && nullptr == allAtOncelisteners) return; - std::vector oneByOnelisteners; - oneByOnelisteners.reserve(touchListeners->size()); - - std::vector allInOnelisteners; - allInOnelisteners.reserve(touchListeners->size()); - - EventListenerTouch* touchEventListener = nullptr; - - std::for_each(touchListeners->begin(), touchListeners->end(), [&](EventListenerItem*& item){ - - touchEventListener = static_cast(item->listener); - - if (touchEventListener->_dispatchMode == Touch::DispatchMode::ONE_BY_ONE) - { - oneByOnelisteners.push_back(item); - } - else if (touchEventListener->_dispatchMode == Touch::DispatchMode::ALL_AT_ONCE) - { - allInOnelisteners.push_back(item); - } - else - { - CCASSERT(false, "Not supported touch listener type."); - } - }); - - bool isNeedsMutableSet = (oneByOnelisteners.size() > 0 && allInOnelisteners.size() > 0); + bool isNeedsMutableSet = (oneByOnelisteners && allAtOncelisteners); std::vector orignalTouches = event->getTouches(); std::vector mutableTouches(orignalTouches.size()); @@ -333,7 +310,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // // process the target handlers 1st // - if (oneByOnelisteners.size() > 0) + if (oneByOnelisteners) { auto mutableTouchesIter = mutableTouches.begin(); auto touchesIter = orignalTouches.begin(); @@ -342,7 +319,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) { bool isSwallowed = false; - for (auto& item : oneByOnelisteners) + for (auto& item : *oneByOnelisteners) { // Skip if the listener was removed. if (item->listener == nullptr) @@ -353,7 +330,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) bool isClaimed = false; std::vector::iterator removedIter; - auto touchEventListener = static_cast(item->listener); + auto touchEventListener = static_cast(item->listener); EventTouch::EventCode eventCode = event->getEventCode(); if (eventCode == EventTouch::EventCode::BEGAN) @@ -434,9 +411,9 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // // process standard handlers 2nd // - if (allInOnelisteners.size() > 0 && mutableTouches.size() > 0) + if (allAtOncelisteners && mutableTouches.size() > 0) { - for (auto& item : allInOnelisteners) + for (auto& item : *allAtOncelisteners) { // Skip if the listener was removed. if (item->listener == nullptr) @@ -444,7 +421,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) event->setCurrentTarget(item->node); - auto touchEventListener = static_cast(item->listener); + auto touchEventListener = static_cast(item->listener); switch (event->getEventCode()) { diff --git a/cocos/2d/CCEventListener.cpp b/cocos/2d/CCEventListener.cpp index ce3c787883..451be9a8c8 100644 --- a/cocos/2d/CCEventListener.cpp +++ b/cocos/2d/CCEventListener.cpp @@ -44,7 +44,7 @@ bool EventListener::init(const std::string& t, std::function callb return true; } -bool EventListener::checkAvaiable() +bool EventListener::checkAvailable() { return (_onEvent != nullptr); } diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index 82c47445e0..559cf21739 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -54,7 +54,7 @@ public: virtual ~EventListener(); /** Checks whether the listener is available. */ - virtual bool checkAvaiable() = 0; + virtual bool checkAvailable() = 0; /** Clones the listener, its subclasses have to override this method. */ virtual EventListener* clone() = 0; diff --git a/cocos/2d/CCEventListenerAcceleration.cpp b/cocos/2d/CCEventListenerAcceleration.cpp index e7e1f6055b..d8b01fc4ce 100644 --- a/cocos/2d/CCEventListenerAcceleration.cpp +++ b/cocos/2d/CCEventListenerAcceleration.cpp @@ -84,7 +84,7 @@ EventListenerAcceleration* EventListenerAcceleration::clone() return ret; } -bool EventListenerAcceleration::checkAvaiable() +bool EventListenerAcceleration::checkAvailable() { CCASSERT(onAccelerationEvent, ""); diff --git a/cocos/2d/CCEventListenerAcceleration.h b/cocos/2d/CCEventListenerAcceleration.h index 1fb9536be7..2905df9486 100644 --- a/cocos/2d/CCEventListenerAcceleration.h +++ b/cocos/2d/CCEventListenerAcceleration.h @@ -38,7 +38,7 @@ public: /// Overrides virtual EventListenerAcceleration* clone() override; - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; private: EventListenerAcceleration(); diff --git a/cocos/2d/CCEventListenerCustom.cpp b/cocos/2d/CCEventListenerCustom.cpp index 7be79b9dcb..abe4153198 100644 --- a/cocos/2d/CCEventListenerCustom.cpp +++ b/cocos/2d/CCEventListenerCustom.cpp @@ -80,10 +80,10 @@ EventListenerCustom* EventListenerCustom::clone() return ret; } -bool EventListenerCustom::checkAvaiable() +bool EventListenerCustom::checkAvailable() { bool ret = false; - if (EventListener::checkAvaiable() && _onCustomEvent != nullptr) + if (EventListener::checkAvailable() && _onCustomEvent != nullptr) { ret = true; } diff --git a/cocos/2d/CCEventListenerCustom.h b/cocos/2d/CCEventListenerCustom.h index 190ed63f95..a823d4a4ba 100644 --- a/cocos/2d/CCEventListenerCustom.h +++ b/cocos/2d/CCEventListenerCustom.h @@ -59,7 +59,7 @@ public: static EventListenerCustom* create(const std::string& eventName, std::function callback); /// Overrides - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; virtual EventListenerCustom* clone() override; protected: diff --git a/cocos/2d/CCEventListenerKeyboard.cpp b/cocos/2d/CCEventListenerKeyboard.cpp index 80709f8cef..a6e3b617ae 100644 --- a/cocos/2d/CCEventListenerKeyboard.cpp +++ b/cocos/2d/CCEventListenerKeyboard.cpp @@ -29,7 +29,7 @@ NS_CC_BEGIN -bool EventListenerKeyboard::checkAvaiable() +bool EventListenerKeyboard::checkAvailable() { CCASSERT(onKeyPressed && onKeyReleased, ""); diff --git a/cocos/2d/CCEventListenerKeyboard.h b/cocos/2d/CCEventListenerKeyboard.h index f7b4c288d9..dd223da533 100644 --- a/cocos/2d/CCEventListenerKeyboard.h +++ b/cocos/2d/CCEventListenerKeyboard.h @@ -40,7 +40,7 @@ public: /// Overrides virtual EventListenerKeyboard* clone() override; - virtual bool checkAvaiable() override; + virtual bool checkAvailable() override; std::function onKeyPressed; std::function onKeyReleased; diff --git a/cocos/2d/CCEventListenerTouch.cpp b/cocos/2d/CCEventListenerTouch.cpp index ec418c2949..49ec1462c9 100644 --- a/cocos/2d/CCEventListenerTouch.cpp +++ b/cocos/2d/CCEventListenerTouch.cpp @@ -30,46 +30,39 @@ NS_CC_BEGIN -EventListenerTouch::EventListenerTouch() +EventListenerTouchOneByOne::EventListenerTouchOneByOne() : onTouchBegan(nullptr) , onTouchMoved(nullptr) , onTouchEnded(nullptr) , onTouchCancelled(nullptr) -, onTouchesBegan(nullptr) -, onTouchesMoved(nullptr) -, onTouchesEnded(nullptr) -, onTouchesCancelled(nullptr) , _needSwallow(false) -, _dispatchMode(Touch::DispatchMode::ALL_AT_ONCE) { } -EventListenerTouch::~EventListenerTouch() +EventListenerTouchOneByOne::~EventListenerTouchOneByOne() { - CCLOGINFO("In the destructor of TouchEventListener, %p", this); + CCLOGINFO("In the destructor of EventListenerTouchOneByOne, %p", this); } -bool EventListenerTouch::init(Touch::DispatchMode mode) +bool EventListenerTouchOneByOne::init() { - if (EventListener::init(EventTouch::EVENT_TYPE, nullptr)) + if (EventListener::init(EventTouch::MODE_ONE_BY_ONE, nullptr)) { - _dispatchMode = mode; return true; } return false; } -void EventListenerTouch::setSwallowTouches(bool needSwallow) +void EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow) { - CCASSERT(_dispatchMode == Touch::DispatchMode::ONE_BY_ONE, "Swallow touches only available in OneByOne mode."); _needSwallow = needSwallow; } -EventListenerTouch* EventListenerTouch::create(Touch::DispatchMode mode) +EventListenerTouchOneByOne* EventListenerTouchOneByOne::create() { - auto ret = new EventListenerTouch(); - if (ret && ret->init(mode)) + auto ret = new EventListenerTouchOneByOne(); + if (ret && ret->init()) { ret->autorelease(); } @@ -80,38 +73,22 @@ EventListenerTouch* EventListenerTouch::create(Touch::DispatchMode mode) return ret; } -bool EventListenerTouch::checkAvaiable() +bool EventListenerTouchOneByOne::checkAvailable() { - if (_dispatchMode == Touch::DispatchMode::ALL_AT_ONCE) + if (onTouchBegan == nullptr && onTouchMoved == nullptr + && onTouchEnded == nullptr && onTouchCancelled == nullptr) { - if (onTouchesBegan == nullptr && onTouchesMoved == nullptr - && onTouchesEnded == nullptr && onTouchesCancelled == nullptr) - { - CCASSERT(false, "Invalid TouchEventListener."); - return false; - } - } - else if (_dispatchMode == Touch::DispatchMode::ONE_BY_ONE) - { - if (onTouchBegan == nullptr && onTouchMoved == nullptr - && onTouchEnded == nullptr && onTouchCancelled == nullptr) - { - CCASSERT(false, "Invalid TouchEventListener."); - return false; - } - } - else - { - CCASSERT(false, ""); + CCASSERT(false, "Invalid TouchEventListener."); + return false; } return true; } -EventListenerTouch* EventListenerTouch::clone() +EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone() { - auto ret = new EventListenerTouch(); - if (ret && ret->init(_dispatchMode)) + auto ret = new EventListenerTouchOneByOne(); + if (ret && ret->init()) { ret->autorelease(); @@ -119,13 +96,8 @@ EventListenerTouch* EventListenerTouch::clone() ret->onTouchMoved = onTouchMoved; ret->onTouchEnded = onTouchEnded; ret->onTouchCancelled = onTouchCancelled; - ret->onTouchesBegan = onTouchesBegan; - ret->onTouchesMoved = onTouchesMoved; - ret->onTouchesEnded = onTouchesEnded; - ret->onTouchesCancelled = onTouchesCancelled; ret->_claimedTouches = _claimedTouches; - ret->_dispatchMode = _dispatchMode; ret->_needSwallow = _needSwallow; } else @@ -135,4 +107,73 @@ EventListenerTouch* EventListenerTouch::clone() return ret; } +///////// +EventListenerTouchAllAtOnce::EventListenerTouchAllAtOnce() +: onTouchesBegan(nullptr) +, onTouchesMoved(nullptr) +, onTouchesEnded(nullptr) +, onTouchesCancelled(nullptr) +{ +} + +EventListenerTouchAllAtOnce::~EventListenerTouchAllAtOnce() +{ + CCLOGINFO("In the destructor of EventListenerTouchAllAtOnce, %p", this); +} + +bool EventListenerTouchAllAtOnce::init() +{ + if (EventListener::init(EventTouch::MODE_ALL_AT_ONCE, nullptr)) + { + return true; + } + + return false; +} + +EventListenerTouchAllAtOnce* EventListenerTouchAllAtOnce::create() +{ + auto ret = new EventListenerTouchAllAtOnce(); + if (ret && ret->init()) + { + ret->autorelease(); + } + else + { + CC_SAFE_DELETE(ret); + } + return ret; +} + +bool EventListenerTouchAllAtOnce::checkAvailable() +{ + if (onTouchesBegan == nullptr && onTouchesMoved == nullptr + && onTouchesEnded == nullptr && onTouchesCancelled == nullptr) + { + CCASSERT(false, "Invalid TouchEventListener."); + return false; + } + + return true; +} + +EventListenerTouchAllAtOnce* EventListenerTouchAllAtOnce::clone() +{ + auto ret = new EventListenerTouchAllAtOnce(); + if (ret && ret->init()) + { + ret->autorelease(); + + ret->onTouchesBegan = onTouchesBegan; + ret->onTouchesMoved = onTouchesMoved; + ret->onTouchesEnded = onTouchesEnded; + ret->onTouchesCancelled = onTouchesCancelled; + } + else + { + CC_SAFE_DELETE(ret); + } + return ret; +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCEventListenerTouch.h b/cocos/2d/CCEventListenerTouch.h index 3002676bda..d34de1b237 100644 --- a/cocos/2d/CCEventListenerTouch.h +++ b/cocos/2d/CCEventListenerTouch.h @@ -33,38 +33,58 @@ NS_CC_BEGIN -class EventListenerTouch : public EventListener + +class EventListenerTouchOneByOne : public EventListener { public: - static EventListenerTouch* create(Touch::DispatchMode mode); + static EventListenerTouchOneByOne* create(); + + virtual ~EventListenerTouchOneByOne(); + + void setSwallowTouches(bool needSwallow); /// Overrides - virtual EventListenerTouch* clone() override; - virtual bool checkAvaiable() override; - - virtual ~EventListenerTouch(); - -private: - EventListenerTouch(); - bool init(Touch::DispatchMode mode); - + virtual EventListenerTouchOneByOne* clone() override; + virtual bool checkAvailable() override; + // + public: std::function onTouchBegan; std::function onTouchMoved; std::function onTouchEnded; std::function onTouchCancelled; +private: + EventListenerTouchOneByOne(); + bool init(); + + std::vector _claimedTouches; + bool _needSwallow; + + friend class EventDispatcher; +}; + + +class EventListenerTouchAllAtOnce : public EventListener +{ +public: + static EventListenerTouchAllAtOnce* create(); + virtual ~EventListenerTouchAllAtOnce(); + + /// Overrides + virtual EventListenerTouchAllAtOnce* clone() override; + virtual bool checkAvailable() override; + // +public: std::function&, Event*)> onTouchesBegan; std::function&, Event*)> onTouchesMoved; std::function&, Event*)> onTouchesEnded; std::function&, Event*)> onTouchesCancelled; - void setSwallowTouches(bool needSwallow); - private: - std::vector _claimedTouches; - bool _needSwallow; - Touch::DispatchMode _dispatchMode; + EventListenerTouchAllAtOnce(); + bool init(); +private: friend class EventDispatcher; }; diff --git a/cocos/2d/CCEventTouch.cpp b/cocos/2d/CCEventTouch.cpp index dbb0963775..987d87d0e9 100644 --- a/cocos/2d/CCEventTouch.cpp +++ b/cocos/2d/CCEventTouch.cpp @@ -26,6 +26,9 @@ NS_CC_BEGIN +const char* EventTouch::MODE_ONE_BY_ONE = "TouchEventOneByOne"; +const char* EventTouch::MODE_ALL_AT_ONCE = "TouchEventAllAtOnce"; + const char* EventTouch::EVENT_TYPE = "TouchEvent"; NS_CC_END diff --git a/cocos/2d/CCEventTouch.h b/cocos/2d/CCEventTouch.h index 3d54cecea7..558bfe0593 100644 --- a/cocos/2d/CCEventTouch.h +++ b/cocos/2d/CCEventTouch.h @@ -36,7 +36,12 @@ NS_CC_BEGIN class EventTouch : public Event { public: + static const char* MODE_ONE_BY_ONE; + static const char* MODE_ALL_AT_ONCE; + static const char* EVENT_TYPE; + + static const int MAX_TOUCHES = 5; enum class EventCode diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index 19346ea844..717570e6fe 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -48,14 +48,6 @@ NS_CC_BEGIN // Layer Layer::Layer() -: _touchEnabled(false) -, _accelerometerEnabled(false) -, _keyboardEnabled(false) -, _touchMode(Touch::DispatchMode::ALL_AT_ONCE) -, _swallowsTouches(true) -, _touchListener(nullptr) -, _keyboardListener(nullptr) -, _accelerationListener(nullptr) { _ignoreAnchorPointForPosition = true; setAnchorPoint(Point(0.5f, 0.5f)); @@ -74,8 +66,6 @@ bool Layer::init() Director * pDirector; CC_BREAK_IF(!(pDirector = Director::getInstance())); this->setContentSize(pDirector->getWinSize()); - setTouchEnabled(false); - setAccelerometerEnabled(false); // success bRet = true; } while(0); @@ -97,44 +87,6 @@ Layer *Layer::create() } } -/// Touch and Accelerometer related - -void Layer::addTouchListener() -{ - if (_touchListener != nullptr) - return; - - auto dispatcher = EventDispatcher::getInstance(); - - if( _touchMode == Touch::DispatchMode::ALL_AT_ONCE ) - { - // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ALL_AT_ONCE); - - listener->onTouchesBegan = CC_CALLBACK_2(Layer::onTouchesBegan, this); - listener->onTouchesMoved = CC_CALLBACK_2(Layer::onTouchesMoved, this); - listener->onTouchesEnded = CC_CALLBACK_2(Layer::onTouchesEnded, this); - listener->onTouchesCancelled = CC_CALLBACK_2(Layer::onTouchesCancelled, this); - - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - _touchListener = listener; - } - else - { - // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); - listener->setSwallowTouches(_swallowsTouches); - - listener->onTouchBegan = CC_CALLBACK_2(Layer::onTouchBegan, this); - listener->onTouchMoved = CC_CALLBACK_2(Layer::onTouchMoved, this); - listener->onTouchEnded = CC_CALLBACK_2(Layer::onTouchEnded, this); - listener->onTouchCancelled = CC_CALLBACK_2(Layer::onTouchCancelled, this); - - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - _touchListener = listener; - } -} - int Layer::executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* touch) { if (kScriptTypeNone != _scriptType) @@ -160,323 +112,6 @@ int Layer::executeScriptTouchesHandler(EventTouch::EventCode eventType, const st return 0; } -/// isTouchEnabled getter -bool Layer::isTouchEnabled() const -{ - return _touchEnabled; -} - -/// isTouchEnabled setter -void Layer::setTouchEnabled(bool enabled) -{ - if (_touchEnabled != enabled) - { - _touchEnabled = enabled; - if (_running) - { - if (enabled) - { - this->addTouchListener(); - } - else - { - EventDispatcher::getInstance()->removeEventListener(_touchListener); - _touchListener = nullptr; - } - } - } -} - -void Layer::setTouchMode(Touch::DispatchMode mode) -{ - if(_touchMode != mode) - { - _touchMode = mode; - - if( _touchEnabled) - { - setTouchEnabled(false); - setTouchEnabled(true); - } - } -} - -void Layer::setSwallowsTouches(bool swallowsTouches) -{ - if (_swallowsTouches != swallowsTouches) - { - _swallowsTouches = swallowsTouches; - - if( _touchEnabled) - { - setTouchEnabled(false); - setTouchEnabled(true); - } - } -} - -Touch::DispatchMode Layer::getTouchMode() const -{ - return _touchMode; -} - -bool Layer::isSwallowsTouches() const -{ - return _swallowsTouches; -} - - - -/// isAccelerometerEnabled getter -bool Layer::isAccelerometerEnabled() const -{ - return _accelerometerEnabled; -} -/// isAccelerometerEnabled setter -void Layer::setAccelerometerEnabled(bool enabled) -{ - if (enabled != _accelerometerEnabled) - { - _accelerometerEnabled = enabled; - - Device::setAccelerometerEnabled(enabled); - - if (_running) - { - auto dispatcher = EventDispatcher::getInstance(); - dispatcher->removeEventListener(_accelerationListener); - _accelerationListener = nullptr; - - if (enabled) - { - _accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this); - } - } - } -} - - -void Layer::setAccelerometerInterval(double interval) { - if (_accelerometerEnabled) - { - if (_running) - { - Device::setAccelerometerInterval(interval); - } - } -} - - -void Layer::onAcceleration(Acceleration* pAccelerationValue, Event* event) -{ - CC_UNUSED_PARAM(pAccelerationValue); - - if(kScriptTypeNone != _scriptType) - { - BasicScriptData data(this,(void*)pAccelerationValue); - ScriptEvent event(kAccelerometerEvent,&data); - ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); - } -} - -void Layer::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event) -{ - CC_UNUSED_PARAM(keyCode); - CC_UNUSED_PARAM(event); -} - -void Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) -{ - CC_UNUSED_PARAM(event); - if(kScriptTypeNone != _scriptType) - { - KeypadScriptData data(keyCode, this); - ScriptEvent event(kKeypadEvent,&data); - ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); - } -} - -/// isKeyboardEnabled getter -bool Layer::isKeyboardEnabled() const -{ - return _keyboardEnabled; -} -/// isKeyboardEnabled setter -void Layer::setKeyboardEnabled(bool enabled) -{ - if (enabled != _keyboardEnabled) - { - _keyboardEnabled = enabled; - - auto dispatcher = EventDispatcher::getInstance(); - dispatcher->removeEventListener(_keyboardListener); - _keyboardListener = nullptr; - - if (enabled) - { - auto listener = EventListenerKeyboard::create(); - listener->onKeyPressed = CC_CALLBACK_2(Layer::onKeyPressed, this); - listener->onKeyReleased = CC_CALLBACK_2(Layer::onKeyReleased, this); - - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - _keyboardListener = listener; - } - } -} - -/// Callbacks -void Layer::onEnter() -{ - // register 'parent' nodes first - // since events are propagated in reverse order - if (_touchEnabled) - { - this->addTouchListener(); - } - - // then iterate over all the children - Node::onEnter(); - - // add this layer to concern the Accelerometer Sensor - if (_accelerometerEnabled) - { - auto dispatcher = EventDispatcher::getInstance(); - dispatcher->removeEventListener(_accelerationListener); - _accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this); - } -} - -void Layer::onExit() -{ - auto dispatcher = EventDispatcher::getInstance(); - - dispatcher->removeEventListener(_touchListener); - _touchListener = nullptr; - - // remove this layer from the delegates who concern Accelerometer Sensor - dispatcher->removeEventListener(_accelerationListener); - _accelerationListener = nullptr; - - // remove this layer from the delegates who concern the keypad msg - dispatcher->removeEventListener(_keyboardListener); - _keyboardListener = nullptr; - - Node::onExit(); -} - -void Layer::onEnterTransitionDidFinish() -{ - if (_accelerometerEnabled) - { - auto dispatcher = EventDispatcher::getInstance(); - dispatcher->removeEventListener(_accelerationListener); - _accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this); - } - - Node::onEnterTransitionDidFinish(); -} - -bool Layer::onTouchBegan(Touch *pTouch, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - return executeScriptTouchHandler(EventTouch::EventCode::BEGAN, pTouch) == 0 ? false : true; - } - - CC_UNUSED_PARAM(pTouch); - CC_UNUSED_PARAM(pEvent); - CCASSERT(false, "Layer#ccTouchBegan override me"); - return true; -} - -void Layer::onTouchMoved(Touch *pTouch, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchHandler(EventTouch::EventCode::MOVED, pTouch); - return; - } - - CC_UNUSED_PARAM(pTouch); - CC_UNUSED_PARAM(pEvent); -} - -void Layer::onTouchEnded(Touch *pTouch, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchHandler(EventTouch::EventCode::ENDED, pTouch); - return; - } - - CC_UNUSED_PARAM(pTouch); - CC_UNUSED_PARAM(pEvent); -} - -void Layer::onTouchCancelled(Touch *pTouch, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchHandler(EventTouch::EventCode::CANCELLED, pTouch); - return; - } - - CC_UNUSED_PARAM(pTouch); - CC_UNUSED_PARAM(pEvent); -} - -void Layer::onTouchesBegan(const std::vector& pTouches, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchesHandler(EventTouch::EventCode::BEGAN, pTouches); - return; - } - - CC_UNUSED_PARAM(pTouches); - CC_UNUSED_PARAM(pEvent); -} - -void Layer::onTouchesMoved(const std::vector& pTouches, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchesHandler(EventTouch::EventCode::MOVED, pTouches); - return; - } - - CC_UNUSED_PARAM(pTouches); - CC_UNUSED_PARAM(pEvent); -} - -void Layer::onTouchesEnded(const std::vector& pTouches, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchesHandler(EventTouch::EventCode::ENDED, pTouches); - return; - } - - CC_UNUSED_PARAM(pTouches); - CC_UNUSED_PARAM(pEvent); -} - -void Layer::onTouchesCancelled(const std::vector& pTouches, Event *pEvent) -{ - if (kScriptTypeNone != _scriptType) - { - executeScriptTouchesHandler(EventTouch::EventCode::CANCELLED, pTouches); - return; - } - - CC_UNUSED_PARAM(pTouches); - CC_UNUSED_PARAM(pEvent); -} - - #ifdef CC_USE_PHYSICS void Layer::addChild(Node* child) { diff --git a/cocos/2d/CCLayer.h b/cocos/2d/CCLayer.h index 0dad16ff21..09effe2fcd 100644 --- a/cocos/2d/CCLayer.h +++ b/cocos/2d/CCLayer.h @@ -46,10 +46,6 @@ NS_CC_BEGIN class TouchScriptHandlerEntry; -class EventListenerTouch; -class EventListenerKeyboard; -class EventListenerAcceleration; - // // Layer // @@ -86,22 +82,9 @@ public: CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesEnded(Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesCancelled(Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);} - // default implements are used to call script callback if exist - virtual bool onTouchBegan(Touch *touch, Event *event); - virtual void onTouchMoved(Touch *touch, Event *event); - virtual void onTouchEnded(Touch *touch, Event *event); - virtual void onTouchCancelled(Touch *touch, Event *event); - -// // default implements are used to call script callback if exist - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); - virtual void onTouchesEnded(const std::vector& touches, Event *event); - virtual void onTouchesCancelled(const std::vector&touches, Event *event); /** @deprecated Please override onAcceleration */ CC_DEPRECATED_ATTRIBUTE virtual void didAccelerate(Acceleration* accelerationValue) final {}; - - virtual void onAcceleration(Acceleration* acc, Event* event); /** If isTouchEnabled, this method is called onEnter. Override it to change the way Layer receives touch events. @@ -115,48 +98,13 @@ public: */ CC_DEPRECATED_ATTRIBUTE virtual void registerWithTouchDispatcher() final {}; - /** whether or not it will receive Touch events. - You can enable / disable touch events with this property. - Only the touches of this node will be affected. This "method" is not propagated to it's children. - @since v0.8.1 - */ - virtual bool isTouchEnabled() const; - virtual void setTouchEnabled(bool value); - - virtual void setTouchMode(Touch::DispatchMode mode); - virtual Touch::DispatchMode getTouchMode() const; - - /** swallowsTouches of the touch events. Default is true */ - virtual void setSwallowsTouches(bool swallowsTouches); - virtual bool isSwallowsTouches() const; - - /** whether or not it will receive Accelerometer events - You can enable / disable accelerometer events with this property. - @since v0.8.1 - */ - virtual bool isAccelerometerEnabled() const; - virtual void setAccelerometerEnabled(bool value); - virtual void setAccelerometerInterval(double interval); - - /** whether or not it will receive keyboard or keypad events - You can enable / disable accelerometer events with this property. - it's new in cocos2d-x - */ - - virtual bool isKeyboardEnabled() const; - virtual void setKeyboardEnabled(bool value); /** Please use onKeyPressed instead. */ virtual void keyPressed(int keyCode) final {}; /** Please use onKeyReleased instead. */ virtual void keyReleased(int keyCode) final {}; - - virtual void onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event); - virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event); - CC_DEPRECATED_ATTRIBUTE virtual bool isKeypadEnabled() const final { return isKeyboardEnabled(); }; - CC_DEPRECATED_ATTRIBUTE virtual void setKeypadEnabled(bool value) { setKeyboardEnabled(value); }; /** @deprecated Please override onKeyReleased and check the keycode of KeyboardEvent::KeyCode::Menu(KEY_BACKSPACE) instead. */ CC_DEPRECATED_ATTRIBUTE virtual void keyBackClicked() final {}; @@ -164,21 +112,6 @@ public: // // Overrides // - /** - * @js NA - * @lua NA - */ - virtual void onEnter() override; - /** - * @js NA - * @lua NA - */ - virtual void onExit() override; - /** - * @js NA - * @lua NA - */ - virtual void onEnterTransitionDidFinish() override; #ifdef CC_USE_PHYSICS virtual void addChild(Node* child) override; @@ -186,15 +119,6 @@ public: virtual void addChild(Node* child, int zOrder, int tag) override; #endif // CC_USE_PHYSICS -protected: - void addTouchListener(); - - bool _touchEnabled; - bool _accelerometerEnabled; - bool _keyboardEnabled; - EventListenerTouch* _touchListener; - EventListenerKeyboard* _keyboardListener; - EventListenerAcceleration* _accelerationListener; private: Touch::DispatchMode _touchMode; bool _swallowsTouches; diff --git a/cocos/2d/CCMenu.cpp b/cocos/2d/CCMenu.cpp index c0c10e9cdb..fc38405355 100644 --- a/cocos/2d/CCMenu.cpp +++ b/cocos/2d/CCMenu.cpp @@ -127,9 +127,6 @@ bool Menu::initWithArray(Array* pArrayOfItems) { if (Layer::init()) { - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); - setTouchEnabled(true); - _enabled = true; // menu in the center of the screen Size s = Director::getInstance()->getWinSize(); @@ -188,8 +185,15 @@ void Menu::onEnter() { Layer::onEnter(); - setTouchEnabled(true); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + auto eventDispatcher = EventDispatcher::getInstance(); + + auto touchListener = EventListenerTouchOneByOne::create(); + touchListener->onTouchBegan = CC_CALLBACK_2(Menu::onTouchBegan, this); + touchListener->onTouchMoved = CC_CALLBACK_2(Menu::onTouchMoved, this); + touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this); + touchListener->onTouchCancelled = CC_CALLBACK_2(Menu::onTouchCancelled, this); + + eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); } void Menu::onExit() diff --git a/cocos/2d/CCMenu.h b/cocos/2d/CCMenu.h index bd685786c4..a735d138db 100644 --- a/cocos/2d/CCMenu.h +++ b/cocos/2d/CCMenu.h @@ -119,10 +119,10 @@ public: virtual void addChild(Node * child, int zOrder) override; virtual void addChild(Node * child, int zOrder, int tag) override; - virtual bool onTouchBegan(Touch* touch, Event* event) override; - virtual void onTouchEnded(Touch* touch, Event* event) override; - virtual void onTouchCancelled(Touch* touch, Event* event) override; - virtual void onTouchMoved(Touch* touch, Event* event) override; + virtual bool onTouchBegan(Touch* touch, Event* event); + virtual void onTouchEnded(Touch* touch, Event* event); + virtual void onTouchCancelled(Touch* touch, Event* event); + virtual void onTouchMoved(Touch* touch, Event* event); virtual void onEnter() override; virtual void onExit() override; From cfaef2a01ab78140ce8ea67e24055be0e30cec90 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 12 Oct 2013 14:02:01 +0800 Subject: [PATCH 020/144] Adding onEnterHook, onXXXHook for Node. --- cocos/2d/CCNode.cpp | 25 +++++++++++++++ cocos/2d/CCNode.h | 6 +++- .../cocosbuilder/CCLayerLoader.cpp | 4 +-- .../cocostudio/CCInputDelegate.cpp | 4 +-- cocos/gui/UILayer.cpp | 15 ++++++--- .../GUI/CCControlExtension/CCControl.cpp | 15 +++++---- .../CCControlExtension/CCControlButton.cpp | 1 - .../CCControlColourPicker.cpp | 1 - .../CCControlExtension/CCControlHuePicker.cpp | 1 - .../CCControlPotentiometer.cpp | 2 -- .../CCControlSaturationBrightnessPicker.cpp | 1 - .../CCControlExtension/CCControlSlider.cpp | 1 - .../CCControlExtension/CCControlStepper.cpp | 2 -- .../CCControlExtension/CCControlSwitch.cpp | 1 - extensions/GUI/CCScrollView/CCScrollView.cpp | 32 ++++++++++++------- extensions/GUI/CCScrollView/CCScrollView.h | 5 --- .../AccelerometerTest/AccelerometerTest.cpp | 6 ++-- .../AccelerometerTest/AccelerometerTest.h | 2 +- .../Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h | 2 +- .../Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp | 17 ++++++++-- .../Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp | 9 +++++- .../Cpp/TestCpp/Classes/BugsTest/Bug-914.h | 4 +-- .../Cpp/TestCpp/Classes/BugsTest/BugsTest.h | 4 +-- .../ClickAndMoveTest/ClickAndMoveTest.cpp | 9 ++++-- .../ClickAndMoveTest/ClickAndMoveTest.h | 4 +-- .../ClippingNodeTest/ClippingNodeTest.cpp | 18 +++++++++-- .../ClippingNodeTest/ClippingNodeTest.h | 2 +- .../TestCpp/Classes/PhysicsTest/PhysicsTest.h | 4 +-- 28 files changed, 133 insertions(+), 64 deletions(-) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 2145829c34..33f9963526 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -136,6 +136,11 @@ Node::Node(void) , _physicsBody(nullptr) #endif { + onEnterHook = nullptr; + onEnterTransitionDidFinishHook = nullptr; + onExitHook = nullptr; + onExitTransitionDidStartHook = nullptr; + // set default scheduler and actionManager Director *director = Director::getInstance(); _actionManager = director->getActionManager(); @@ -945,6 +950,11 @@ void Node::onEnter() ScriptEvent scriptEvent(kNodeEvent,(void*)&data); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); } + + if (onEnterHook) + { + onEnterHook(); + } } void Node::onEnterTransitionDidFinish() @@ -960,10 +970,20 @@ void Node::onEnterTransitionDidFinish() ScriptEvent scriptEvent(kNodeEvent,(void*)&data); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); } + + if (onEnterTransitionDidFinishHook) + { + onEnterTransitionDidFinishHook(); + } } void Node::onExitTransitionDidStart() { + if (onExitTransitionDidStartHook) + { + onExitTransitionDidStartHook(); + } + arrayMakeObjectsPerformSelector(_children, onExitTransitionDidStart, Node*); if (_scriptType != kScriptTypeNone) { @@ -976,6 +996,11 @@ void Node::onExitTransitionDidStart() void Node::onExit() { + if (onExitHook) + { + onExitHook(); + } + this->pauseSchedulerAndActions(); _running = false; diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index ca0529756b..ca0a8eca96 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -928,6 +928,7 @@ public: * @lua NA */ virtual void onEnter(); + std::function onEnterHook; /** Event callback that is invoked when the Node enters in the 'stage'. * If the Node enters the 'stage' with a transition, this event is called when the transition finishes. @@ -936,6 +937,7 @@ public: * @lua NA */ virtual void onEnterTransitionDidFinish(); + std::function onEnterTransitionDidFinishHook; /** * Event callback that is invoked every time the Node leaves the 'stage'. @@ -946,6 +948,7 @@ public: * @lua NA */ virtual void onExit(); + std::function onExitHook; /** * Event callback that is called every time the Node leaves the 'stage'. @@ -954,7 +957,8 @@ public: * @lua NA */ virtual void onExitTransitionDidStart(); - + std::function onExitTransitionDidStartHook; + /// @} end of event callbacks. diff --git a/cocos/editor-support/cocosbuilder/CCLayerLoader.cpp b/cocos/editor-support/cocosbuilder/CCLayerLoader.cpp index f13cf610f6..ebca5a8839 100644 --- a/cocos/editor-support/cocosbuilder/CCLayerLoader.cpp +++ b/cocos/editor-support/cocosbuilder/CCLayerLoader.cpp @@ -14,9 +14,9 @@ namespace cocosbuilder { void LayerLoader::onHandlePropTypeCheck(Node * pNode, Node * pParent, const char * pPropertyName, bool pCheck, CCBReader * ccbReader) { if(strcmp(pPropertyName, PROPERTY_TOUCH_ENABLED) == 0) { - ((Layer *)pNode)->setTouchEnabled(pCheck); +// FIXME: ((Layer *)pNode)->setTouchEnabled(pCheck); } else if(strcmp(pPropertyName, PROPERTY_ACCELEROMETER_ENABLED) == 0) { - ((Layer *)pNode)->setAccelerometerEnabled(pCheck); +// FIXME: ((Layer *)pNode)->setAccelerometerEnabled(pCheck); } else if(strcmp(pPropertyName, PROPERTY_MOUSE_ENABLED) == 0) { // TODO XXX CCLOG("The property '%s' is not supported!", PROPERTY_MOUSE_ENABLED); diff --git a/cocos/editor-support/cocostudio/CCInputDelegate.cpp b/cocos/editor-support/cocostudio/CCInputDelegate.cpp index 9f4fd46a8d..968645bc4e 100644 --- a/cocos/editor-support/cocostudio/CCInputDelegate.cpp +++ b/cocos/editor-support/cocostudio/CCInputDelegate.cpp @@ -112,7 +112,7 @@ void InputDelegate::setTouchEnabled(bool enabled) { if( _touchMode == Touch::DispatchMode::ALL_AT_ONCE ) { // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ALL_AT_ONCE); + auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = CC_CALLBACK_2(InputDelegate::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(InputDelegate::onTouchesMoved, this); @@ -123,7 +123,7 @@ void InputDelegate::setTouchEnabled(bool enabled) _touchListener = listener; } else { // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(InputDelegate::onTouchBegan, this); diff --git a/cocos/gui/UILayer.cpp b/cocos/gui/UILayer.cpp index f92d73c9c7..891301bf5b 100644 --- a/cocos/gui/UILayer.cpp +++ b/cocos/gui/UILayer.cpp @@ -74,15 +74,22 @@ UILayer* UILayer::create(void) void UILayer::onEnter() { - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); - setTouchEnabled(true); CCLayer::onEnter(); + auto listener = EventListenerTouchOneByOne::create(); + listener->setSwallowTouches(true); + + listener->onTouchBegan = CC_CALLBACK_2(UILayer::onTouchBegan, this); + listener->onTouchMoved = CC_CALLBACK_2(UILayer::onTouchMoved, this); + listener->onTouchEnded = CC_CALLBACK_2(UILayer::onTouchEnded, this); + listener->onTouchCancelled = CC_CALLBACK_2(UILayer::onTouchCancelled, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); } void UILayer::onExit() { - setTouchEnabled(false); +// setTouchEnabled(false); CCLayer::onExit(); } @@ -164,4 +171,4 @@ void UILayer::onTouchCancelled(Touch *pTouch, Event *pEvent) _inputManager->onTouchCancelled(pTouch); } -} \ No newline at end of file +} diff --git a/extensions/GUI/CCControlExtension/CCControl.cpp b/extensions/GUI/CCControlExtension/CCControl.cpp index d12859b703..1419edbc36 100644 --- a/extensions/GUI/CCControlExtension/CCControl.cpp +++ b/extensions/GUI/CCControlExtension/CCControl.cpp @@ -93,17 +93,18 @@ Control::~Control() CC_SAFE_RELEASE(_dispatchTable); } -////Menu - Events -//void Control::registerWithTouchDispatcher() -//{ -// Director::getInstance()->getTouchDispatcher()->addTargetedDelegate(this, getTouchPriority(), true); -//} - void Control::onEnter() { Layer::onEnter(); - this->setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + auto dispatcher = EventDispatcher::getInstance(); + auto touchListener = EventListenerTouchOneByOne::create(); + touchListener->onTouchBegan = CC_CALLBACK_2(Control::onTouchBegan, this); + touchListener->onTouchMoved = CC_CALLBACK_2(Control::onTouchMoved, this); + touchListener->onTouchEnded = CC_CALLBACK_2(Control::onTouchEnded, this); + touchListener->onTouchCancelled = CC_CALLBACK_2(Control::onTouchCancelled, this); + + dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); } void Control::onExit() diff --git a/extensions/GUI/CCControlExtension/CCControlButton.cpp b/extensions/GUI/CCControlExtension/CCControlButton.cpp index 4f889f7066..5e4e102aba 100644 --- a/extensions/GUI/CCControlExtension/CCControlButton.cpp +++ b/extensions/GUI/CCControlExtension/CCControlButton.cpp @@ -96,7 +96,6 @@ bool ControlButton::initWithLabelAndBackgroundSprite(Node* node, Scale9Sprite* b this->setTitleLabelDispatchTable(Dictionary::create()); this->setBackgroundSpriteDispatchTable(Dictionary::create()); - setTouchEnabled(true); _isPushed = false; _zoomOnTouchDown = true; diff --git a/extensions/GUI/CCControlExtension/CCControlColourPicker.cpp b/extensions/GUI/CCControlExtension/CCControlColourPicker.cpp index 18da7f0abf..082c929bea 100644 --- a/extensions/GUI/CCControlExtension/CCControlColourPicker.cpp +++ b/extensions/GUI/CCControlExtension/CCControlColourPicker.cpp @@ -54,7 +54,6 @@ bool ControlColourPicker::init() { if (Control::init()) { - setTouchEnabled(true); // Cache the sprites SpriteFrameCache::getInstance()->addSpriteFramesWithFile("extensions/CCControlColourPickerSpriteSheet.plist"); diff --git a/extensions/GUI/CCControlExtension/CCControlHuePicker.cpp b/extensions/GUI/CCControlExtension/CCControlHuePicker.cpp index 48230e84ab..6e5600edf0 100644 --- a/extensions/GUI/CCControlExtension/CCControlHuePicker.cpp +++ b/extensions/GUI/CCControlExtension/CCControlHuePicker.cpp @@ -62,7 +62,6 @@ bool ControlHuePicker::initWithTargetAndPos(Node* target, Point pos) { if (Control::init()) { - setTouchEnabled(true); // Add background and slider sprites this->setBackground(ControlUtils::addSpriteToTargetWithPosAndAnchor("huePickerBackground.png", target, pos, Point(0.0f, 0.0f))); this->setSlider(ControlUtils::addSpriteToTargetWithPosAndAnchor("colourPicker.png", target, pos, Point(0.5f, 0.5f))); diff --git a/extensions/GUI/CCControlExtension/CCControlPotentiometer.cpp b/extensions/GUI/CCControlExtension/CCControlPotentiometer.cpp index 3a28593955..ab3fccdb74 100644 --- a/extensions/GUI/CCControlExtension/CCControlPotentiometer.cpp +++ b/extensions/GUI/CCControlExtension/CCControlPotentiometer.cpp @@ -76,8 +76,6 @@ bool ControlPotentiometer::initWithTrackSprite_ProgressTimer_ThumbSprite(Sprite* { if (Control::init()) { - setTouchEnabled(true); - setProgressTimer(progressTimer); setThumbSprite(thumbSprite); thumbSprite->setPosition(progressTimer->getPosition()); diff --git a/extensions/GUI/CCControlExtension/CCControlSaturationBrightnessPicker.cpp b/extensions/GUI/CCControlExtension/CCControlSaturationBrightnessPicker.cpp index 3252de4c94..4d59fca00d 100644 --- a/extensions/GUI/CCControlExtension/CCControlSaturationBrightnessPicker.cpp +++ b/extensions/GUI/CCControlExtension/CCControlSaturationBrightnessPicker.cpp @@ -60,7 +60,6 @@ bool ControlSaturationBrightnessPicker::initWithTargetAndPos(Node* target, Point { if (Control::init()) { - setTouchEnabled(true); // Add background and slider sprites _background=ControlUtils::addSpriteToTargetWithPosAndAnchor("colourPickerBackground.png", target, pos, Point(0.0f, 0.0f)); _overlay=ControlUtils::addSpriteToTargetWithPosAndAnchor("colourPickerOverlay.png", target, pos, Point(0.0f, 0.0f)); diff --git a/extensions/GUI/CCControlExtension/CCControlSlider.cpp b/extensions/GUI/CCControlExtension/CCControlSlider.cpp index 1ba96962b6..bafd327d69 100644 --- a/extensions/GUI/CCControlExtension/CCControlSlider.cpp +++ b/extensions/GUI/CCControlExtension/CCControlSlider.cpp @@ -84,7 +84,6 @@ ControlSlider* ControlSlider::create(Sprite * backgroundSprite, Sprite* pogressS CCASSERT(thumbSprite, "Thumb sprite must be not nil"); ignoreAnchorPointForPosition(false); - setTouchEnabled(true); this->setBackgroundSprite(backgroundSprite); this->setProgressSprite(progressSprite); diff --git a/extensions/GUI/CCControlExtension/CCControlStepper.cpp b/extensions/GUI/CCControlExtension/CCControlStepper.cpp index 7aee633bda..4c4df49589 100644 --- a/extensions/GUI/CCControlExtension/CCControlStepper.cpp +++ b/extensions/GUI/CCControlExtension/CCControlStepper.cpp @@ -74,8 +74,6 @@ bool ControlStepper::initWithMinusSpriteAndPlusSprite(Sprite *minusSprite, Sprit CCASSERT(minusSprite, "Minus sprite must be not nil"); CCASSERT(plusSprite, "Plus sprite must be not nil"); - setTouchEnabled(true); - // Set the default values _autorepeat = true; _continuous = true; diff --git a/extensions/GUI/CCControlExtension/CCControlSwitch.cpp b/extensions/GUI/CCControlExtension/CCControlSwitch.cpp index dcf7fd555e..fe67a3f905 100644 --- a/extensions/GUI/CCControlExtension/CCControlSwitch.cpp +++ b/extensions/GUI/CCControlExtension/CCControlSwitch.cpp @@ -346,7 +346,6 @@ bool ControlSwitch::initWithMaskSprite(Sprite *maskSprite, Sprite * onSprite, Sp CCASSERT(offSprite, "offSprite must not be nil."); CCASSERT(thumbSprite, "thumbSprite must not be nil."); - setTouchEnabled(true); _on = true; _switchSprite = new ControlSwitchSprite(); diff --git a/extensions/GUI/CCScrollView/CCScrollView.cpp b/extensions/GUI/CCScrollView/CCScrollView.cpp index ee6a416310..e5f4c0503e 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.cpp +++ b/extensions/GUI/CCScrollView/CCScrollView.cpp @@ -109,8 +109,16 @@ bool ScrollView::initWithViewSize(Size size, Node *container/* = NULL*/) this->setViewSize(size); - setTouchEnabled(true); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + this->onEnterHook = [this]() { + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = CC_CALLBACK_2(ScrollView::onTouchBegan, this); + listener->onTouchMoved = CC_CALLBACK_2(ScrollView::onTouchMoved, this); + listener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this); + listener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this); + + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; _touches.reserve(EventTouch::MAX_TOUCHES); @@ -177,16 +185,16 @@ void ScrollView::resume(Object* sender) _container->resumeSchedulerAndActions(); } -void ScrollView::setTouchEnabled(bool e) -{ - Layer::setTouchEnabled(e); - if (!e) - { - _dragging = false; - _touchMoved = false; - _touches.clear(); - } -} +//void ScrollView::setTouchEnabled(bool e) +//{ +// Layer::setTouchEnabled(e); +// if (!e) +// { +// _dragging = false; +// _touchMoved = false; +// _touches.clear(); +// } +//} void ScrollView::setContentOffset(Point offset, bool animated/* = false*/) { diff --git a/extensions/GUI/CCScrollView/CCScrollView.h b/extensions/GUI/CCScrollView/CCScrollView.h index 5b002887ee..42b9d78425 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.h +++ b/extensions/GUI/CCScrollView/CCScrollView.h @@ -216,10 +216,6 @@ public: virtual void onTouchCancelled(Touch *touch, Event *event); // Overrides -// virtual bool ccTouchBegan(Touch *pTouch, Event *pEvent) override; -// virtual void ccTouchMoved(Touch *pTouch, Event *pEvent) override; -// virtual void ccTouchEnded(Touch *pTouch, Event *pEvent) override; -// virtual void ccTouchCancelled(Touch *pTouch, Event *pEvent) override; virtual void setContentSize(const Size & size) override; virtual const Size& getContentSize() const override; /** @@ -230,7 +226,6 @@ public: virtual void addChild(Node * child, int zOrder, int tag) override; virtual void addChild(Node * child, int zOrder) override; virtual void addChild(Node * child) override; - void setTouchEnabled(bool e) override; protected: /** diff --git a/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp b/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp index 4f06570737..ada7540cc6 100644 --- a/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp +++ b/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp @@ -32,8 +32,10 @@ void AccelerometerTest::onEnter() { Layer::onEnter(); - setAccelerometerEnabled(true); - + auto dispatcher = EventDispatcher::getInstance(); + + auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(AccelerometerTest::onAcceleration, this)); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto label = LabelTTF::create(title().c_str(), "Arial", 32); addChild(label, 1); diff --git a/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.h b/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.h index f1524be1ab..7e4cc7edf1 100644 --- a/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.h +++ b/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.h @@ -15,7 +15,7 @@ public: AccelerometerTest(void); ~AccelerometerTest(void); - virtual void onAcceleration(Acceleration* acc, Event* event) override; + virtual void onAcceleration(Acceleration* acc, Event* event); virtual std::string title(); virtual void onEnter(); diff --git a/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h b/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h index 9e04493964..480d572f7a 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h +++ b/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h @@ -21,7 +21,7 @@ public: void addNewSpriteAtPosition(Point p); void update(float dt); - virtual void onTouchesEnded(const std::vector& touches, Event* event) override; + virtual void onTouchesEnded(const std::vector& touches, Event* event); //CREATE_NODE(Box2DTestLayer); } ; diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp index 2f03948186..a86859ebb1 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp @@ -19,7 +19,13 @@ bool Bug624Layer::init() label->setPosition(Point(size.width/2, size.height/2)); addChild(label); - setAccelerometerEnabled(true); + + this->onEnterHook = [this](){ + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer::onAcceleration, this)); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; + schedule(schedule_selector(Bug624Layer::switchLayer), 5.0f); return true; @@ -56,7 +62,14 @@ bool Bug624Layer2::init() label->setPosition(Point(size.width/2, size.height/2)); addChild(label); - setAccelerometerEnabled(true); + + this->onEnterHook = [this](){ + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer2::onAcceleration, this)); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; + + schedule(schedule_selector(Bug624Layer2::switchLayer), 5.0f); return true; diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp index 64665fd18f..337d9b1006 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp @@ -30,7 +30,14 @@ bool Bug914Layer::init() // Apple recommends to re-assign "self" with the "super" return value if (BugsTestBaseLayer::init()) { - setTouchEnabled(true); + this->onEnterHook = [this](){ + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(Bug914Layer::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(Bug914Layer::onTouchesMoved, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; + // ask director the the window size auto size = Director::getInstance()->getWinSize(); LayerColor *layer; diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h index af5f8c1bdd..41ee2c25c8 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h @@ -9,8 +9,8 @@ public: static Scene* scene(); virtual bool init(); - virtual void onTouchesMoved(const std::vector& touches, Event * event) override; - virtual void onTouchesBegan(const std::vector& touches, Event * event) override; + virtual void onTouchesMoved(const std::vector& touches, Event * event); + virtual void onTouchesBegan(const std::vector& touches, Event * event); void restart(Object* sender); CREATE_FUNC(Bug914Layer); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h index 8ea7d2bbbd..88de62b0a1 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h +++ b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h @@ -8,8 +8,8 @@ class BugsTestMainLayer : public Layer public: virtual void onEnter(); - virtual void onTouchesBegan(const std::vector& touches, Event *event) override; - virtual void onTouchesMoved(const std::vector&touches, Event *event) override; + virtual void onTouchesBegan(const std::vector& touches, Event *event); + virtual void onTouchesMoved(const std::vector&touches, Event *event); protected: Point _beginPos; diff --git a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp index 4215b8810d..5a87658f35 100644 --- a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp @@ -17,8 +17,13 @@ void ClickAndMoveTestScene::runThisTest() MainLayer::MainLayer() { - setTouchEnabled(true); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + this->onEnterHook = [this](){ + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan, this); + listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; auto sprite = Sprite::create(s_pathGrossini); diff --git a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h index f223d0b5ee..7cb8f7a3b4 100644 --- a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h +++ b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h @@ -13,8 +13,8 @@ class MainLayer : public Layer { public: MainLayer(); - virtual bool onTouchBegan(Touch* touch, Event *event) override; - virtual void onTouchEnded(Touch* touch, Event *event) override; + virtual bool onTouchBegan(Touch* touch, Event *event); + virtual void onTouchEnded(Touch* touch, Event *event); }; #endif diff --git a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp index 51e9791097..fcde7712ad 100644 --- a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp @@ -448,8 +448,13 @@ void HoleDemo::setup() _outerClipper->addChild(holesClipper); this->addChild(_outerClipper); - - this->setTouchEnabled(true); + + this->onEnterHook = [this](){ + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(HoleDemo::onTouchesBegan, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; } void HoleDemo::pokeHoleAtPoint(Point point) @@ -526,7 +531,14 @@ void ScrollViewDemo::setup() _scrolling = false; - this->setTouchEnabled(true); + this->onEnterHook = [this](){ + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(ScrollViewDemo::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(ScrollViewDemo::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(ScrollViewDemo::onTouchesEnded, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + }; } void ScrollViewDemo::onTouchesBegan(const std::vector& touches, Event *event) diff --git a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h index 11445bf406..0cb0c21d6d 100644 --- a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h +++ b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h @@ -98,7 +98,7 @@ public: virtual std::string title(); virtual std::string subtitle(); void pokeHoleAtPoint(Point point); - virtual void onTouchesBegan(const std::vector& touches, Event *event) override; + virtual void onTouchesBegan(const std::vector& touches, Event *event); private: ClippingNode* _outerClipper; Node* _holes; diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index 0c685ef98e..7dbb28617b 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -57,8 +57,8 @@ public: void onEnter() override; std::string subtitle() override; - void onTouchesEnded(const std::vector& touches, Event* event) override; - void onAcceleration(Acceleration* acc, Event* event) override; + void onTouchesEnded(const std::vector& touches, Event* event); + void onAcceleration(Acceleration* acc, Event* event); }; class PhysicsDemoLogoSmash : public PhysicsDemo From f7e2c63230d8d3dde81baba0578d8aab199f0fed Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 21 Oct 2013 17:22:42 +0800 Subject: [PATCH 021/144] Refactor event dispatcher. Remove non-node relative member variables. --- cocos/2d/CCDirector.cpp | 2 - cocos/2d/CCEventDispatcher.cpp | 185 +++++++++++++++++++++++++++++---- cocos/2d/CCEventDispatcher.h | 43 +++++++- cocos/2d/CCEventListener.h | 2 +- cocos/2d/CCNode.cpp | 23 +--- cocos/2d/CCNode.h | 21 +--- 6 files changed, 210 insertions(+), 66 deletions(-) diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index 8d1d8cb5df..9dc388ea11 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -229,8 +229,6 @@ void Director::setGLDefaultValues() // Draw the Scene void Director::drawScene() { - Node::resetEventPriorityIndex(); - // calculate "global" dt calculateDeltaTime(); diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 0e596b788a..57a8d5ffde 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -59,10 +59,156 @@ private: NS_CC_BEGIN static EventDispatcher* g_instance = nullptr; +static int s_eventPriorityIndex = 0; + +void EventDispatcher::visitNode(Node* node) +{ + int i = 0; + int childrenCount = node->_children ? node->_children->count() : 0; + + if(childrenCount > 0) + { + Node* child = nullptr; + // visit children zOrder < 0 + for( ; i < childrenCount; i++ ) + { + child = static_cast( node->_children->getObjectAtIndex(i) ); + + if ( child && child->_ZOrder < 0 ) + visitNode(child); + else + break; + } + + node->_eventPriority = ++s_eventPriorityIndex; + + for( ; i < childrenCount; i++ ) + { + child = static_cast( node->_children->getObjectAtIndex(i) ); + if (child) + visitNode(child); + } + } + else + { + node->_eventPriority = ++s_eventPriorityIndex; + } +} + +EventDispatcher::EventListenerItem::EventListenerItem() +: fixedPriority(0) +, listener(nullptr) +, node(nullptr) +{ + +} EventDispatcher::EventListenerItem::~EventListenerItem() { - CC_SAFE_RELEASE(this->node); +} + +EventDispatcher::EventListenerItemVector::EventListenerItemVector() +: _sceneGraphItems(nullptr) +, _fixedItems(nullptr) +{ +} + +EventDispatcher::EventListenerItemVector::~EventListenerItemVector() +{ + CC_SAFE_DELETE(_sceneGraphItems); + CC_SAFE_DELETE(_fixedItems); +} + +size_t EventDispatcher::EventListenerItemVector::size() const +{ + size_t ret = 0; + if (_sceneGraphItems) + ret += _sceneGraphItems->size(); + if (_fixedItems) + ret += _fixedItems->size(); + + return ret; +} + +bool EventDispatcher::EventListenerItemVector::empty() const +{ + return (_sceneGraphItems == nullptr || _sceneGraphItems->empty()) + && (_fixedItems == nullptr || _fixedItems->empty()); +} + +void EventDispatcher::EventListenerItemVector::iterate(IterateCallback cb, EventDispatcher::EventListenerItemVector::IterateMode mode/* = IterateMode::ALL*/) +{ + auto loop = [&cb](std::vector* items) -> bool { + for (auto iter = items->begin(); iter != items->end(); ++iter) + { + if (cb(iter, items)) + return false; + } + return true; + }; + + switch (mode) + { + case IterateMode::FIXED_PRIORITY_LESS_THAN_0: + loop(_lt0); + break; + case IterateMode::SCENE_GRAPH_PRIORITY: + loop(_eq0); + break; + case IterateMode::FIXED_PRIORITY_GREATER_THAN_0: + loop(_gt0); + break; + case IterateMode::ALL: + { + if (!loop(_lt0)) return; + if (!loop(_eq0)) return; + if (!loop(_gt0)) return; + } + default: + break; + } +} + +void EventDispatcher::EventListenerItemVector::push_back(EventDispatcher::EventListenerItem* item) +{ + if (item->fixedPriority == 0) + { + if (_sceneGraphItems == nullptr) + { + _sceneGraphItems = new std::vector(); + _sceneGraphItems->reserve(100); + } + + _sceneGraphItems->push_back(item); + } + else + { + if (_fixedItems == nullptr) + { + _fixedItems = new std::vector(); + _fixedItems->reserve(100); + } + + _fixedItems->push_back(item); + } +} + +void EventDispatcher::EventListenerItemVector::remove(EventDispatcher::EventListenerItem* item) +{ + if (item->fixedPriority < 0) + { + CCASSERT(_lt0, "vector invaild"); + + } + else if (item->fixedPriority == 0) + { + CCASSERT(_eq0, "vector invaild"); + + } + else + { + CCASSERT(_gt0, "vector invalid"); + } } EventDispatcher::EventDispatcher() @@ -96,13 +242,13 @@ void EventDispatcher::addEventListenerWithItem(EventListenerItem* item) { if (_inDispatch == 0) { - std::vector* listenerList = nullptr; + EventListenerItemVector* listenerList = nullptr; auto iter = _listeners.find(item->listener->_type); if (iter == _listeners.end()) { - listenerList = new std::vector(); - listenerList->reserve(100); + listenerList = new EventListenerItemVector(); +// listenerList->reserve(100); _listeners.insert(std::make_pair(item->listener->_type, listenerList)); } else @@ -110,7 +256,7 @@ void EventDispatcher::addEventListenerWithItem(EventListenerItem* item) listenerList = iter->second; } - listenerList->insert(listenerList->begin(), item); + listenerList->push_back(item); setDirtyForEventType(item->listener->_type, true); } @@ -169,32 +315,35 @@ void EventDispatcher::removeEventListener(EventListener* listener) for (auto iter = _listeners.begin(); iter != _listeners.end();) { - for (auto itemIter = iter->second->begin(); itemIter != iter->second->end(); ++itemIter) - { - if ((*itemIter)->listener == listener) + iter->second->iterate([&](std::vector::iterator itemIt, std::vector* current) -> bool { + + auto item = *itemIt; + if (item->listener == listener) { CC_SAFE_RETAIN(listener); - (*itemIter)->listener->_isRegistered = false; - if ((*itemIter)->node != nullptr) + item->listener->_isRegistered = false; + if (item->node != nullptr) { - (*itemIter)->node->dissociateEventListener(listener); + item->node->dissociateEventListener(listener); } - (*itemIter)->listener->release(); + item->listener->release(); if (_inDispatch == 0) { - delete (*itemIter); - iter->second->erase(itemIter); + current->erase(itemIt); + delete item; } else { - (*itemIter)->listener = nullptr; + item->listener = nullptr; } - + isFound = true; - break; + return false; } - } + + return true; + }); if (iter->second->empty()) { diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 06b6e430c7..04191ea6d8 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -100,23 +100,58 @@ public: */ void dispatchEvent(Event* event, bool forceSortListeners = false); + void sortSceneGraphListeners(const std::string& eventType); + void setDirtyForEventType(const std::string& eventType, bool isDirty); bool isDirtyForEventType(const std::string& eventType); + void visitNode(Node* node); + public: /** Destructor of EventDispatcher */ ~EventDispatcher(); private: + struct EventListenerItem { - int fixedPriority; // The higher the number, the higher the priority - Node* node; // Weak reference. + int fixedPriority; // The higher the number, the higher the priority, 0 is for scene graph base priority. + Node* node; // Weak reference. EventListener* listener; + + EventListenerItem(); ~EventListenerItem(); }; + + class EventListenerItemVector + { + public: + EventListenerItemVector(); + ~EventListenerItemVector(); + size_t size() const; + bool empty() const; + + enum class IterateMode + { + FIXED_PRIORITY_LESS_THAN_0, + SCENE_GRAPH_PRIORITY, + FIXED_PRIORITY_GREATER_THAN_0, + ALL + }; + + typedef std::function::iterator, std::vector*)> IterateCallback; + + void iterate(IterateCallback cb, IterateMode mode = IterateMode::ALL); + void push_back(EventListenerItem* item); + void remove(EventListenerItem* item); + + private: + std::vector* _fixedItems; + std::vector* _sceneGraphItems; + }; + /** Constructor of EventDispatcher */ EventDispatcher(); @@ -127,7 +162,7 @@ private: void dispatchTouchEvent(EventTouch* event); /** Gets event the listener list for the event type. */ - std::vector* getListenerItemsForType(const std::string& eventType); + EventListenerItemVector* getListenerItemsForType(const std::string& eventType); /** Sorts the listeners of specified type by priority */ void sortAllEventListenerItemsForType(const std::string& eventType); @@ -142,7 +177,7 @@ private: /** * Listeners map. */ - std::map*> _listeners; + std::map _listeners; /// Priority dirty flag std::map _priorityDirtyFlagMap; diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index 559cf21739..982531416c 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -39,7 +39,7 @@ class Event; /** * The base class of event listener. * If you need custom listener which with different callback, you need to inherit this class. - * For instance, you could refer to AccelerationEventListener, KeyboardEventListener or TouchEventListener, CustomEventListener. + * For instance, you could refer to EventListenerAcceleration, EventListenerKeyboard, EventListenerTouchOneByOne, EventListenerCustom. */ class EventListener : public Object { diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 33f9963526..aad3d3fe6d 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -89,10 +89,10 @@ bool nodeComparisonLess(Object* p1, Object* p2) // XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered. static int s_globalOrderOfArrival = 1; -int Node::_globalEventPriorityIndex = 0; Node::Node(void) -: _rotationX(0.0f) +: _eventPriority(0) +, _rotationX(0.0f) , _rotationY(0.0f) , _scaleX(1.0f) , _scaleY(1.0f) @@ -130,8 +130,6 @@ Node::Node(void) , _isTransitionFinished(false) , _updateScriptHandler(0) , _componentContainer(NULL) -, _eventPriority(0) -, _oldEventPriority(0) #ifdef CC_USE_PHYSICS , _physicsBody(nullptr) #endif @@ -864,7 +862,6 @@ void Node::visit() } // self draw this->draw(); - updateEventPriorityIndex(); for( ; i < _children->count(); i++ ) { @@ -876,7 +873,6 @@ void Node::visit() else { this->draw(); - updateEventPriorityIndex(); } // reset for next frame @@ -1367,11 +1363,6 @@ void Node::removeAllComponents() _componentContainer->removeAll(); } -void Node::resetEventPriorityIndex() -{ - _globalEventPriorityIndex = 0; -} - void Node::associateEventListener(EventListener* listener) { _eventlisteners.insert(listener); @@ -1394,16 +1385,6 @@ void Node::removeAllEventListeners() } } -void Node::setDirtyForAllEventListeners() -{ - auto dispatcher = EventDispatcher::getInstance(); - - for (auto& listener : _eventlisteners) - { - dispatcher->setDirtyForEventType(listener->_type, true); - } -} - #ifdef CC_USE_PHYSICS void Node::setPhysicsBody(PhysicsBody* body) { diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index ca0a8eca96..b5c42f2301 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -1407,32 +1407,17 @@ private: friend class Director; friend class EventDispatcher; - int getEventPriority() const { return _eventPriority; }; - void associateEventListener(EventListener* listener); void dissociateEventListener(EventListener* listener); - static void resetEventPriorityIndex(); std::set _eventlisteners; + int _eventPriority; protected: - /// Upates event priority for this node. - inline void updateEventPriorityIndex() { - _oldEventPriority = _eventPriority; - _eventPriority = ++_globalEventPriorityIndex; - if (_oldEventPriority != _eventPriority) - { - setDirtyForAllEventListeners(); - } - }; - /// Removes all event listeners that associated with this node. void removeAllEventListeners(); - /// Sets dirty for event listener. - void setDirtyForAllEventListeners(); - /// lazy allocs void childrenAlloc(void); @@ -1509,10 +1494,6 @@ protected: ccScriptType _scriptType; ///< type of script binding, lua or javascript ComponentContainer *_componentContainer; ///< Dictionary of components - - int _eventPriority; ///< The scene graph based priority of event listener. - int _oldEventPriority; ///< The old scene graph based priority of event listener. - static int _globalEventPriorityIndex; ///< The index of global event priority. #ifdef CC_USE_PHYSICS PhysicsBody* _physicsBody; ///< the physicsBody the node have From 1f3863e787b97955796e23ad22c718ed142932c3 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 11:27:24 +0800 Subject: [PATCH 022/144] Event Dispatcher refactor commit. TestCpp could run. --- cocos/2d/CCEventDispatcher.cpp | 903 +++++++++++------- cocos/2d/CCEventDispatcher.h | 105 +- cocos/2d/CCEventListener.cpp | 1 + cocos/2d/CCEventListener.h | 12 +- cocos/2d/CCMenu.cpp | 2 + cocos/2d/CCNode.cpp | 61 +- cocos/2d/CCNode.h | 18 - cocos/2d/CCParticleBatchNode.cpp | 1 - cocos/2d/CCRenderTexture.cpp | 1 - cocos/2d/CCSpriteBatchNode.cpp | 1 - cocos/2d/platform/CCEGLViewProtocol.cpp | 6 +- .../editor-support/cocostudio/CCArmature.cpp | 1 - .../editor-support/cocostudio/CCBatchNode.cpp | 1 - extensions/GUI/CCScrollView/CCScrollView.cpp | 20 +- .../Classes/ActionsTest/ActionsTest.cpp | 2 +- .../Classes/Box2DTestBed/Box2dView.cpp | 20 +- .../TestCpp/Classes/Box2DTestBed/Box2dView.h | 3 +- .../Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp | 16 +- .../Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp | 12 +- .../Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp | 2 +- .../Classes/ChipmunkTest/ChipmunkTest.cpp | 4 +- .../Classes/ChipmunkTest/ChipmunkTest.h | 4 +- .../ClickAndMoveTest/ClickAndMoveTest.cpp | 12 +- .../ClippingNodeTest/ClippingNodeTest.cpp | 24 +- .../CocosDenshionTest/CocosDenshionTest.cpp | 4 +- .../Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp | 2 +- .../Cpp/TestCpp/Classes/CurlTest/CurlTest.h | 2 +- .../CocoStudioArmatureTest/ArmatureScene.cpp | 6 +- .../CocoStudioArmatureTest/ArmatureScene.h | 2 +- .../Classes/ExtensionsTest/ExtensionsTest.cpp | 2 +- .../Classes/KeyboardTest/KeyboardTest.cpp | 2 +- .../TestCpp/Classes/KeypadTest/KeypadTest.cpp | 2 +- .../TestCpp/Classes/KeypadTest/KeypadTest.h | 2 +- .../TestCpp/Classes/LabelTest/LabelTest.cpp | 2 +- .../Classes/LabelTest/LabelTestNew.cpp | 2 +- .../TestCpp/Classes/LayerTest/LayerTest.cpp | 4 +- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp | 18 +- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.h | 1 + .../MotionStreakTest/MotionStreakTest.cpp | 2 +- .../Classes/MutiTouchTest/MutiTouchTest.cpp | 2 +- .../NewEventDispatcherTest.cpp | 6 +- .../Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp | 2 +- .../Classes/ParallaxTest/ParallaxTest.cpp | 2 +- .../Classes/ParticleTest/ParticleTest.cpp | 2 +- .../PerformanceTouchesTest.cpp | 14 +- .../PerformanceTest/PerformanceTouchesTest.h | 16 +- .../Classes/PhysicsTest/PhysicsTest.cpp | 4 +- .../RenderTextureTest/RenderTextureTest.cpp | 6 +- .../SpriteTest/SpriteTest.cpp.REMOVED.git-id | 2 +- .../Classes/TextInputTest/TextInputTest.cpp | 4 +- .../Classes/TileMapTest/TileMapTest.cpp | 2 +- .../TestCpp/Classes/TouchesTest/Paddle.cpp | 2 +- samples/Cpp/TestCpp/Classes/controller.cpp | 4 +- 53 files changed, 763 insertions(+), 590 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 57a8d5ffde..7933a5edd6 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -31,7 +31,7 @@ #include -#define DUMP_LISTENER_ITEM_PRIORITY_INFO 0 +#define DUMP_LISTENER_ITEM_PRIORITY_INFO 1 namespace { @@ -61,155 +61,156 @@ NS_CC_BEGIN static EventDispatcher* g_instance = nullptr; static int s_eventPriorityIndex = 0; -void EventDispatcher::visitNode(Node* node) +void EventDispatcher::visitTarget(Node* node) { + // Reset priority index + s_eventPriorityIndex = 0; + _nodePriorityMap.clear(); + int i = 0; - int childrenCount = node->_children ? node->_children->count() : 0; + Array* children = node->getChildren(); + int childrenCount = children ? children->count() : 0; if(childrenCount > 0) { + Node* child = nullptr; // visit children zOrder < 0 for( ; i < childrenCount; i++ ) { - child = static_cast( node->_children->getObjectAtIndex(i) ); + child = static_cast( children->getObjectAtIndex(i) ); - if ( child && child->_ZOrder < 0 ) - visitNode(child); + if ( child && child->getZOrder() < 0 ) + visitTarget(child); else break; } - node->_eventPriority = ++s_eventPriorityIndex; + _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); for( ; i < childrenCount; i++ ) { - child = static_cast( node->_children->getObjectAtIndex(i) ); + child = static_cast( children->getObjectAtIndex(i) ); if (child) - visitNode(child); + visitTarget(child); } } else { - node->_eventPriority = ++s_eventPriorityIndex; + _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); } } -EventDispatcher::EventListenerItem::EventListenerItem() -: fixedPriority(0) -, listener(nullptr) -, node(nullptr) +void EventDispatcher::pauseTarget(Node* node) { - + auto listenerIter = _nodeListenersMap.find(node); + if (listenerIter != _nodeListenersMap.end()) + { + auto listeners = listenerIter->second; + for (auto& l : *listeners) + { + l->_paused = true; + } + } } -EventDispatcher::EventListenerItem::~EventListenerItem() +void EventDispatcher::resumeTarget(Node* node) +{ + auto listenerIter = _nodeListenersMap.find(node); + if (listenerIter != _nodeListenersMap.end()) + { + auto listeners = listenerIter->second; + for (auto& l : *listeners) + { + l->_paused = false; + } + } +} + +void EventDispatcher::cleanTarget(Node* node) +{ + auto listenerIter = _nodeListenersMap.find(node); + if (listenerIter != _nodeListenersMap.end()) + { + auto listeners = listenerIter->second; + for (auto& l : *listeners) + { + removeEventListener(l); + } + } +} + +EventDispatcher::EventListenerVector::EventListenerVector() +: _sceneGraphListeners(nullptr) +, _fixedListeners(nullptr) +, _gt0Index(0) { } -EventDispatcher::EventListenerItemVector::EventListenerItemVector() -: _sceneGraphItems(nullptr) -, _fixedItems(nullptr) +EventDispatcher::EventListenerVector::~EventListenerVector() { + CC_SAFE_DELETE(_sceneGraphListeners); + CC_SAFE_DELETE(_fixedListeners); } -EventDispatcher::EventListenerItemVector::~EventListenerItemVector() -{ - CC_SAFE_DELETE(_sceneGraphItems); - CC_SAFE_DELETE(_fixedItems); -} - -size_t EventDispatcher::EventListenerItemVector::size() const +size_t EventDispatcher::EventListenerVector::size() const { size_t ret = 0; - if (_sceneGraphItems) - ret += _sceneGraphItems->size(); - if (_fixedItems) - ret += _fixedItems->size(); + if (_sceneGraphListeners) + ret += _sceneGraphListeners->size(); + if (_fixedListeners) + ret += _fixedListeners->size(); return ret; } -bool EventDispatcher::EventListenerItemVector::empty() const +bool EventDispatcher::EventListenerVector::empty() const { - return (_sceneGraphItems == nullptr || _sceneGraphItems->empty()) - && (_fixedItems == nullptr || _fixedItems->empty()); + return (_sceneGraphListeners == nullptr || _sceneGraphListeners->empty()) + && (_fixedListeners == nullptr || _fixedListeners->empty()); } -void EventDispatcher::EventListenerItemVector::iterate(IterateCallback cb, EventDispatcher::EventListenerItemVector::IterateMode mode/* = IterateMode::ALL*/) +void EventDispatcher::EventListenerVector::push_back(EventListener* listener) { - auto loop = [&cb](std::vector* items) -> bool { - for (auto iter = items->begin(); iter != items->end(); ++iter) + if (listener->_fixedPriority == 0) + { + if (_sceneGraphListeners == nullptr) { - if (cb(iter, items)) - return false; + _sceneGraphListeners = new std::vector(); + _sceneGraphListeners->reserve(100); } - return true; - }; + + _sceneGraphListeners->push_back(listener); + } + else + { + if (_fixedListeners == nullptr) + { + _fixedListeners = new std::vector(); + _fixedListeners->reserve(100); + } + + _fixedListeners->push_back(listener); + } +} + +void EventDispatcher::EventListenerVector::clear() +{ + if (_sceneGraphListeners) + { + _sceneGraphListeners->clear(); + delete _sceneGraphListeners; + _sceneGraphListeners = nullptr; + } - switch (mode) + if (_fixedListeners) { - case IterateMode::FIXED_PRIORITY_LESS_THAN_0: - loop(_lt0); - break; - case IterateMode::SCENE_GRAPH_PRIORITY: - loop(_eq0); - break; - case IterateMode::FIXED_PRIORITY_GREATER_THAN_0: - loop(_gt0); - break; - case IterateMode::ALL: - { - if (!loop(_lt0)) return; - if (!loop(_eq0)) return; - if (!loop(_gt0)) return; - } - default: - break; + _fixedListeners->clear(); + delete _fixedListeners; + _fixedListeners = nullptr; } } -void EventDispatcher::EventListenerItemVector::push_back(EventDispatcher::EventListenerItem* item) -{ - if (item->fixedPriority == 0) - { - if (_sceneGraphItems == nullptr) - { - _sceneGraphItems = new std::vector(); - _sceneGraphItems->reserve(100); - } - - _sceneGraphItems->push_back(item); - } - else - { - if (_fixedItems == nullptr) - { - _fixedItems = new std::vector(); - _fixedItems->reserve(100); - } - - _fixedItems->push_back(item); - } -} - -void EventDispatcher::EventListenerItemVector::remove(EventDispatcher::EventListenerItem* item) -{ - if (item->fixedPriority < 0) - { - CCASSERT(_lt0, "vector invaild"); - - } - else if (item->fixedPriority == 0) - { - CCASSERT(_eq0, "vector invaild"); - - } - else - { - CCASSERT(_gt0, "vector invalid"); - } -} EventDispatcher::EventDispatcher() : _inDispatch(0) @@ -238,31 +239,75 @@ void EventDispatcher::destroyInstance() CC_SAFE_DELETE(g_instance); } -void EventDispatcher::addEventListenerWithItem(EventListenerItem* item) +void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener) +{ + std::vector* listeners = nullptr; + auto found = _nodeListenersMap.find(node); + if (found != _nodeListenersMap.end()) + { + listeners = found->second; + } + else + { + listeners = new std::vector(); + } + + listeners->push_back(listener); + + _nodeListenersMap.insert(std::make_pair(node, listeners)); +} + +void EventDispatcher::dissociateNodeAndEventListener(Node* node, EventListener* listener) +{ + std::vector* listeners = nullptr; + auto found = _nodeListenersMap.find(node); + if (found != _nodeListenersMap.end()) + { + listeners = found->second; + auto iter = std::find(listeners->begin(), listeners->end(), listener); + if (iter != listeners->end()) + { + listeners->erase(iter); + } + + if (listeners->empty()) + { + _nodeListenersMap.erase(found); + } + } +} + +void EventDispatcher::addEventListener(EventListener* listener) { if (_inDispatch == 0) { - EventListenerItemVector* listenerList = nullptr; + EventListenerVector* listenerList = nullptr; - auto iter = _listeners.find(item->listener->_type); + auto iter = _listeners.find(listener->_type); if (iter == _listeners.end()) { - listenerList = new EventListenerItemVector(); -// listenerList->reserve(100); - _listeners.insert(std::make_pair(item->listener->_type, listenerList)); + listenerList = new EventListenerVector(); + _listeners.insert(std::make_pair(listener->_type, listenerList)); } else { listenerList = iter->second; } - listenerList->push_back(item); - - setDirtyForEventType(item->listener->_type, true); + listenerList->push_back(listener); + + if (listener->_fixedPriority == 0) + { + setDirtyForEventType(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + } + else + { + setDirtyForEventType(listener->_type, DirtyFlag::FIXED_PRITORY); + } } else { - _toAddedListeners.push_back(item); + _toAddedListeners.push_back(listener); } } @@ -274,17 +319,21 @@ void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* list if (!listener->checkAvailable()) return; - auto item = new EventListenerItem(); - item->node = node; - item->node->retain(); - item->fixedPriority = 0; - item->listener = listener; - item->listener->retain(); - item->listener->_isRegistered = true; + listener->_node = node; +// listener->_node->retain(); + listener->_fixedPriority = 0; - addEventListenerWithItem(item); + listener->retain(); + listener->_isRegistered = true; - node->associateEventListener(listener); + addEventListener(listener); + + associateNodeAndEventListener(node, listener); + + if (node->isRunning()) + { + resumeTarget(node); + } } void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority) @@ -296,14 +345,13 @@ void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, if (!listener->checkAvailable()) return; - auto item = new EventListenerItem(); - item->node = nullptr; - item->fixedPriority = fixedPriority; - item->listener = listener; - item->listener->retain(); - item->listener->_isRegistered = true; + listener->_node = nullptr; + listener->_fixedPriority = fixedPriority; + listener->retain(); + listener->_isRegistered = true; + listener->_paused = false; - addEventListenerWithItem(item); + addEventListener(listener); } void EventDispatcher::removeEventListener(EventListener* listener) @@ -313,37 +361,45 @@ void EventDispatcher::removeEventListener(EventListener* listener) bool isFound = false; - for (auto iter = _listeners.begin(); iter != _listeners.end();) - { - iter->second->iterate([&](std::vector::iterator itemIt, std::vector* current) -> bool { + auto removeListenerInVector = [&](std::vector* listeners){ + if (listeners == nullptr) + return; - auto item = *itemIt; - if (item->listener == listener) + for (auto iter = listeners->begin(); iter != listeners->end(); ++iter) + { + auto l = *iter; + if (l == listener) { CC_SAFE_RETAIN(listener); - item->listener->_isRegistered = false; - if (item->node != nullptr) + l->_isRegistered = false; + if (l->_node != nullptr) { - item->node->dissociateEventListener(listener); + dissociateNodeAndEventListener(l->_node, listener); } - item->listener->release(); + l->release(); if (_inDispatch == 0) { - current->erase(itemIt); - delete item; - } - else - { - item->listener = nullptr; + listeners->erase(iter); } isFound = true; - return false; + break; } - - return true; - }); + } + }; + + for (auto iter = _listeners.begin(); iter != _listeners.end();) + { + auto listeners = iter->second; + auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); + auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); + + removeListenerInVector(sceneGraphPriorityListeners); + if (!isFound) + { + removeListenerInVector(fixedPriorityListeners); + } if (iter->second->empty()) { @@ -374,17 +430,18 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority) for (auto iter = _listeners.begin(); iter != _listeners.end(); ++iter) { - for (auto itemIter = iter->second->begin(); itemIter != iter->second->end(); ++itemIter) + auto fixedPriorityListeners = iter->second->getFixedPriorityListeners(); + if (fixedPriorityListeners) { - auto item = *itemIter; - if (item->listener == listener) + auto found = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener); + if (found != fixedPriorityListeners->end()) { - CCASSERT(item->node, "Can't set fixed priority with scene graph based listener."); + CCASSERT(listener->_node, "Can't set fixed priority with scene graph based listener."); - if (item->fixedPriority != fixedPriority) + if (listener->_fixedPriority != fixedPriority) { - item->fixedPriority = fixedPriority; - setDirtyForEventType(listener->_type, true); + listener->_fixedPriority = fixedPriority; + setDirtyForEventType(listener->_type, DirtyFlag::FIXED_PRITORY); } return; } @@ -392,59 +449,151 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority) } } -void EventDispatcher::dispatchEvent(Event* event, bool forceSortListeners) +void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, std::function onEvent) +{ + bool shouldStopPropagation = false; + auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); + auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); + + int i = 0; + // priority < 0 + if (fixedPriorityListeners) + { + for (; !fixedPriorityListeners->empty() && i < listeners->getGt0Index(); ++i) + { + auto l = fixedPriorityListeners->at(i); + if (!l->isPaused() && onEvent(l)) + { + shouldStopPropagation = true; + break; + } + } + } + + if (sceneGraphPriorityListeners) + { + if (!shouldStopPropagation) + { + // priority == 0, scene graph priority + for (auto& listener : *sceneGraphPriorityListeners) + { + if (!listener->isPaused() && onEvent(listener)) + { + shouldStopPropagation = true; + break; + } + } + } + } + + if (fixedPriorityListeners) + { + if (!shouldStopPropagation) + { + // priority > 0 + for (; i < fixedPriorityListeners->size(); ++i) + { + auto l = fixedPriorityListeners->at(i); + + if (!l->isPaused() && onEvent(fixedPriorityListeners->at(i))) + { + shouldStopPropagation = true; + break; + } + } + } + } +} + +void EventDispatcher::dispatchEvent(Event* event) { if (!_isEnabled) return; - bool isDirty = false; + updateDirtyFlagForSceneGraph(); + + DirtyFlag dirtyFlag = DirtyFlag::NONE; + auto dirtyIter = _priorityDirtyFlagMap.find(event->_type); if (dirtyIter != _priorityDirtyFlagMap.end()) { - isDirty = dirtyIter->second; + dirtyFlag = dirtyIter->second; } - if (forceSortListeners || isDirty) + if (dirtyFlag != DirtyFlag::NONE) { - sortAllEventListenerItemsForType(event->_type); - // Sets the dirty flag to false - if (isDirty) + if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY) { - dirtyIter->second = false; + sortEventListenersOfFixedPriority(event->_type); } + + if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY) + { + sortEventListenersOfSceneGraphPriority(event->_type); + } + + dirtyIter->second = DirtyFlag::NONE; } - + DispatchGuard guard(_inDispatch); - - if (event->_type == EventTouch::EVENT_TYPE) - { - dispatchTouchEvent(static_cast(event)); - return; - } auto iter = _listeners.find(event->getType()); if (iter != _listeners.end()) { - auto listenerList = iter->second; - for (auto& item : *listenerList) - { - CCASSERT(item, "listener item is invalid."); - - event->setCurrentTarget(item->node); - item->listener->_onEvent(event); - - if (event->isStopped()) - break; - } + auto listeners = iter->second; + + auto onEvent = [&event](EventListener* listener) -> bool{ + event->setCurrentTarget(listener->_node); + listener->_onEvent(event); + return event->isStopped(); + }; + + dispatchEventToListeners(listeners, onEvent); } - updateListenerItems(); + updateListeners(); } void EventDispatcher::dispatchTouchEvent(EventTouch* event) { - auto oneByOnelisteners = getListenerItemsForType(EventTouch::MODE_ONE_BY_ONE); - auto allAtOncelisteners = getListenerItemsForType(EventTouch::MODE_ALL_AT_ONCE); + if (!_isEnabled) + return; + + updateDirtyFlagForSceneGraph(); + + auto sortTouchListeners = [this](const std::string& type){ + + DirtyFlag dirtyFlag = DirtyFlag::NONE; + auto dirtyIter = _priorityDirtyFlagMap.find(type); + if (dirtyIter != _priorityDirtyFlagMap.end()) + { + dirtyFlag = dirtyIter->second; + } + + if (dirtyFlag != DirtyFlag::NONE) + { + if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY) + { + sortEventListenersOfFixedPriority(type); + } + + if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY) + { + sortEventListenersOfSceneGraphPriority(type); + } + + dirtyIter->second = DirtyFlag::NONE; + } + + }; + + sortTouchListeners(EventTouch::MODE_ONE_BY_ONE); + sortTouchListeners(EventTouch::MODE_ALL_AT_ONCE); + + DispatchGuard guard(_inDispatch); + + auto oneByOnelisteners = getListeners(EventTouch::MODE_ONE_BY_ONE); + auto allAtOncelisteners = getListeners(EventTouch::MODE_ALL_AT_ONCE); // If there aren't any touch listeners, return directly. if (nullptr == oneByOnelisteners && nullptr == allAtOncelisteners) @@ -455,7 +604,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) std::vector orignalTouches = event->getTouches(); std::vector mutableTouches(orignalTouches.size()); std::copy(orignalTouches.begin(), orignalTouches.end(), mutableTouches.begin()); - + // // process the target handlers 1st // @@ -468,62 +617,63 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) { bool isSwallowed = false; - for (auto& item : *oneByOnelisteners) - { + auto onTouchEvent = [&](EventListener* l) -> bool { // Return true to break + EventListenerTouchOneByOne* listener = static_cast(l); + // Skip if the listener was removed. - if (item->listener == nullptr) - continue; + if (!listener->_isRegistered) + return false; - event->setCurrentTarget(item->node); + event->setCurrentTarget(listener->_node); bool isClaimed = false; std::vector::iterator removedIter; - auto touchEventListener = static_cast(item->listener); EventTouch::EventCode eventCode = event->getEventCode(); if (eventCode == EventTouch::EventCode::BEGAN) { - if (touchEventListener->onTouchBegan) + if (listener->onTouchBegan) { - isClaimed = touchEventListener->onTouchBegan(*touchesIter, event); - if (isClaimed && item->listener) + CCLOG("onTouchBegan..."); + isClaimed = listener->onTouchBegan(*touchesIter, event); + if (isClaimed && listener->_isRegistered) { - touchEventListener->_claimedTouches.push_back(*touchesIter); + listener->_claimedTouches.push_back(*touchesIter); } } } - else if (touchEventListener->_claimedTouches.size() > 0 - && ((removedIter = std::find(touchEventListener->_claimedTouches.begin(), touchEventListener->_claimedTouches.end(), *touchesIter)) != touchEventListener->_claimedTouches.end())) + else if (listener->_claimedTouches.size() > 0 + && ((removedIter = std::find(listener->_claimedTouches.begin(), listener->_claimedTouches.end(), *touchesIter)) != listener->_claimedTouches.end())) { isClaimed = true; switch (eventCode) { case EventTouch::EventCode::MOVED: - if (touchEventListener->onTouchMoved) + if (listener->onTouchMoved) { - touchEventListener->onTouchMoved(*touchesIter, event); + listener->onTouchMoved(*touchesIter, event); } break; case EventTouch::EventCode::ENDED: - if (touchEventListener->onTouchEnded) + if (listener->onTouchEnded) { - touchEventListener->onTouchEnded(*touchesIter, event); + listener->onTouchEnded(*touchesIter, event); } - if (item->listener) + if (listener->_isRegistered) { - touchEventListener->_claimedTouches.erase(removedIter); + listener->_claimedTouches.erase(removedIter); } break; case EventTouch::EventCode::CANCELLED: - if (touchEventListener->onTouchCancelled) + if (listener->onTouchCancelled) { - touchEventListener->onTouchCancelled(*touchesIter, event); + listener->onTouchCancelled(*touchesIter, event); } - if (item->listener) + if (listener->_isRegistered) { - touchEventListener->_claimedTouches.erase(removedIter); + listener->_claimedTouches.erase(removedIter); } break; default: @@ -535,21 +685,30 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // If the event was stopped, return directly. if (event->isStopped()) { - updateListenerItems(); - return; + updateListeners(); + return true; } CCASSERT((*touchesIter)->getID() == (*mutableTouchesIter)->getID(), ""); - if (isClaimed && item->listener && touchEventListener->_needSwallow) + if (isClaimed && listener->_isRegistered && listener->_needSwallow) { if (isNeedsMutableSet) { mutableTouchesIter = mutableTouches.erase(mutableTouchesIter); isSwallowed = true; } - break; + return true; } + + return false; + }; + + // + dispatchEventToListeners(oneByOnelisteners, onTouchEvent); + if (event->isStopped()) + { + return; } if (!isSwallowed) @@ -562,40 +721,39 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // if (allAtOncelisteners && mutableTouches.size() > 0) { - for (auto& item : *allAtOncelisteners) - { + + auto onTouchesEvent = [&](EventListener* l) -> bool{ + EventListenerTouchAllAtOnce* listener = static_cast(l); // Skip if the listener was removed. - if (item->listener == nullptr) - continue; + if (!listener->_isRegistered) + return false; - event->setCurrentTarget(item->node); - - auto touchEventListener = static_cast(item->listener); + event->setCurrentTarget(listener->_node); switch (event->getEventCode()) { case EventTouch::EventCode::BEGAN: - if (touchEventListener->onTouchesBegan) + if (listener->onTouchesBegan) { - touchEventListener->onTouchesBegan(mutableTouches, event); + listener->onTouchesBegan(mutableTouches, event); } break; case EventTouch::EventCode::MOVED: - if (touchEventListener->onTouchesMoved) + if (listener->onTouchesMoved) { - touchEventListener->onTouchesMoved(mutableTouches, event); + listener->onTouchesMoved(mutableTouches, event); } break; case EventTouch::EventCode::ENDED: - if (touchEventListener->onTouchesEnded) + if (listener->onTouchesEnded) { - touchEventListener->onTouchesEnded(mutableTouches, event); + listener->onTouchesEnded(mutableTouches, event); } break; case EventTouch::EventCode::CANCELLED: - if (touchEventListener->onTouchesCancelled) + if (listener->onTouchesCancelled) { - touchEventListener->onTouchesCancelled(mutableTouches, event); + listener->onTouchesCancelled(mutableTouches, event); } break; default: @@ -606,120 +764,196 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // If the event was stopped, return directly. if (event->isStopped()) { - updateListenerItems(); - return; + updateListeners(); + return false; } + + return false; + }; + + dispatchEventToListeners(allAtOncelisteners, onTouchesEvent); + if (event->isStopped()) + { + return; } } - updateListenerItems(); + updateListeners(); } -void EventDispatcher::updateListenerItems() +void EventDispatcher::updateListeners() { - auto listenerItemIter = _listeners.begin(); - while (listenerItemIter != _listeners.end()) + auto listenersIter = _listeners.begin(); + while (listenersIter != _listeners.end()) { - for (auto iter = listenerItemIter->second->begin(); iter != listenerItemIter->second->end();) + auto listeners = listenersIter->second; + auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); + auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); + + if (sceneGraphPriorityListeners) { - if ((*iter)->listener == nullptr) + for (auto iter = sceneGraphPriorityListeners->begin(); iter != sceneGraphPriorityListeners->end();) { - delete (*iter); - iter = listenerItemIter->second->erase(iter); - } - else - { - ++iter; + auto l = *iter; + if (!l->_isRegistered) + { + iter = sceneGraphPriorityListeners->erase(iter); + } + else + { + ++iter; + } } } - if (listenerItemIter->second->empty()) + if (fixedPriorityListeners) { - _priorityDirtyFlagMap.erase(listenerItemIter->first); - delete listenerItemIter->second; - listenerItemIter = _listeners.erase(listenerItemIter); + for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();) + { + auto l = *iter; + if (!l->_isRegistered) + { + iter = fixedPriorityListeners->erase(iter); + } + else + { + ++iter; + } + } + } + + if (listenersIter->second->empty()) + { + _priorityDirtyFlagMap.erase(listenersIter->first); + delete listenersIter->second; + listenersIter = _listeners.erase(listenersIter); } else { - ++listenerItemIter; + ++listenersIter; } } if (!_toAddedListeners.empty()) { - std::vector* listenerList = nullptr; + EventListenerVector* listeners = nullptr; - for (auto& item : _toAddedListeners) + for (auto& listener : _toAddedListeners) { - auto itr = _listeners.find(item->listener->_type); + auto itr = _listeners.find(listener->_type); if (itr == _listeners.end()) { - listenerList = new std::vector(); - listenerList->reserve(100); - _listeners.insert(std::make_pair(item->listener->_type, listenerList)); + + listeners = new EventListenerVector(); + _listeners.insert(std::make_pair(listener->_type, listeners)); } else { - listenerList = itr->second; + listeners = itr->second; } - listenerList->push_back(item); + listeners->push_back(listener); - setDirtyForEventType(item->listener->_type, true); + if (listener->_fixedPriority == 0) + { + setDirtyForEventType(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + } + else + { + setDirtyForEventType(listener->_type, DirtyFlag::FIXED_PRITORY); + } } _toAddedListeners.clear(); } } -void EventDispatcher::sortAllEventListenerItemsForType(const std::string &eventType) +void EventDispatcher::updateDirtyFlagForSceneGraph() +{ + if (!_dirtyNodes.empty()) + { + for (auto& node : _dirtyNodes) + { + auto iter = _nodeListenersMap.find(node); + if (iter != _nodeListenersMap.end()) + { + for (auto& l : *iter->second) + { + setDirtyForEventType(l->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + } + } + } + + _dirtyNodes.clear(); + } +} + +void EventDispatcher::sortEventListenersOfSceneGraphPriority(const std::string& eventType) { if (eventType.empty()) return; - auto listenerList = getListenerItemsForType(eventType); - - if (listenerList == nullptr) + auto listeners = getListeners(eventType); + + if (listeners == nullptr) return; - // After sort: priority < 0, = 0, scene graph, > 0 - std::sort(listenerList->begin(), listenerList->end(), [](const EventListenerItem* item1, const EventListenerItem* item2) { - - // item1 and item2 are both using fixed priority. - if (nullptr == item1->node && nullptr == item2->node) - { - return item1->fixedPriority < item2->fixedPriority; - } - // item1 and item2 are both using scene graph based priority. - else if (nullptr != item1->node && nullptr != item2->node) - { - return item1->node->getEventPriority() > item2->node->getEventPriority(); - } - else if (nullptr != item1->node && nullptr == item2->node) - { - return 0 < item2->fixedPriority; - } - else if (nullptr == item1->node && nullptr != item2->node) - { - return item1->fixedPriority <= 0; - } - else - { - CCASSERT(false, "sort event node error..."); - return false; - } + Node* rootNode = (Node*)Director::getInstance()->getRunningScene(); + + visitTarget(rootNode); + + // After sort: priority < 0, > 0 + auto sceneGraphlisteners = listeners->getSceneGraphPriorityListeners(); + std::sort(sceneGraphlisteners->begin(), sceneGraphlisteners->end(), [this](const EventListener* l1, const EventListener* l2) { + return _nodePriorityMap[l1->_node] >= _nodePriorityMap[l2->_node]; }); #if DUMP_LISTENER_ITEM_PRIORITY_INFO log("-----------------------------------"); - for (auto& item : *listenerList) + for (auto& l : *sceneGraphlisteners) { - log("listener item priority: node (%p), fixed (%d)", item->node, item->fixedPriority); + log("listener priority: node ([%s]%p), fixed (%d)", typeid(*l->_node).name(), l->_node, l->_fixedPriority); + } +#endif +} + +void EventDispatcher::sortEventListenersOfFixedPriority(const std::string &eventType) +{ + if (eventType.empty()) + return; + + auto listeners = getListeners(eventType); + + if (listeners == nullptr) + return; + + // After sort: priority < 0, > 0 + auto fixedlisteners = listeners->getFixedPriorityListeners(); + std::sort(fixedlisteners->begin(), fixedlisteners->end(), [](const EventListener* l1, const EventListener* l2) { + return l1->_fixedPriority < l2->_fixedPriority; + }); + + // FIXME: Should use binary search + int index = 0; + for (auto& listener : *fixedlisteners) + { + if (listener->_fixedPriority >= 0) + break; + ++index; + } + + listeners->setGt0Index(index); + +#if DUMP_LISTENER_ITEM_PRIORITY_INFO + log("-----------------------------------"); + for (auto& l : *fixedlisteners) + { + log("listener priority: node (%p), fixed (%d)", l->_node, l->_fixedPriority); } #endif } -std::vector* EventDispatcher::getListenerItemsForType(const std::string &eventType) +EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const std::string &eventType) { auto iter = _listeners.find(eventType); if (iter != _listeners.end()) @@ -738,29 +972,42 @@ void EventDispatcher::removeListenersForEventType(const std::string& eventType) auto listenerItemIter = _listeners.find(eventType); if (listenerItemIter != _listeners.end()) { - for (auto iter = listenerItemIter->second->begin(); iter != listenerItemIter->second->end(); ++iter) - { - (*iter)->listener->_isRegistered = false; - if ((*iter)->node != nullptr) - { - (*iter)->node->dissociateEventListener((*iter)->listener); - } + auto listeners = listenerItemIter->second; + auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); + auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); + + auto removeAllListenersInVector = [&](std::vector* listenerVector){ + if (listenerVector == nullptr) + return; - (*iter)->listener->release(); - if (_inDispatch) + for (auto iter = listenerVector->begin(); iter != listenerVector->end();) { - (*iter)->listener = nullptr; + auto l = *iter; + l->_isRegistered = false; + if (l->_node != nullptr) + { + dissociateNodeAndEventListener(l->_node, l); + } + + l->release(); + if (_inDispatch == 0) + { + iter = listenerVector->erase(iter); + } + else + { + ++iter; + } } - else - { - delete (*iter); - } - } + }; + + removeAllListenersInVector(sceneGraphPriorityListeners); + removeAllListenersInVector(fixedPriorityListeners); if (!_inDispatch) { - listenerItemIter->second->clear(); - delete listenerItemIter->second; + listeners->clear(); + delete listeners; _listeners.erase(listenerItemIter); _priorityDirtyFlagMap.erase(eventType); } @@ -769,36 +1016,18 @@ void EventDispatcher::removeListenersForEventType(const std::string& eventType) void EventDispatcher::removeAllListeners() { - for (auto listenerItemIter = _listeners.begin(); listenerItemIter != _listeners.end(); ++listenerItemIter) + std::vector types(_listeners.size()); + + for (auto iter = _listeners.begin(); iter != _listeners.end(); ++iter) { - for (auto iter = listenerItemIter->second->begin(); iter != listenerItemIter->second->end(); ++iter) - { - (*iter)->listener->_isRegistered = false; - if ((*iter)->node != nullptr) - { - (*iter)->node->dissociateEventListener((*iter)->listener); - } - - (*iter)->listener->release(); - if (_inDispatch) - { - (*iter)->listener = nullptr; - } - else - { - delete (*iter); - } - } - - if (!_inDispatch) - { - listenerItemIter->second->clear(); - delete listenerItemIter->second; - - _priorityDirtyFlagMap.clear(); - } + types.push_back(iter->first); } + for (auto& type : types) + { + removeListenersForEventType(type); + } + if (!_inDispatch) { _listeners.clear(); @@ -816,31 +1045,37 @@ bool EventDispatcher::isEnabled() const return _isEnabled; } -void EventDispatcher::setDirtyForEventType(const std::string& eventType, bool isDirty) +void EventDispatcher::setDirtyForNode(Node* node) +{ + _dirtyNodes.insert(node); +} + +void EventDispatcher::setDirtyForEventType(const std::string& eventType, DirtyFlag flag) { CCASSERT(!eventType.empty(), "Invalid event type."); auto iter = _priorityDirtyFlagMap.find(eventType); if (iter == _priorityDirtyFlagMap.end()) { - _priorityDirtyFlagMap.insert(std::make_pair(eventType, isDirty)); + _priorityDirtyFlagMap.insert(std::make_pair(eventType, flag)); } else { - iter->second = isDirty; + int ret = (int)flag | (int)iter->second; + iter->second = (DirtyFlag) ret; } } -bool EventDispatcher::isDirtyForEventType(const std::string& eventType) +EventDispatcher::DirtyFlag EventDispatcher::isDirtyForEventType(const std::string& eventType) { - bool isDirty = false; + DirtyFlag flag = DirtyFlag::NONE; auto iter = _priorityDirtyFlagMap.find(eventType); if (iter != _priorityDirtyFlagMap.end()) { - isDirty = iter->second; + flag = iter->second; } - return isDirty; + return flag; } NS_CC_END diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 04191ea6d8..dc70491075 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -98,15 +98,31 @@ public: * Also removes all EventListeners marked for deletion from the * event dispatcher list. */ - void dispatchEvent(Event* event, bool forceSortListeners = false); - - void sortSceneGraphListeners(const std::string& eventType); + void dispatchEvent(Event* event); - void setDirtyForEventType(const std::string& eventType, bool isDirty); + /** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */ + void dispatchTouchEvent(EventTouch* event); - bool isDirtyForEventType(const std::string& eventType); + /// Priority dirty flag + enum class DirtyFlag + { + NONE = 0, + FIXED_PRITORY = 1 << 0, + SCENE_GRAPH_PRIORITY = 1 << 1, + ALL = FIXED_PRITORY | SCENE_GRAPH_PRIORITY + }; - void visitNode(Node* node); + void setDirtyForNode(Node* node); + + void setDirtyForEventType(const std::string& eventType, DirtyFlag flag); + + DirtyFlag isDirtyForEventType(const std::string& eventType); + + void visitTarget(Node* node); + + void pauseTarget(Node* node); + void resumeTarget(Node* node); + void cleanTarget(Node* node); public: /** Destructor of EventDispatcher */ @@ -114,75 +130,68 @@ public: private: - struct EventListenerItem - { - int fixedPriority; // The higher the number, the higher the priority, 0 is for scene graph base priority. - Node* node; // Weak reference. - EventListener* listener; - - EventListenerItem(); - ~EventListenerItem(); - }; - - - class EventListenerItemVector + class EventListenerVector { public: - EventListenerItemVector(); - ~EventListenerItemVector(); + EventListenerVector(); + ~EventListenerVector(); size_t size() const; bool empty() const; - enum class IterateMode - { - FIXED_PRIORITY_LESS_THAN_0, - SCENE_GRAPH_PRIORITY, - FIXED_PRIORITY_GREATER_THAN_0, - ALL - }; - - typedef std::function::iterator, std::vector*)> IterateCallback; - - void iterate(IterateCallback cb, IterateMode mode = IterateMode::ALL); - void push_back(EventListenerItem* item); - void remove(EventListenerItem* item); + void push_back(EventListener* item); + void clear(); + inline std::vector* getFixedPriorityListeners() const { return _fixedListeners; }; + inline std::vector* getSceneGraphPriorityListeners() const { return _sceneGraphListeners; }; + inline int getGt0Index() const { return _gt0Index; }; + inline void setGt0Index(int index) { _gt0Index = index; }; private: - std::vector* _fixedItems; - std::vector* _sceneGraphItems; + std::vector* _fixedListeners; + std::vector* _sceneGraphListeners; + int _gt0Index; }; /** Constructor of EventDispatcher */ EventDispatcher(); /** Adds event listener with item */ - void addEventListenerWithItem(EventListenerItem* item); - - /** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */ - void dispatchTouchEvent(EventTouch* event); + void addEventListener(EventListener* listener); /** Gets event the listener list for the event type. */ - EventListenerItemVector* getListenerItemsForType(const std::string& eventType); + EventListenerVector* getListeners(const std::string& eventType); - /** Sorts the listeners of specified type by priority */ - void sortAllEventListenerItemsForType(const std::string& eventType); + void updateDirtyFlagForSceneGraph(); - /** Updates all listener items + /** Sorts the listeners of specified type by scene graph priority */ + void sortEventListenersOfSceneGraphPriority(const std::string& eventType); + + /** Sorts the listeners of specified type by fixed priority */ + void sortEventListenersOfFixedPriority(const std::string& eventType); + + /** Updates all listeners * 1) Removes all listener items that have been marked as 'removed' when dispatching event. * 2) Adds all listener items that have been marked as 'added' when dispatching event. */ - void updateListenerItems(); + void updateListeners(); + void associateNodeAndEventListener(Node* node, EventListener* listener); + void dissociateNodeAndEventListener(Node* node, EventListener* listener); + + void dispatchEventToListeners(EventListenerVector* listeners, std::function onEvent); + private: /** * Listeners map. */ - std::map _listeners; + std::map _listeners; - /// Priority dirty flag - std::map _priorityDirtyFlagMap; + std::map _priorityDirtyFlagMap; - std::vector _toAddedListeners; + std::map*> _nodeListenersMap; + std::map _nodePriorityMap; + + std::vector _toAddedListeners; + std::set _dirtyNodes; int _inDispatch; ///< Whether it's in dispatching event bool _isEnabled; ///< Whether to enable dispatching event diff --git a/cocos/2d/CCEventListener.cpp b/cocos/2d/CCEventListener.cpp index 451be9a8c8..8b34ca5173 100644 --- a/cocos/2d/CCEventListener.cpp +++ b/cocos/2d/CCEventListener.cpp @@ -40,6 +40,7 @@ bool EventListener::init(const std::string& t, std::function callb _onEvent = callback; _type = t; _isRegistered = false; + _paused = true; return true; } diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index 982531416c..f68f9694f9 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -31,10 +31,12 @@ #include #include #include +#include NS_CC_BEGIN class Event; +class Node; /** * The base class of event listener. @@ -58,13 +60,21 @@ public: /** Clones the listener, its subclasses have to override this method. */ virtual EventListener* clone() = 0; + + inline bool isPaused() const { return _paused; }; + protected: std::function _onEvent; /// Event callback function std::string _type; /// Event type bool _isRegistered; /// Whether the listener has been added to dispatcher. + // The priority of event listener + int _fixedPriority; // The higher the number, the higher the priority, 0 is for scene graph base priority. + Node* _node; // scene graph based priority + bool _paused; + +private: friend class EventDispatcher; - friend class Node; }; NS_CC_END diff --git a/cocos/2d/CCMenu.cpp b/cocos/2d/CCMenu.cpp index fc38405355..3105a2d8a3 100644 --- a/cocos/2d/CCMenu.cpp +++ b/cocos/2d/CCMenu.cpp @@ -188,6 +188,8 @@ void Menu::onEnter() auto eventDispatcher = EventDispatcher::getInstance(); auto touchListener = EventListenerTouchOneByOne::create(); + touchListener->setSwallowTouches(true); + touchListener->onTouchBegan = CC_CALLBACK_2(Menu::onTouchBegan, this); touchListener->onTouchMoved = CC_CALLBACK_2(Menu::onTouchMoved, this); touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this); diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index aad3d3fe6d..8b9d41f9ec 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -91,8 +91,7 @@ bool nodeComparisonLess(Object* p1, Object* p2) static int s_globalOrderOfArrival = 1; Node::Node(void) -: _eventPriority(0) -, _rotationX(0.0f) +: _rotationX(0.0f) , _rotationY(0.0f) , _scaleX(1.0f) , _scaleY(1.0f) @@ -134,11 +133,6 @@ Node::Node(void) , _physicsBody(nullptr) #endif { - onEnterHook = nullptr; - onEnterTransitionDidFinishHook = nullptr; - onExitHook = nullptr; - onExitTransitionDidStartHook = nullptr; - // set default scheduler and actionManager Director *director = Director::getInstance(); _actionManager = director->getActionManager(); @@ -188,7 +182,7 @@ Node::~Node() CC_SAFE_DELETE(_componentContainer); - removeAllEventListeners(); + EventDispatcher::getInstance()->cleanTarget(this); #ifdef CC_USE_PHYSICS CC_SAFE_RELEASE(_physicsBody); @@ -243,6 +237,8 @@ void Node::setZOrder(int z) { _parent->reorderChild(this, z); } + + EventDispatcher::getInstance()->setDirtyForNode(this); } /// vertexZ getter @@ -643,6 +639,8 @@ void Node::addChild(Node *child, int zOrder, int tag) child->onEnterTransitionDidFinish(); } } + + EventDispatcher::getInstance()->setDirtyForNode(this); } void Node::addChild(Node *child, int zOrder) @@ -936,7 +934,8 @@ void Node::onEnter() arrayMakeObjectsPerformSelector(_children, onEnter, Node*); this->resumeSchedulerAndActions(); - + EventDispatcher::getInstance()->resumeTarget(this); + _running = true; if (_scriptType != kScriptTypeNone) @@ -946,11 +945,6 @@ void Node::onEnter() ScriptEvent scriptEvent(kNodeEvent,(void*)&data); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); } - - if (onEnterHook) - { - onEnterHook(); - } } void Node::onEnterTransitionDidFinish() @@ -966,20 +960,10 @@ void Node::onEnterTransitionDidFinish() ScriptEvent scriptEvent(kNodeEvent,(void*)&data); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); } - - if (onEnterTransitionDidFinishHook) - { - onEnterTransitionDidFinishHook(); - } } void Node::onExitTransitionDidStart() { - if (onExitTransitionDidStartHook) - { - onExitTransitionDidStartHook(); - } - arrayMakeObjectsPerformSelector(_children, onExitTransitionDidStart, Node*); if (_scriptType != kScriptTypeNone) { @@ -992,10 +976,7 @@ void Node::onExitTransitionDidStart() void Node::onExit() { - if (onExitHook) - { - onExitHook(); - } + EventDispatcher::getInstance()->pauseTarget(this); this->pauseSchedulerAndActions(); @@ -1009,8 +990,6 @@ void Node::onExit() } arrayMakeObjectsPerformSelector(_children, onExit, Node*); - - removeAllEventListeners(); } void Node::setActionManager(ActionManager* actionManager) @@ -1363,28 +1342,6 @@ void Node::removeAllComponents() _componentContainer->removeAll(); } -void Node::associateEventListener(EventListener* listener) -{ - _eventlisteners.insert(listener); -} - -void Node::dissociateEventListener(EventListener* listener) -{ - _eventlisteners.erase(listener); -} - -void Node::removeAllEventListeners() -{ - auto dispatcher = EventDispatcher::getInstance(); - - auto eventListenersCopy = _eventlisteners; - - for (auto& listener : eventListenersCopy) - { - dispatcher->removeEventListener(listener); - } -} - #ifdef CC_USE_PHYSICS void Node::setPhysicsBody(PhysicsBody* body) { diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index b5c42f2301..fcc38b23b5 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -928,7 +928,6 @@ public: * @lua NA */ virtual void onEnter(); - std::function onEnterHook; /** Event callback that is invoked when the Node enters in the 'stage'. * If the Node enters the 'stage' with a transition, this event is called when the transition finishes. @@ -937,7 +936,6 @@ public: * @lua NA */ virtual void onEnterTransitionDidFinish(); - std::function onEnterTransitionDidFinishHook; /** * Event callback that is invoked every time the Node leaves the 'stage'. @@ -948,7 +946,6 @@ public: * @lua NA */ virtual void onExit(); - std::function onExitHook; /** * Event callback that is called every time the Node leaves the 'stage'. @@ -957,7 +954,6 @@ public: * @lua NA */ virtual void onExitTransitionDidStart(); - std::function onExitTransitionDidStartHook; /// @} end of event callbacks. @@ -1401,23 +1397,9 @@ public: virtual void updatePhysicsTransform(); #endif - - -private: - friend class Director; - friend class EventDispatcher; - - void associateEventListener(EventListener* listener); - void dissociateEventListener(EventListener* listener); - - std::set _eventlisteners; - int _eventPriority; protected: - /// Removes all event listeners that associated with this node. - void removeAllEventListeners(); - /// lazy allocs void childrenAlloc(void); diff --git a/cocos/2d/CCParticleBatchNode.cpp b/cocos/2d/CCParticleBatchNode.cpp index a7dbdc14d1..788fdd221c 100644 --- a/cocos/2d/CCParticleBatchNode.cpp +++ b/cocos/2d/CCParticleBatchNode.cpp @@ -144,7 +144,6 @@ void ParticleBatchNode::visit() transform(); draw(); - updateEventPriorityIndex(); if ( _grid && _grid->isActive()) { diff --git a/cocos/2d/CCRenderTexture.cpp b/cocos/2d/CCRenderTexture.cpp index 5bace186cf..d76c258f87 100644 --- a/cocos/2d/CCRenderTexture.cpp +++ b/cocos/2d/CCRenderTexture.cpp @@ -465,7 +465,6 @@ void RenderTexture::visit() transform(); _sprite->visit(); draw(); - updateEventPriorityIndex(); if (_grid && _grid->isActive()) { diff --git a/cocos/2d/CCSpriteBatchNode.cpp b/cocos/2d/CCSpriteBatchNode.cpp index b4be9bd045..195b5fa8eb 100644 --- a/cocos/2d/CCSpriteBatchNode.cpp +++ b/cocos/2d/CCSpriteBatchNode.cpp @@ -158,7 +158,6 @@ void SpriteBatchNode::visit(void) transform(); draw(); - updateEventPriorityIndex(); if (_grid && _grid->isActive()) { diff --git a/cocos/2d/platform/CCEGLViewProtocol.cpp b/cocos/2d/platform/CCEGLViewProtocol.cpp index 9b1e943019..094e584e97 100644 --- a/cocos/2d/platform/CCEGLViewProtocol.cpp +++ b/cocos/2d/platform/CCEGLViewProtocol.cpp @@ -247,7 +247,7 @@ void EGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float y } touchEvent._eventCode = EventTouch::EventCode::BEGAN; - EventDispatcher::getInstance()->dispatchEvent(&touchEvent); + EventDispatcher::getInstance()->dispatchTouchEvent(&touchEvent); } void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[]) @@ -294,7 +294,7 @@ void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys } touchEvent._eventCode = EventTouch::EventCode::MOVED; - EventDispatcher::getInstance()->dispatchEvent(&touchEvent); + EventDispatcher::getInstance()->dispatchTouchEvent(&touchEvent); } void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, int ids[], float xs[], float ys[]) @@ -347,7 +347,7 @@ void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode } touchEvent._eventCode = eventCode; - EventDispatcher::getInstance()->dispatchEvent(&touchEvent); + EventDispatcher::getInstance()->dispatchTouchEvent(&touchEvent); for (auto& touch : touchEvent._touches) { diff --git a/cocos/editor-support/cocostudio/CCArmature.cpp b/cocos/editor-support/cocostudio/CCArmature.cpp index 5885cbbd25..5c3b54e3df 100644 --- a/cocos/editor-support/cocostudio/CCArmature.cpp +++ b/cocos/editor-support/cocostudio/CCArmature.cpp @@ -624,7 +624,6 @@ void Armature::visit() transform(); sortAllChildren(); draw(); - updateEventPriorityIndex(); // reset for next frame _orderOfArrival = 0; diff --git a/cocos/editor-support/cocostudio/CCBatchNode.cpp b/cocos/editor-support/cocostudio/CCBatchNode.cpp index 0c6f7598ae..7ef2188fb8 100644 --- a/cocos/editor-support/cocostudio/CCBatchNode.cpp +++ b/cocos/editor-support/cocostudio/CCBatchNode.cpp @@ -81,7 +81,6 @@ void BatchNode::visit() transform(); sortAllChildren(); draw(); - updateEventPriorityIndex(); // reset for next frame _orderOfArrival = 0; diff --git a/extensions/GUI/CCScrollView/CCScrollView.cpp b/extensions/GUI/CCScrollView/CCScrollView.cpp index e5f4c0503e..ecc17ef0e7 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.cpp +++ b/extensions/GUI/CCScrollView/CCScrollView.cpp @@ -109,16 +109,14 @@ bool ScrollView::initWithViewSize(Size size, Node *container/* = NULL*/) this->setViewSize(size); - this->onEnterHook = [this]() { - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchOneByOne::create(); - listener->onTouchBegan = CC_CALLBACK_2(ScrollView::onTouchBegan, this); - listener->onTouchMoved = CC_CALLBACK_2(ScrollView::onTouchMoved, this); - listener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this); - listener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this); - - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = CC_CALLBACK_2(ScrollView::onTouchBegan, this); + listener->onTouchMoved = CC_CALLBACK_2(ScrollView::onTouchMoved, this); + listener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this); + listener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this); + + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); _touches.reserve(EventTouch::MAX_TOUCHES); @@ -578,7 +576,6 @@ void ScrollView::visit() // this draw this->draw(); - updateEventPriorityIndex(); // draw children zOrder >= 0 for( ; i < _children->count(); i++ ) @@ -591,7 +588,6 @@ void ScrollView::visit() else { this->draw(); - updateEventPriorityIndex(); } this->afterDraw(); diff --git a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp index e0e3562a54..0e7a14ffdf 100644 --- a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp @@ -1375,7 +1375,7 @@ void ActionStacked::onEnter() this->centerSprites(0); - this->setTouchEnabled(true); +//cjh this->setTouchEnabled(true); auto s = Director::getInstance()->getWinSize(); this->addNewSpriteWithCoords(Point(s.width/2, s.height/2)); diff --git a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp index 4c958bebaa..9614180fb2 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp +++ b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp @@ -33,6 +33,7 @@ MenuLayer::MenuLayer(void) MenuLayer::~MenuLayer(void) { + EventDispatcher::getInstance()->removeEventListener(_touchListener); } MenuLayer* MenuLayer::menuWithEntryID(int entryId) @@ -52,9 +53,6 @@ bool MenuLayer::initWithEntryID(int entryId) m_entryID = entryId; - setTouchEnabled( true ); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); - Box2DView* view = Box2DView::viewWithEntryID( entryId ); addChild(view, 0, kTagBox2DNode); view->setScale(15); @@ -81,18 +79,17 @@ bool MenuLayer::initWithEntryID(int entryId) addChild(menu, 1); - // Removes touch event listener - EventDispatcher::getInstance()->removeEventListener(_touchListener); - // Adds touch event listener - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(MenuLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(MenuLayer::onTouchMoved, this); EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, 1); + _touchListener = listener; + return true; } @@ -180,19 +177,16 @@ Box2DView* Box2DView::viewWithEntryID(int entryId) bool Box2DView::initWithEntryID(int entryId) { // setIsAccelerometerEnabled( true ); - setTouchEnabled( true ); +// FIXME cjh: setTouchEnabled( true ); schedule( schedule_selector(Box2DView::tick) ); m_entry = g_testEntries + entryId; m_test = m_entry->createFcn(); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); - // Removes Touch Event Listener - EventDispatcher::getInstance()->removeEventListener(_touchListener); // Adds Touch Event Listener - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(Box2DView::onTouchBegan, this); @@ -232,6 +226,8 @@ void Box2DView::draw() Box2DView::~Box2DView() { + // Removes Touch Event Listener + EventDispatcher::getInstance()->removeEventListener(_touchListener); delete m_test; } // diff --git a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h index 5f3e785535..681e44de6c 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h +++ b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h @@ -7,7 +7,7 @@ class MenuLayer : public Layer { int m_entryID; - + EventListenerTouchOneByOne* _touchListener; public: MenuLayer(void); virtual ~MenuLayer(void); @@ -30,6 +30,7 @@ struct TestEntry; class Test; class Box2DView : public Layer { + EventListenerTouchOneByOne* _touchListener; TestEntry* m_entry; Test* m_test; int m_entryID; diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp index a86859ebb1..9eb6d6ab5c 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp @@ -20,11 +20,9 @@ bool Bug624Layer::init() label->setPosition(Point(size.width/2, size.height/2)); addChild(label); - this->onEnterHook = [this](){ - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer::onAcceleration, this)); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); schedule(schedule_selector(Bug624Layer::switchLayer), 5.0f); @@ -63,11 +61,9 @@ bool Bug624Layer2::init() label->setPosition(Point(size.width/2, size.height/2)); addChild(label); - this->onEnterHook = [this](){ - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer2::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer2::onAcceleration, this)); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); schedule(schedule_selector(Bug624Layer2::switchLayer), 5.0f); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp index 337d9b1006..76ab5b3b31 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp @@ -30,13 +30,11 @@ bool Bug914Layer::init() // Apple recommends to re-assign "self" with the "super" return value if (BugsTestBaseLayer::init()) { - this->onEnterHook = [this](){ - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchAllAtOnce::create(); - listener->onTouchesBegan = CC_CALLBACK_2(Bug914Layer::onTouchesBegan, this); - listener->onTouchesMoved = CC_CALLBACK_2(Bug914Layer::onTouchesMoved, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(Bug914Layer::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(Bug914Layer::onTouchesMoved, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp index 237b12077c..7f28de8df8 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp @@ -67,7 +67,7 @@ void BugsTestMainLayer::onEnter() _itmeMenu->setPosition(s_tCurPos); addChild(_itmeMenu); - setTouchEnabled(true); +//cjh setTouchEnabled(true); } void BugsTestMainLayer::onTouchesBegan(const std::vector& touches, Event *event) diff --git a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp index f617ee501b..46cae7762e 100644 --- a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp @@ -21,8 +21,8 @@ ChipmunkTestLayer::ChipmunkTestLayer() { #if CC_ENABLE_CHIPMUNK_INTEGRATION // enable events - setTouchEnabled(true); - setAccelerometerEnabled(true); +//FIXME: setTouchEnabled(true); +// setAccelerometerEnabled(true); // title auto label = LabelTTF::create("Multi touch the screen", "Marker Felt", 36); diff --git a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h index 33ae31cee7..3480f0314a 100644 --- a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h +++ b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h @@ -24,8 +24,8 @@ public: void addNewSpriteAtPosition(Point p); void update(float dt); void toggleDebugCallback(Object* sender); - virtual void onTouchesEnded(const std::vector& touches, Event* event) override; - virtual void onAcceleration(Acceleration* acc, Event* event) override; + virtual void onTouchesEnded(const std::vector& touches, Event* event); + virtual void onAcceleration(Acceleration* acc, Event* event); private: Texture2D* _spriteTexture; // weak ref diff --git a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp index 5a87658f35..408188925f 100644 --- a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp @@ -17,13 +17,11 @@ void ClickAndMoveTestScene::runThisTest() MainLayer::MainLayer() { - this->onEnterHook = [this](){ - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchOneByOne::create(); - listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan, this); - listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan, this); + listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto sprite = Sprite::create(s_pathGrossini); diff --git a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp index fcde7712ad..56ad34de68 100644 --- a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp @@ -449,12 +449,10 @@ void HoleDemo::setup() this->addChild(_outerClipper); - this->onEnterHook = [this](){ - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchAllAtOnce::create(); - listener->onTouchesBegan = CC_CALLBACK_2(HoleDemo::onTouchesBegan, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(HoleDemo::onTouchesBegan, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void HoleDemo::pokeHoleAtPoint(Point point) @@ -531,14 +529,12 @@ void ScrollViewDemo::setup() _scrolling = false; - this->onEnterHook = [this](){ - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchAllAtOnce::create(); - listener->onTouchesBegan = CC_CALLBACK_2(ScrollViewDemo::onTouchesBegan, this); - listener->onTouchesMoved = CC_CALLBACK_2(ScrollViewDemo::onTouchesMoved, this); - listener->onTouchesEnded = CC_CALLBACK_2(ScrollViewDemo::onTouchesEnded, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); - }; + auto dispatcher = EventDispatcher::getInstance(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(ScrollViewDemo::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(ScrollViewDemo::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(ScrollViewDemo::onTouchesEnded, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void ScrollViewDemo::onTouchesBegan(const std::vector& touches, Event *event) diff --git a/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp b/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp index 207a26a2ab..9589cde586 100644 --- a/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp +++ b/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp @@ -65,7 +65,7 @@ private: // Director::getInstance()->getTouchDispatcher()->addTargetedDelegate(this, 100, true); // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(Button::onTouchBegan, this); @@ -238,7 +238,7 @@ _sliderMusicVolume(NULL) // "stop all effects" // }; - setTouchEnabled(true); +//cjh setTouchEnabled(true); // preload background music and effect SimpleAudioEngine::getInstance()->preloadBackgroundMusic( MUSIC_FILE ); diff --git a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp index b8cfc653b7..83945cd581 100644 --- a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp +++ b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp @@ -9,7 +9,7 @@ CurlTest::CurlTest() addChild(label, 0); label->setPosition( Point(VisibleRect::center().x, VisibleRect::top().y-50) ); - setTouchEnabled(true); +//FIXME cjh: setTouchEnabled(true); // create a label to display the tip string _label = LabelTTF::create("Touch the screen to connect", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h index da0290d0bf..9688d03e38 100644 --- a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h +++ b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h @@ -10,7 +10,7 @@ public: CurlTest(); ~CurlTest(); - virtual void onTouchesEnded(const std::vector& touches, cocos2d::Event *event) override; + virtual void onTouchesEnded(const std::vector& touches, cocos2d::Event *event); private: cocos2d::LabelTTF* _label; diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp index 66eb20472b..eaf14546be 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp @@ -477,7 +477,7 @@ void TestAnimationEvent::callback2() void TestParticleDisplay::onEnter() { ArmatureTestLayer::onEnter(); - setTouchEnabled(true); +//FIXME cjh: setTouchEnabled(true); animationID = 0; @@ -534,7 +534,7 @@ void TestParticleDisplay::onTouchesEnded(const std::vector& touches, Eve void TestUseMutiplePicture::onEnter() { ArmatureTestLayer::onEnter(); - setTouchEnabled(true); +//cjh setTouchEnabled(true); displayIndex = 0; @@ -935,7 +935,7 @@ std::string TestAnchorPoint::title() void TestArmatureNesting::onEnter() { ArmatureTestLayer::onEnter(); - setTouchEnabled(true); +//cjh setTouchEnabled(true); armature = Armature::create("cyborg"); armature->getAnimation()->playByIndex(1); diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h index 625fdddf88..ccd07d1d72 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h @@ -138,7 +138,7 @@ class TestUseMutiplePicture : public ArmatureTestLayer virtual void onExit(); virtual std::string title(); virtual std::string subtitle(); - virtual void onTouchesEnded(const std::vector& touches, Event* event) override; + virtual void onTouchesEnded(const std::vector& touches, Event* event); int displayIndex; cocostudio::Armature *armature; diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp index 0c802b3f97..7c95239cfa 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp @@ -118,7 +118,7 @@ void ExtensionsMainLayer::onEnter() _itemMenu->addChild(pItem, kItemTagBasic + i); } - setTouchEnabled(true); +//cjh setTouchEnabled(true); addChild(_itemMenu); } diff --git a/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp b/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp index 9e2fd40647..7140a44e8a 100644 --- a/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp +++ b/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp @@ -7,7 +7,7 @@ KeyboardTest::KeyboardTest() addChild(label, 0); label->setPosition( Point(s.width/2, s.height-50) ); - setKeyboardEnabled(true); +//cjh setKeyboardEnabled(true); // create a label to display the tip string _label = LabelTTF::create("Please press any key and see console log...", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp index 7cdbebbc6e..5bda6cccf2 100644 --- a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp +++ b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp @@ -7,7 +7,7 @@ KeypadTest::KeypadTest() addChild(label, 0); label->setPosition( Point(s.width/2, s.height-50) ); - setKeyboardEnabled(true); +//cjh setKeyboardEnabled(true); // create a label to display the tip string _label = LabelTTF::create("Please press any key...", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.h b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.h index 760ab8eb01..e525511e4a 100644 --- a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.h +++ b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.h @@ -10,7 +10,7 @@ public: KeypadTest(); ~KeypadTest(); - virtual void onKeyReleased(EventKeyboard::KeyCode keycode, Event* event) override; + virtual void onKeyReleased(EventKeyboard::KeyCode keycode, Event* event); private: LabelTTF* _label; diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp index 36b434f139..52fc92c2e4 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp @@ -1135,7 +1135,7 @@ static float alignmentItemPadding = 50; static float menuItemPaddingCenter = 50; BitmapFontMultiLineAlignment::BitmapFontMultiLineAlignment() { - this->setTouchEnabled(true); +//cjh this->setTouchEnabled(true); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp index d822776e62..47173da112 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp @@ -650,7 +650,7 @@ static float menuItemPaddingCenter = 50; LabelFNTMultiLineAlignment::LabelFNTMultiLineAlignment() { - this->setTouchEnabled(true); +//cjh this->setTouchEnabled(true); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp index 26175b6e3f..e27b82cf16 100644 --- a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp +++ b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp @@ -449,7 +449,7 @@ void LayerTest1::onEnter() { LayerTest::onEnter(); - setTouchEnabled(true); +//cjh setTouchEnabled(true); auto s = Director::getInstance()->getWinSize(); auto layer = LayerColor::create( Color4B(0xFF, 0x00, 0x00, 0x80), 200, 200); @@ -590,7 +590,7 @@ LayerGradientTest::LayerGradientTest() auto layer1 = LayerGradient::create(Color4B(255,0,0,255), Color4B(0,255,0,255), Point(0.9f, 0.9f)); addChild(layer1, 0, kTagLayer); - setTouchEnabled(true); +//cjh setTouchEnabled(true); auto label1 = LabelTTF::create("Compressed Interpolation: Enabled", "Marker Felt", 26); auto label2 = LabelTTF::create("Compressed Interpolation: Disabled", "Marker Felt", 26); diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp index 8a5809ee6b..a61f15225b 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp @@ -25,8 +25,8 @@ enum { //------------------------------------------------------------------ MenuLayerMainMenu::MenuLayerMainMenu() { - setTouchEnabled(true); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); +//cjh setTouchEnabled(true); +// setTouchMode(Touch::DispatchMode::ONE_BY_ONE); // Font Item auto spriteNormal = Sprite::create(s_MenuItem, Rect(0,23*2,115,23)); @@ -532,8 +532,8 @@ BugsTest::BugsTest() void BugsTest::issue1410MenuCallback(Object *sender) { auto menu = static_cast( static_cast(sender)->getParent() ); - menu->setTouchEnabled(false); - menu->setTouchEnabled(true); +//cjh menu->setTouchEnabled(false); +// menu->setTouchEnabled(true); log("NO CRASHES"); } @@ -541,8 +541,8 @@ void BugsTest::issue1410MenuCallback(Object *sender) void BugsTest::issue1410v2MenuCallback(cocos2d::Object *pSender) { auto menu = static_cast( static_cast(pSender)->getParent() ); - menu->setTouchEnabled(true); - menu->setTouchEnabled(false); +//cjh menu->setTouchEnabled(true); +// menu->setTouchEnabled(false); log("NO CRASHES. AND MENU SHOULD STOP WORKING"); } @@ -571,11 +571,11 @@ RemoveMenuItemWhenMove::RemoveMenuItemWhenMove() menu->setPosition(Point(s.width/2, s.height/2)); - setTouchEnabled(true); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); +//cjh setTouchEnabled(true); +// setTouchMode(Touch::DispatchMode::ONE_BY_ONE); // Register Touch Event - _touchListener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + _touchListener = EventListenerTouchOneByOne::create(); _touchListener->setSwallowTouches(false); _touchListener->onTouchBegan = CC_CALLBACK_2(RemoveMenuItemWhenMove::onTouchBegan, this); diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h index f023871835..41072151c5 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h @@ -113,6 +113,7 @@ public: private: MenuItemFont *item; + EventListenerTouchOneByOne* _touchListener; }; diff --git a/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp b/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp index dcbb3a3beb..7c4fe4340f 100644 --- a/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp @@ -121,7 +121,7 @@ void MotionStreakTest2::onEnter() { MotionStreakTest::onEnter(); - setTouchEnabled(true); +//cjh setTouchEnabled(true); auto s = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp index 9ef9656951..f92fa93299 100644 --- a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp @@ -56,7 +56,7 @@ bool MutiTouchTestLayer::init() { if (Layer::init()) { - setTouchEnabled(true); +//cjh setTouchEnabled(true); auto title = LabelTTF::create("Please touch the screen!", "", 24); title->setPosition(VisibleRect::top()+Point(0, -40)); diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 60a2f909a9..797f042ca7 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -141,7 +141,7 @@ void TouchableSpriteTest::onEnter() sprite2->addChild(sprite3, 1); // Make sprite1 touchable - auto listener1 = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); listener1->onTouchBegan = [](Touch* touch, Event* event){ @@ -243,7 +243,7 @@ public: auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = [=](Touch* touch, Event* event){ @@ -348,7 +348,7 @@ void RemoveListenerWhenDispatching::onEnter() addChild(sprite1, 10); // Make sprite1 touchable - auto listener1 = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); setUserObject(listener1); diff --git a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp index 8689ee9f99..db7f53d7c2 100644 --- a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp @@ -723,7 +723,7 @@ std::string CameraCenterTest::subtitle() //------------------------------------------------------------------ ConvertToNode::ConvertToNode() { - setTouchEnabled(true); +//cjh setTouchEnabled(true); auto s = Director::getInstance()->getWinSize(); auto rotate = RotateBy::create(10, 360); diff --git a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp index cfa80084b9..bc2a128603 100644 --- a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp @@ -87,7 +87,7 @@ std::string Parallax1::title() Parallax2::Parallax2() { - setTouchEnabled( true ); +//cjh setTouchEnabled( true ); // Top Layer, a simple image auto cocosImage = Sprite::create(s_Power); diff --git a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp index bd4b98dea6..414c915135 100644 --- a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp @@ -1068,7 +1068,7 @@ void ParticleDemo::onEnter(void) _emitter = NULL; - setTouchEnabled( true ); +//cjh setTouchEnabled( true ); auto s = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp index 60c5341463..a928a3bd23 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp @@ -119,9 +119,9 @@ std::string TouchesMainScene::title() void TouchesPerformTest1::onEnter() { TouchesMainScene::onEnter(); - setTouchEnabled(true); - setTouchMode(Touch::DispatchMode::ONE_BY_ONE); - setSwallowsTouches(true); +//cjh setTouchEnabled(true); +// setTouchMode(Touch::DispatchMode::ONE_BY_ONE); +// setSwallowsTouches(true); } std::string TouchesPerformTest1::title() @@ -158,7 +158,7 @@ void TouchesPerformTest1::onTouchCancelled(Touch* touch, Event* event) void TouchesPerformTest2::onEnter() { TouchesMainScene::onEnter(); - setTouchEnabled(true); +//cjh setTouchEnabled(true); } std::string TouchesPerformTest2::title() @@ -231,8 +231,8 @@ void TouchesPerformTest3::onEnter() { int zorder = rand() % TOUCHABLE_NODE_NUM; auto layer = new TouchableLayer(); - layer->setTouchEnabled(true); - layer->setTouchMode(Touch::DispatchMode::ONE_BY_ONE); +//cjh layer->setTouchEnabled(true); +// layer->setTouchMode(Touch::DispatchMode::ONE_BY_ONE); addChild(layer, zorder); layer->release(); } @@ -260,7 +260,7 @@ void TouchesPerformTest3::onEnter() { CC_PROFILER_START(TOUCH_PROFILER_NAME); - dispatcher->dispatchEvent(&event, false); + dispatcher->dispatchEvent(&event); CC_PROFILER_STOP(TOUCH_PROFILER_NAME); } diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h index 47029a3bc6..5cb4d35ad9 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h @@ -36,10 +36,10 @@ public: virtual void onEnter() override; virtual std::string title() override; - virtual bool onTouchBegan(Touch* touch, Event* event) override; - virtual void onTouchMoved(Touch* touch, Event* event) override; - virtual void onTouchEnded(Touch* touch, Event* event) override; - virtual void onTouchCancelled(Touch* touch, Event* event) override; + virtual bool onTouchBegan(Touch* touch, Event* event) ; + virtual void onTouchMoved(Touch* touch, Event* event) ; + virtual void onTouchEnded(Touch* touch, Event* event) ; + virtual void onTouchCancelled(Touch* touch, Event* event) ; }; class TouchesPerformTest2 : public TouchesMainScene @@ -53,10 +53,10 @@ public: virtual void onEnter() override; virtual std::string title() override; - void onTouchesBegan(const std::vector& touches, Event* event) override; - void onTouchesMoved(const std::vector& touches, Event* event) override; - void onTouchesEnded(const std::vector& touches, Event* event) override; - void onTouchesCancelled(const std::vector& touches, Event* event) override; + void onTouchesBegan(const std::vector& touches, Event* event) ; + void onTouchesMoved(const std::vector& touches, Event* event) ; + void onTouchesEnded(const std::vector& touches, Event* event) ; + void onTouchesCancelled(const std::vector& touches, Event* event) ; }; class TouchesPerformTest3 : public PerformBasicLayer diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index f0ceb3553c..4c56986746 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -197,8 +197,8 @@ void PhysicsDemoClickAdd::onEnter() PhysicsDemo::onEnter(); #ifdef CC_USE_PHYSICS - setTouchEnabled(true); - setAccelerometerEnabled(true); +//cjh setTouchEnabled(true); +// setAccelerometerEnabled(true); auto node = Node::create(); node->setPhysicsBody(PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size)); diff --git a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp index 433415f677..1669b78c1f 100644 --- a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp +++ b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp @@ -111,7 +111,7 @@ RenderTextureSave::RenderTextureSave() _brush->retain(); _brush->setColor(Color3B::RED); _brush->setOpacity(20); - this->setTouchEnabled(true); +//cjh this->setTouchEnabled(true); // Save Image menu MenuItemFont::setFontSize(16); @@ -296,7 +296,7 @@ void RenderTextureScene::runThisTest() RenderTextureZbuffer::RenderTextureZbuffer() { - this->setTouchEnabled(true); +//cjh this->setTouchEnabled(true); auto size = Director::getInstance()->getWinSize(); auto label = LabelTTF::create("vertexZ = 50", "Marker Felt", 64); label->setPosition(Point(size.width / 2, size.height * 0.25f)); @@ -627,7 +627,7 @@ void SpriteRenderTextureBug::SimpleSprite::draw() SpriteRenderTextureBug::SpriteRenderTextureBug() { - setTouchEnabled(true); +//cjh setTouchEnabled(true); auto s = Director::getInstance()->getWinSize(); addNewSpriteWithCoords(Point(s.width/2, s.height/2)); diff --git a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id index 16b0471301..a3d466373a 100644 --- a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id +++ b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id @@ -1 +1 @@ -b17d2ec91cd40aaf09376a62f38f97ca3f7da2c7 \ No newline at end of file +4701ba8fb99f70629c5575dcf6fb3536543ac0b6 \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp index 3392a3e9f8..1645d017d8 100644 --- a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp +++ b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp @@ -126,10 +126,10 @@ void TextInputTest::onEnter() KeyboardNotificationLayer::KeyboardNotificationLayer() : _trackNode(0) { - setTouchEnabled(true); +//cjh setTouchEnabled(true); // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(KeyboardNotificationLayer::onTouchBegan, this); listener->onTouchEnded = CC_CALLBACK_2(KeyboardNotificationLayer::onTouchEnded, this); diff --git a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp index 761afa4a71..7be2b29c32 100644 --- a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp +++ b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp @@ -1430,7 +1430,7 @@ Layer* restartTileMapAction() TileDemo::TileDemo(void) : BaseTest() { - setTouchEnabled( true ); +//cjh setTouchEnabled( true ); } TileDemo::~TileDemo(void) diff --git a/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp b/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp index 2e3720d10c..e168d7a1bc 100644 --- a/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp +++ b/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp @@ -38,7 +38,7 @@ void Paddle::onEnter() Sprite::onEnter(); // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(Paddle::onTouchBegan, this); diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index f78fb2c9af..c7b03f1acf 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -120,12 +120,12 @@ TestController::TestController() _itemMenu->setPosition(s_tCurPos); addChild(_itemMenu); - setTouchEnabled(true); +//cjh setTouchEnabled(true); addChild(menu, 1); // Register Touch Event - auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(TestController::onTouchBegan, this); From 9ed263056c126bf6efc6dc46ddd8154e48244771 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 16:14:03 +0800 Subject: [PATCH 023/144] Use eventDispatcher to dispatch event. Remove controller codes in Layer. --- cocos/2d/CCEventDispatcher.cpp | 159 +++++++++--------- cocos/2d/CCEventListenerTouch.h | 1 - cocos/2d/CCMenu.h | 10 +- .../Cpp/SimpleGame/Classes/HelloWorldScene.h | 2 +- .../Classes/ActionsTest/ActionsTest.cpp | 4 +- .../TestCpp/Classes/ActionsTest/ActionsTest.h | 2 +- .../Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h | 2 +- .../Classes/Box2DTestBed/Box2dView.cpp | 3 - .../TestCpp/Classes/Box2DTestBed/Box2dView.h | 10 +- .../Cpp/TestCpp/Classes/BugsTest/Bug-914.h | 4 +- .../Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp | 7 +- .../Cpp/TestCpp/Classes/BugsTest/BugsTest.h | 4 +- .../Classes/ChipmunkTest/ChipmunkTest.cpp | 9 +- .../Classes/ChipmunkTest/ChipmunkTest.h | 2 +- .../ClickAndMoveTest/ClickAndMoveTest.h | 4 +- .../ClippingNodeTest/ClippingNodeTest.h | 8 +- .../CocosDenshionTest/CocosDenshionTest.cpp | 13 -- .../Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp | 4 +- .../Cpp/TestCpp/Classes/CurlTest/CurlTest.h | 2 +- .../CocoStudioArmatureTest/ArmatureScene.cpp | 15 +- .../CocoStudioArmatureTest/ArmatureScene.h | 6 +- .../PlayerController.h | 2 +- .../Classes/ExtensionsTest/ExtensionsTest.cpp | 6 +- .../Classes/ExtensionsTest/ExtensionsTest.h | 4 +- .../Classes/KeyboardTest/KeyboardTest.cpp | 8 +- .../TestCpp/Classes/KeypadTest/KeypadTest.cpp | 7 +- .../TestCpp/Classes/LabelTest/LabelTest.cpp | 9 +- .../Cpp/TestCpp/Classes/LabelTest/LabelTest.h | 6 +- .../Classes/LabelTest/LabelTestNew.cpp | 8 +- .../TestCpp/Classes/LabelTest/LabelTestNew.h | 6 +- .../TestCpp/Classes/LayerTest/LayerTest.cpp | 11 +- .../Cpp/TestCpp/Classes/LayerTest/LayerTest.h | 8 +- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp | 20 ++- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.h | 12 +- .../MotionStreakTest/MotionStreakTest.cpp | 6 +- .../Classes/MutiTouchTest/MutiTouchTest.cpp | 6 +- .../Classes/MutiTouchTest/MutiTouchTest.h | 1 - .../NewEventDispatcherTest.cpp | 87 +++++++++- .../NewEventDispatcherTest.h | 12 ++ .../Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp | 5 +- .../Cpp/TestCpp/Classes/NodeTest/NodeTest.h | 2 +- .../Classes/ParallaxTest/ParallaxTest.cpp | 4 +- .../Classes/ParallaxTest/ParallaxTest.h | 2 +- .../Classes/ParticleTest/ParticleTest.cpp | 6 +- .../Classes/ParticleTest/ParticleTest.h | 6 +- .../PerformanceTouchesTest.cpp | 41 +++-- .../PerformanceTest/PerformanceTouchesTest.h | 8 +- .../Classes/PhysicsTest/PhysicsTest.cpp | 9 +- .../RenderTextureTest/RenderTextureTest.cpp | 18 +- .../RenderTextureTest/RenderTextureTest.h | 10 +- .../SpriteTest/SpriteTest.cpp.REMOVED.git-id | 2 +- .../TestCpp/Classes/SpriteTest/SpriteTest.h | 2 +- .../Classes/TextInputTest/TextInputTest.cpp | 4 - .../Classes/TextInputTest/TextInputTest.h | 1 - .../Classes/TileMapTest/TileMapTest.cpp | 4 +- .../TestCpp/Classes/TileMapTest/TileMapTest.h | 2 +- samples/Cpp/TestCpp/Classes/controller.cpp | 2 - 57 files changed, 392 insertions(+), 226 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 7933a5edd6..05a2a66ddf 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -61,85 +61,6 @@ NS_CC_BEGIN static EventDispatcher* g_instance = nullptr; static int s_eventPriorityIndex = 0; -void EventDispatcher::visitTarget(Node* node) -{ - // Reset priority index - s_eventPriorityIndex = 0; - _nodePriorityMap.clear(); - - int i = 0; - Array* children = node->getChildren(); - int childrenCount = children ? children->count() : 0; - - if(childrenCount > 0) - { - - Node* child = nullptr; - // visit children zOrder < 0 - for( ; i < childrenCount; i++ ) - { - child = static_cast( children->getObjectAtIndex(i) ); - - if ( child && child->getZOrder() < 0 ) - visitTarget(child); - else - break; - } - - _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); - - for( ; i < childrenCount; i++ ) - { - child = static_cast( children->getObjectAtIndex(i) ); - if (child) - visitTarget(child); - } - } - else - { - _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); - } -} - -void EventDispatcher::pauseTarget(Node* node) -{ - auto listenerIter = _nodeListenersMap.find(node); - if (listenerIter != _nodeListenersMap.end()) - { - auto listeners = listenerIter->second; - for (auto& l : *listeners) - { - l->_paused = true; - } - } -} - -void EventDispatcher::resumeTarget(Node* node) -{ - auto listenerIter = _nodeListenersMap.find(node); - if (listenerIter != _nodeListenersMap.end()) - { - auto listeners = listenerIter->second; - for (auto& l : *listeners) - { - l->_paused = false; - } - } -} - -void EventDispatcher::cleanTarget(Node* node) -{ - auto listenerIter = _nodeListenersMap.find(node); - if (listenerIter != _nodeListenersMap.end()) - { - auto listeners = listenerIter->second; - for (auto& l : *listeners) - { - removeEventListener(l); - } - } -} - EventDispatcher::EventListenerVector::EventListenerVector() : _sceneGraphListeners(nullptr) , _fixedListeners(nullptr) @@ -239,6 +160,85 @@ void EventDispatcher::destroyInstance() CC_SAFE_DELETE(g_instance); } +void EventDispatcher::visitTarget(Node* node) +{ + // Reset priority index + s_eventPriorityIndex = 0; + _nodePriorityMap.clear(); + + int i = 0; + Array* children = node->getChildren(); + int childrenCount = children ? children->count() : 0; + + if(childrenCount > 0) + { + + Node* child = nullptr; + // visit children zOrder < 0 + for( ; i < childrenCount; i++ ) + { + child = static_cast( children->getObjectAtIndex(i) ); + + if ( child && child->getZOrder() < 0 ) + visitTarget(child); + else + break; + } + + _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); + + for( ; i < childrenCount; i++ ) + { + child = static_cast( children->getObjectAtIndex(i) ); + if (child) + visitTarget(child); + } + } + else + { + _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); + } +} + +void EventDispatcher::pauseTarget(Node* node) +{ + auto listenerIter = _nodeListenersMap.find(node); + if (listenerIter != _nodeListenersMap.end()) + { + auto listeners = listenerIter->second; + for (auto& l : *listeners) + { + l->_paused = true; + } + } +} + +void EventDispatcher::resumeTarget(Node* node) +{ + auto listenerIter = _nodeListenersMap.find(node); + if (listenerIter != _nodeListenersMap.end()) + { + auto listeners = listenerIter->second; + for (auto& l : *listeners) + { + l->_paused = false; + } + } +} + +void EventDispatcher::cleanTarget(Node* node) +{ + auto listenerIter = _nodeListenersMap.find(node); + if (listenerIter != _nodeListenersMap.end()) + { + auto listeners = listenerIter->second; + for (auto& l : *listeners) + { + removeEventListener(l); + } + } +} + void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener) { std::vector* listeners = nullptr; @@ -635,7 +635,6 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) { if (listener->onTouchBegan) { - CCLOG("onTouchBegan..."); isClaimed = listener->onTouchBegan(*touchesIter, event); if (isClaimed && listener->_isRegistered) { diff --git a/cocos/2d/CCEventListenerTouch.h b/cocos/2d/CCEventListenerTouch.h index d34de1b237..09e6e6fe0c 100644 --- a/cocos/2d/CCEventListenerTouch.h +++ b/cocos/2d/CCEventListenerTouch.h @@ -33,7 +33,6 @@ NS_CC_BEGIN - class EventListenerTouchOneByOne : public EventListener { public: diff --git a/cocos/2d/CCMenu.h b/cocos/2d/CCMenu.h index a735d138db..64c275841a 100644 --- a/cocos/2d/CCMenu.h +++ b/cocos/2d/CCMenu.h @@ -112,6 +112,11 @@ public: virtual bool isEnabled() const { return _enabled; } virtual void setEnabled(bool value) { _enabled = value; }; + virtual bool onTouchBegan(Touch* touch, Event* event); + virtual void onTouchEnded(Touch* touch, Event* event); + virtual void onTouchCancelled(Touch* touch, Event* event); + virtual void onTouchMoved(Touch* touch, Event* event); + // overrides virtual void removeChild(Node* child, bool cleanup) override; @@ -119,11 +124,6 @@ public: virtual void addChild(Node * child, int zOrder) override; virtual void addChild(Node * child, int zOrder, int tag) override; - virtual bool onTouchBegan(Touch* touch, Event* event); - virtual void onTouchEnded(Touch* touch, Event* event); - virtual void onTouchCancelled(Touch* touch, Event* event); - virtual void onTouchMoved(Touch* touch, Event* event); - virtual void onEnter() override; virtual void onExit() override; virtual void setOpacityModifyRGB(bool bValue) override {CC_UNUSED_PARAM(bValue);} diff --git a/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h b/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h index a5f2478391..279f2c4399 100644 --- a/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h +++ b/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h @@ -30,7 +30,7 @@ public: void updateGame(float dt); - virtual void onTouchesEnded(const std::vector& touches, cocos2d::Event* event) override; + void onTouchesEnded(const std::vector& touches, cocos2d::Event* event) override; protected: diff --git a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp index 0e7a14ffdf..c41f06c377 100644 --- a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp @@ -1375,7 +1375,9 @@ void ActionStacked::onEnter() this->centerSprites(0); -//cjh this->setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(ActionStacked::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); this->addNewSpriteWithCoords(Point(s.width/2, s.height/2)); diff --git a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.h b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.h index c064ee3436..f67907ceba 100644 --- a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.h +++ b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.h @@ -305,7 +305,7 @@ public: virtual std::string subtitle(); virtual void addNewSpriteWithCoords(Point p); virtual void runActionsInSprite(Sprite* sprite); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); }; class ActionMoveStacked : public ActionStacked diff --git a/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h b/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h index 480d572f7a..5c22274ba3 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h +++ b/samples/Cpp/TestCpp/Classes/Box2DTest/Box2dTest.h @@ -21,7 +21,7 @@ public: void addNewSpriteAtPosition(Point p); void update(float dt); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); //CREATE_NODE(Box2DTestLayer); } ; diff --git a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp index 9614180fb2..0cfbabd90c 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp +++ b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp @@ -176,9 +176,6 @@ Box2DView* Box2DView::viewWithEntryID(int entryId) bool Box2DView::initWithEntryID(int entryId) { -// setIsAccelerometerEnabled( true ); -// FIXME cjh: setTouchEnabled( true ); - schedule( schedule_selector(Box2DView::tick) ); m_entry = g_testEntries + entryId; diff --git a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h index 681e44de6c..d2afa656d6 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h +++ b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.h @@ -19,8 +19,8 @@ public: void backCallback(Object* sender); - virtual bool onTouchBegan(Touch* touch, Event* event); - virtual void onTouchMoved(Touch* touch, Event* event); + bool onTouchBegan(Touch* touch, Event* event); + void onTouchMoved(Touch* touch, Event* event); public: static MenuLayer* menuWithEntryID(int entryId); @@ -44,9 +44,9 @@ public: void draw(); // virtual void registerWithTouchDispatcher(); - virtual bool onTouchBegan(Touch* touch, Event* event); - virtual void onTouchMoved(Touch* touch, Event* event); - virtual void onTouchEnded(Touch* touch, Event* event); + bool onTouchBegan(Touch* touch, Event* event); + void onTouchMoved(Touch* touch, Event* event); + void onTouchEnded(Touch* touch, Event* event); //virtual void accelerometer(UIAccelerometer* accelerometer, Acceleration* acceleration); static Box2DView* viewWithEntryID(int entryId); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h index 41ee2c25c8..d6af9092fe 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.h @@ -9,8 +9,8 @@ public: static Scene* scene(); virtual bool init(); - virtual void onTouchesMoved(const std::vector& touches, Event * event); - virtual void onTouchesBegan(const std::vector& touches, Event * event); + void onTouchesMoved(const std::vector& touches, Event * event); + void onTouchesBegan(const std::vector& touches, Event * event); void restart(Object* sender); CREATE_FUNC(Bug914Layer); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp index 7f28de8df8..1d81217bbb 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp @@ -67,7 +67,12 @@ void BugsTestMainLayer::onEnter() _itmeMenu->setPosition(s_tCurPos); addChild(_itmeMenu); -//cjh setTouchEnabled(true); + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(BugsTestMainLayer::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(BugsTestMainLayer::onTouchesMoved, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); } void BugsTestMainLayer::onTouchesBegan(const std::vector& touches, Event *event) diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h index 88de62b0a1..06e6fb535c 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h +++ b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.h @@ -8,8 +8,8 @@ class BugsTestMainLayer : public Layer public: virtual void onEnter(); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector&touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector&touches, Event *event); protected: Point _beginPos; diff --git a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp index 46cae7762e..bb3ef0e12f 100644 --- a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp @@ -21,9 +21,14 @@ ChipmunkTestLayer::ChipmunkTestLayer() { #if CC_ENABLE_CHIPMUNK_INTEGRATION // enable events -//FIXME: setTouchEnabled(true); -// setAccelerometerEnabled(true); + auto touchListener = EventListenerTouchAllAtOnce::create(); + touchListener->onTouchesEnded = CC_CALLBACK_2(ChipmunkTestLayer::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(touchListener, this); + + auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(ChipmunkTestLayer::onAcceleration, this)); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(accListener, this); + // title auto label = LabelTTF::create("Multi touch the screen", "Marker Felt", 36); label->setPosition(Point( VisibleRect::center().x, VisibleRect::top().y - 30)); diff --git a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h index 3480f0314a..046f53d3fa 100644 --- a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h +++ b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.h @@ -24,7 +24,7 @@ public: void addNewSpriteAtPosition(Point p); void update(float dt); void toggleDebugCallback(Object* sender); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); virtual void onAcceleration(Acceleration* acc, Event* event); private: diff --git a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h index 7cb8f7a3b4..833ced291e 100644 --- a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h +++ b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.h @@ -13,8 +13,8 @@ class MainLayer : public Layer { public: MainLayer(); - virtual bool onTouchBegan(Touch* touch, Event *event); - virtual void onTouchEnded(Touch* touch, Event *event); + bool onTouchBegan(Touch* touch, Event *event); + void onTouchEnded(Touch* touch, Event *event); }; #endif diff --git a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h index 0cb0c21d6d..042e51ddf6 100644 --- a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h +++ b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.h @@ -98,7 +98,7 @@ public: virtual std::string title(); virtual std::string subtitle(); void pokeHoleAtPoint(Point point); - virtual void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); private: ClippingNode* _outerClipper; Node* _holes; @@ -111,9 +111,9 @@ public: virtual std::string title(); virtual std::string subtitle(); virtual void setup(); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); - virtual void onTouchesEnded(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); private: bool _scrolling; Point _lastPoint; diff --git a/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp b/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp index 9589cde586..e83cb001f1 100644 --- a/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp +++ b/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp @@ -227,19 +227,6 @@ _sliderMusicVolume(NULL) addSliders(); schedule(schedule_selector(CocosDenshionTest::updateVolumes)); -// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); - -// std::string testItems[] = { -// "unload effect", -// "pause effect", -// "resume effect", -// "pause all effects", -// "resume all effects", -// "stop all effects" -// }; - -//cjh setTouchEnabled(true); - // preload background music and effect SimpleAudioEngine::getInstance()->preloadBackgroundMusic( MUSIC_FILE ); SimpleAudioEngine::getInstance()->preloadEffect( EFFECT_FILE ); diff --git a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp index 83945cd581..f3ad65db63 100644 --- a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp +++ b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp @@ -9,7 +9,9 @@ CurlTest::CurlTest() addChild(label, 0); label->setPosition( Point(VisibleRect::center().x, VisibleRect::top().y-50) ); -//FIXME cjh: setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(CurlTest::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); // create a label to display the tip string _label = LabelTTF::create("Touch the screen to connect", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h index 9688d03e38..131e3b330a 100644 --- a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h +++ b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.h @@ -10,7 +10,7 @@ public: CurlTest(); ~CurlTest(); - virtual void onTouchesEnded(const std::vector& touches, cocos2d::Event *event); + void onTouchesEnded(const std::vector& touches, cocos2d::Event *event); private: cocos2d::LabelTTF* _label; diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp index eaf14546be..fef387ac01 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp @@ -477,7 +477,10 @@ void TestAnimationEvent::callback2() void TestParticleDisplay::onEnter() { ArmatureTestLayer::onEnter(); -//FIXME cjh: setTouchEnabled(true); + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(TestParticleDisplay::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); animationID = 0; @@ -534,8 +537,11 @@ void TestParticleDisplay::onTouchesEnded(const std::vector& touches, Eve void TestUseMutiplePicture::onEnter() { ArmatureTestLayer::onEnter(); -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(TestUseMutiplePicture::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + displayIndex = 0; armature = Armature::create("Knight_f/Knight"); @@ -935,7 +941,10 @@ std::string TestAnchorPoint::title() void TestArmatureNesting::onEnter() { ArmatureTestLayer::onEnter(); -//cjh setTouchEnabled(true); + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(TestArmatureNesting::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); armature = Armature::create("cyborg"); armature->getAnimation()->playByIndex(1); diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h index ccd07d1d72..51b47085b5 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h @@ -138,7 +138,7 @@ class TestUseMutiplePicture : public ArmatureTestLayer virtual void onExit(); virtual std::string title(); virtual std::string subtitle(); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); int displayIndex; cocostudio::Armature *armature; @@ -150,7 +150,7 @@ class TestParticleDisplay : public ArmatureTestLayer virtual void onExit(); virtual std::string title(); virtual std::string subtitle(); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); int animationID; cocostudio::Armature *armature; @@ -251,7 +251,7 @@ public: virtual void onEnter(); virtual void onExit(); virtual std::string title(); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); cocostudio::Armature *armature; int weaponIndex; diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioComponentsTest/PlayerController.h b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioComponentsTest/PlayerController.h index 671bdf7833..cc5233b539 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioComponentsTest/PlayerController.h +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioComponentsTest/PlayerController.h @@ -13,7 +13,7 @@ protected: virtual ~PlayerController(void); public: - virtual void onTouchesEnded(const std::vector& touches, cocos2d::Event *event) override; + void onTouchesEnded(const std::vector& touches, cocos2d::Event *event) override; public: virtual bool init(); diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp index 7c95239cfa..5ba010f2a9 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp @@ -118,7 +118,11 @@ void ExtensionsMainLayer::onEnter() _itemMenu->addChild(pItem, kItemTagBasic + i); } -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(ExtensionsMainLayer::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(ExtensionsMainLayer::onTouchesMoved, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); addChild(_itemMenu); } diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h index 0b392e4326..abf411fbce 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h @@ -8,8 +8,8 @@ class ExtensionsMainLayer : public Layer public: virtual void onEnter(); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); Point _beginPos; Menu* _itemMenu; diff --git a/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp b/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp index 7140a44e8a..a8a164da01 100644 --- a/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp +++ b/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp @@ -7,8 +7,12 @@ KeyboardTest::KeyboardTest() addChild(label, 0); label->setPosition( Point(s.width/2, s.height-50) ); -//cjh setKeyboardEnabled(true); - + auto listener = EventListenerKeyboard::create(); + listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this); + listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + // create a label to display the tip string _label = LabelTTF::create("Please press any key and see console log...", "Arial", 22); _label->setPosition(Point(s.width / 2, s.height / 2)); diff --git a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp index 5bda6cccf2..c3191d5724 100644 --- a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp +++ b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp @@ -7,8 +7,11 @@ KeypadTest::KeypadTest() addChild(label, 0); label->setPosition( Point(s.width/2, s.height-50) ); -//cjh setKeyboardEnabled(true); - + auto listener = EventListenerKeyboard::create(); + listener->onKeyReleased = CC_CALLBACK_2(KeypadTest::onKeyReleased, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + // create a label to display the tip string _label = LabelTTF::create("Please press any key...", "Arial", 22); _label->setPosition(Point(s.width / 2, s.height / 2)); diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp index 52fc92c2e4..f95831074e 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp @@ -1135,8 +1135,13 @@ static float alignmentItemPadding = 50; static float menuItemPaddingCenter = 50; BitmapFontMultiLineAlignment::BitmapFontMultiLineAlignment() { -//cjh this->setTouchEnabled(true); - + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(BitmapFontMultiLineAlignment::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(BitmapFontMultiLineAlignment::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(BitmapFontMultiLineAlignment::onTouchesEnded, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.h b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.h index 49b121628d..87ff938c97 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.h +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.h @@ -228,9 +228,9 @@ public: virtual std::string subtitle(); void stringChanged(Object *sender); void alignmentChanged(Object *sender); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesEnded(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); public: LabelBMFont *_labelShouldRetain; diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp index 47173da112..d6d5777ada 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp @@ -650,8 +650,12 @@ static float menuItemPaddingCenter = 50; LabelFNTMultiLineAlignment::LabelFNTMultiLineAlignment() { -//cjh this->setTouchEnabled(true); - + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(LabelFNTMultiLineAlignment::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(LabelFNTMultiLineAlignment::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(LabelFNTMultiLineAlignment::onTouchesEnded, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.h b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.h index 1a8035b15f..d494858ffa 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.h +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.h @@ -156,9 +156,9 @@ public: virtual std::string subtitle(); void stringChanged(Object *sender); void alignmentChanged(Object *sender); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesEnded(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); public: Label *_labelShouldRetain; diff --git a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp index e27b82cf16..9fcc560cdf 100644 --- a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp +++ b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp @@ -449,7 +449,12 @@ void LayerTest1::onEnter() { LayerTest::onEnter(); -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(LayerTest1::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(LayerTest1::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(LayerTest1::onTouchesEnded, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); auto layer = LayerColor::create( Color4B(0xFF, 0x00, 0x00, 0x80), 200, 200); @@ -590,7 +595,9 @@ LayerGradientTest::LayerGradientTest() auto layer1 = LayerGradient::create(Color4B(255,0,0,255), Color4B(0,255,0,255), Point(0.9f, 0.9f)); addChild(layer1, 0, kTagLayer); -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesMoved = CC_CALLBACK_2(LayerGradientTest::onTouchesMoved, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); auto label1 = LabelTTF::create("Compressed Interpolation: Enabled", "Marker Felt", 26); auto label2 = LabelTTF::create("Compressed Interpolation: Disabled", "Marker Felt", 26); diff --git a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.h b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.h index fbed1e7e91..dd381b001f 100644 --- a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.h +++ b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.h @@ -74,9 +74,9 @@ public: void updateSize(Point &touchLocation); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); - virtual void onTouchesEnded(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); }; class LayerTest2 : public LayerTest @@ -99,7 +99,7 @@ class LayerGradientTest : public LayerTest { public: LayerGradientTest(); - virtual void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); virtual std::string title(); virtual std::string subtitle(); void toggleItem(cocos2d::Object *sender); diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp index a61f15225b..e1fb43cf39 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp @@ -25,8 +25,13 @@ enum { //------------------------------------------------------------------ MenuLayerMainMenu::MenuLayerMainMenu() { -//cjh setTouchEnabled(true); -// setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = CC_CALLBACK_2(MenuLayerMainMenu::onTouchBegan, this); + listener->onTouchMoved = CC_CALLBACK_2(MenuLayerMainMenu::onTouchMoved, this); + listener->onTouchEnded = CC_CALLBACK_2(MenuLayerMainMenu::onTouchEnded, this); + listener->onTouchCancelled = CC_CALLBACK_2(MenuLayerMainMenu::onTouchCancelled, this); + + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); // Font Item auto spriteNormal = Sprite::create(s_MenuItem, Rect(0,23*2,115,23)); @@ -532,8 +537,8 @@ BugsTest::BugsTest() void BugsTest::issue1410MenuCallback(Object *sender) { auto menu = static_cast( static_cast(sender)->getParent() ); -//cjh menu->setTouchEnabled(false); -// menu->setTouchEnabled(true); + menu->setEnabled(false); + menu->setEnabled(true); log("NO CRASHES"); } @@ -541,8 +546,8 @@ void BugsTest::issue1410MenuCallback(Object *sender) void BugsTest::issue1410v2MenuCallback(cocos2d::Object *pSender) { auto menu = static_cast( static_cast(pSender)->getParent() ); -//cjh menu->setTouchEnabled(true); -// menu->setTouchEnabled(false); + menu->setEnabled(true); + menu->setEnabled(false); log("NO CRASHES. AND MENU SHOULD STOP WORKING"); } @@ -571,9 +576,6 @@ RemoveMenuItemWhenMove::RemoveMenuItemWhenMove() menu->setPosition(Point(s.width/2, s.height/2)); -//cjh setTouchEnabled(true); -// setTouchMode(Touch::DispatchMode::ONE_BY_ONE); - // Register Touch Event _touchListener = EventListenerTouchOneByOne::create(); _touchListener->setSwallowTouches(false); diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h index 41072151c5..127f8c1688 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h @@ -14,10 +14,10 @@ public: ~MenuLayerMainMenu(); public: - virtual bool onTouchBegan(Touch *touch, Event * event); - virtual void onTouchEnded(Touch *touch, Event * event); - virtual void onTouchCancelled(Touch *touch, Event * event); - virtual void onTouchMoved(Touch *touch, Event * event); + bool onTouchBegan(Touch *touch, Event * event); + void onTouchEnded(Touch *touch, Event * event); + void onTouchCancelled(Touch *touch, Event * event); + void onTouchMoved(Touch *touch, Event * event); void allowTouches(float dt); void menuCallback(Object* sender); @@ -106,8 +106,8 @@ class RemoveMenuItemWhenMove : public Layer public: RemoveMenuItemWhenMove(); ~RemoveMenuItemWhenMove(); - virtual bool onTouchBegan(Touch *touch, Event *event); - virtual void onTouchMoved(Touch *touch, Event *event); + bool onTouchBegan(Touch *touch, Event *event); + void onTouchMoved(Touch *touch, Event *event); void goBack(Object *pSender); diff --git a/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp b/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp index 7c4fe4340f..13a376ec29 100644 --- a/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp @@ -121,8 +121,10 @@ void MotionStreakTest2::onEnter() { MotionStreakTest::onEnter(); -//cjh setTouchEnabled(true); - + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesMoved = CC_CALLBACK_2(MotionStreakTest2::onTouchesMoved, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + auto s = Director::getInstance()->getWinSize(); // create the streak object and add it to the scene diff --git a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp index f92fa93299..42e6634de5 100644 --- a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp @@ -56,7 +56,11 @@ bool MutiTouchTestLayer::init() { if (Layer::init()) { -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(MutiTouchTestLayer::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(MutiTouchTestLayer::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(MutiTouchTestLayer::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); auto title = LabelTTF::create("Please touch the screen!", "", 24); title->setPosition(VisibleRect::top()+Point(0, -40)); diff --git a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.h b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.h index 397f9ae276..91333d6493 100644 --- a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.h +++ b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.h @@ -8,7 +8,6 @@ class MutiTouchTestLayer : public Layer public: bool init(); -// virtual void registerWithTouchDispatcher(void); void onTouchesBegan(const std::vector& touches, cocos2d::Event *event); void onTouchesMoved(const std::vector& touches, cocos2d::Event *event); void onTouchesEnded(const std::vector& touches, cocos2d::Event *event); diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 797f042ca7..d44129aee5 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -18,7 +18,8 @@ std::function createFunctions[] = CL(RemoveListenerWhenDispatching), CL(CustomEventTest), CL(LabelKeyboardEventTest), - CL(SpriteAccelerationEventTest) + CL(SpriteAccelerationEventTest), + CL(RemoveAndRetainNodeTest) }; unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); @@ -565,4 +566,88 @@ std::string SpriteAccelerationEventTest::title() std::string SpriteAccelerationEventTest::subtitle() { return "Please move your device\n(Only available on mobile)"; +} + +// RemoveAndRetainNodeTest +void RemoveAndRetainNodeTest::onEnter() +{ + _spriteSaved = false; + + EventDispatcherTestDemo::onEnter(); + + auto dispatcher = EventDispatcher::getInstance(); + + Point origin = Director::getInstance()->getVisibleOrigin(); + Size size = Director::getInstance()->getVisibleSize(); + + _sprite = Sprite::create("Images/CyanSquare.png"); + _sprite->setPosition(origin+Point(size.width/2, size.height/2)); + addChild(_sprite, 10); + + // Make sprite1 touchable + auto listener1 = EventListenerTouchOneByOne::create(); + listener1->setSwallowTouches(true); + + listener1->onTouchBegan = [](Touch* touch, Event* event){ + auto target = static_cast(event->getCurrentTarget()); + + Point locationInNode = target->convertToNodeSpace(touch->getLocation()); + Size s = target->getContentSize(); + Rect rect = Rect(0, 0, s.width, s.height); + + if (rect.containsPoint(locationInNode)) + { + log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y); + target->setOpacity(180); + return true; + } + return false; + }; + + listener1->onTouchMoved = [](Touch* touch, Event* event){ + auto target = static_cast(event->getCurrentTarget()); + target->setPosition(target->getPosition() + touch->getDelta()); + }; + + listener1->onTouchEnded = [=](Touch* touch, Event* event){ + auto target = static_cast(event->getCurrentTarget()); + log("sprite onTouchesEnded.. "); + target->setOpacity(255); + }; + + dispatcher->addEventListenerWithSceneGraphPriority(listener1, _sprite); + + this->runAction(Sequence::create(DelayTime::create(5.0f), + CallFunc::create([this](){ + _spriteSaved = true; + _sprite->retain(); + _sprite->removeFromParent(); + }), + DelayTime::create(5.0f), + CallFunc::create([this](){ + _spriteSaved = false; + this->addChild(_sprite); + _sprite->release(); + }), + nullptr + )); +} + +void RemoveAndRetainNodeTest::onExit() +{ + EventDispatcherTestDemo::onExit(); + if (_spriteSaved) + { + _sprite->release(); + } +} + +std::string RemoveAndRetainNodeTest::title() +{ + return "RemoveAndRetainNodeTest"; +} + +std::string RemoveAndRetainNodeTest::subtitle() +{ + return ""; } \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index 2f5c186438..9af7022bde 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -83,4 +83,16 @@ public: virtual std::string subtitle() override; }; +class RemoveAndRetainNodeTest : public EventDispatcherTestDemo +{ +public: + virtual void onEnter() override; + virtual void onExit() override; + virtual std::string title() override; + virtual std::string subtitle() override; +private: + Sprite* _sprite; + bool _spriteSaved; +}; + #endif /* defined(__samples__NewEventDispatcherTest__) */ diff --git a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp index db7f53d7c2..3276a9b620 100644 --- a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp @@ -723,7 +723,10 @@ std::string CameraCenterTest::subtitle() //------------------------------------------------------------------ ConvertToNode::ConvertToNode() { -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(ConvertToNode::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + auto s = Director::getInstance()->getWinSize(); auto rotate = RotateBy::create(10, 360); diff --git a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.h b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.h index b99892e7ee..6bf14f8d5c 100644 --- a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.h +++ b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.h @@ -125,7 +125,7 @@ class ConvertToNode : public TestCocosNodeDemo { public: ConvertToNode(); - virtual void onTouchesEnded(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); virtual std::string title(); virtual std::string subtitle(); }; diff --git a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp index bc2a128603..e14105b62e 100644 --- a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp @@ -87,7 +87,9 @@ std::string Parallax1::title() Parallax2::Parallax2() { -//cjh setTouchEnabled( true ); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesMoved = CC_CALLBACK_2(Parallax2::onTouchesMoved, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); // Top Layer, a simple image auto cocosImage = Sprite::create(s_Power); diff --git a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.h b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.h index 5d4b6da085..905e34beae 100644 --- a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.h +++ b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.h @@ -43,7 +43,7 @@ protected: public: Parallax2(); - virtual void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); virtual std::string title(); }; diff --git a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp index 414c915135..9e35114538 100644 --- a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp @@ -1068,7 +1068,11 @@ void ParticleDemo::onEnter(void) _emitter = NULL; -//cjh setTouchEnabled( true ); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(ParticleDemo::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(ParticleDemo::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(ParticleDemo::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.h b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.h index c17d8bc73a..4c9e63047f 100644 --- a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.h +++ b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.h @@ -33,9 +33,9 @@ public: void backCallback(Object* sender); void toggleCallback(Object* sender); - virtual void onTouchesBegan(const std::vector& touches, Event *event); - virtual void onTouchesMoved(const std::vector& touches, Event *event); - virtual void onTouchesEnded(const std::vector& touches, Event *event); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); virtual void update(float dt); void setEmitterPosition(); diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp index a928a3bd23..5f1e9566ab 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp @@ -119,9 +119,13 @@ std::string TouchesMainScene::title() void TouchesPerformTest1::onEnter() { TouchesMainScene::onEnter(); -//cjh setTouchEnabled(true); -// setTouchMode(Touch::DispatchMode::ONE_BY_ONE); -// setSwallowsTouches(true); + auto listener = EventListenerTouchOneByOne::create(); + listener->setSwallowTouches(true); + listener->onTouchBegan = CC_CALLBACK_2(TouchesPerformTest1::onTouchBegan, this); + listener->onTouchMoved = CC_CALLBACK_2(TouchesPerformTest1::onTouchMoved, this); + listener->onTouchEnded = CC_CALLBACK_2(TouchesPerformTest1::onTouchEnded, this); + listener->onTouchCancelled = CC_CALLBACK_2(TouchesPerformTest1::onTouchCancelled, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); } std::string TouchesPerformTest1::title() @@ -158,7 +162,13 @@ void TouchesPerformTest1::onTouchCancelled(Touch* touch, Event* event) void TouchesPerformTest2::onEnter() { TouchesMainScene::onEnter(); -//cjh setTouchEnabled(true); + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(TouchesPerformTest2::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(TouchesPerformTest2::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(TouchesPerformTest2::onTouchesEnded, this); + listener->onTouchesCancelled = CC_CALLBACK_2(TouchesPerformTest2::onTouchesCancelled, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); } std::string TouchesPerformTest2::title() @@ -194,18 +204,13 @@ void TouchesPerformTest2::onTouchesCancelled(const std::vector& touches, class TouchableLayer : public Layer { public: - virtual bool onTouchBegan(Touch *touch, Event *event) + bool onTouchBegan(Touch *touch, Event *event) { return false; } - virtual void onTouchMoved(Touch *touch, Event *event) {} - virtual void onTouchEnded(Touch *touch, Event *event) {} - virtual void onTouchCancelled(Touch *touch, Event *event) {} - - virtual void onTouchesBegan(const std::vector& touches, Event *event) {} - virtual void onTouchesMoved(const std::vector& touches, Event *event) {} - virtual void onTouchesEnded(const std::vector& touches, Event *event) {} - virtual void onTouchesCancelled(const std::vector&touches, Event *event) {} + void onTouchMoved(Touch *touch, Event *event) {} + void onTouchEnded(Touch *touch, Event *event) {} + void onTouchCancelled(Touch *touch, Event *event) {} }; @@ -231,8 +236,14 @@ void TouchesPerformTest3::onEnter() { int zorder = rand() % TOUCHABLE_NODE_NUM; auto layer = new TouchableLayer(); -//cjh layer->setTouchEnabled(true); -// layer->setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = CC_CALLBACK_2(TouchableLayer::onTouchBegan, layer); + listener->onTouchMoved = CC_CALLBACK_2(TouchableLayer::onTouchMoved, layer); + listener->onTouchEnded = CC_CALLBACK_2(TouchableLayer::onTouchEnded, layer); + listener->onTouchCancelled = CC_CALLBACK_2(TouchableLayer::onTouchCancelled, layer); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, layer); + addChild(layer, zorder); layer->release(); } diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h index 5cb4d35ad9..11a93ca3ee 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.h @@ -36,10 +36,10 @@ public: virtual void onEnter() override; virtual std::string title() override; - virtual bool onTouchBegan(Touch* touch, Event* event) ; - virtual void onTouchMoved(Touch* touch, Event* event) ; - virtual void onTouchEnded(Touch* touch, Event* event) ; - virtual void onTouchCancelled(Touch* touch, Event* event) ; + bool onTouchBegan(Touch* touch, Event* event) ; + void onTouchMoved(Touch* touch, Event* event) ; + void onTouchEnded(Touch* touch, Event* event) ; + void onTouchCancelled(Touch* touch, Event* event) ; }; class TouchesPerformTest2 : public TouchesMainScene diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 4c56986746..59513a0835 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -197,8 +197,13 @@ void PhysicsDemoClickAdd::onEnter() PhysicsDemo::onEnter(); #ifdef CC_USE_PHYSICS -//cjh setTouchEnabled(true); -// setAccelerometerEnabled(true); + + auto touchListener = EventListenerTouchAllAtOnce::create(); + touchListener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoClickAdd::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(touchListener, this); + + auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(PhysicsDemoClickAdd::onAcceleration, this)); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(accListener, this); auto node = Node::create(); node->setPhysicsBody(PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size)); diff --git a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp index 1669b78c1f..113d4adad3 100644 --- a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp +++ b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp @@ -111,8 +111,11 @@ RenderTextureSave::RenderTextureSave() _brush->retain(); _brush->setColor(Color3B::RED); _brush->setOpacity(20); -//cjh this->setTouchEnabled(true); - + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesMoved = CC_CALLBACK_2(RenderTextureSave::onTouchesMoved, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + // Save Image menu MenuItemFont::setFontSize(16); auto item1 = MenuItemFont::create("Save Image", CC_CALLBACK_1(RenderTextureSave::saveImage, this)); @@ -296,7 +299,12 @@ void RenderTextureScene::runThisTest() RenderTextureZbuffer::RenderTextureZbuffer() { -//cjh this->setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + auto size = Director::getInstance()->getWinSize(); auto label = LabelTTF::create("vertexZ = 50", "Marker Felt", 64); label->setPosition(Point(size.width / 2, size.height * 0.25f)); @@ -627,7 +635,9 @@ void SpriteRenderTextureBug::SimpleSprite::draw() SpriteRenderTextureBug::SpriteRenderTextureBug() { -//cjh setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(SpriteRenderTextureBug::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); addNewSpriteWithCoords(Point(s.width/2, s.height/2)); diff --git a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h index b6ce107092..afd985ec70 100644 --- a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h +++ b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h @@ -24,7 +24,7 @@ public: ~RenderTextureSave(); virtual std::string title(); virtual std::string subtitle(); - virtual void onTouchesMoved(const std::vector& touches, Event* event); + void onTouchesMoved(const std::vector& touches, Event* event); void clearImage(Object *pSender); void saveImage(Object *pSender); @@ -52,9 +52,9 @@ class RenderTextureZbuffer : public RenderTextureTest public: RenderTextureZbuffer(); - virtual void onTouchesMoved(const std::vector& touches, Event* event); - virtual void onTouchesBegan(const std::vector& touches, Event* event); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesMoved(const std::vector& touches, Event* event); + void onTouchesBegan(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); virtual std::string title(); virtual std::string subtitle(); @@ -116,7 +116,7 @@ class SimpleSprite : public Sprite public: SpriteRenderTextureBug(); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); virtual std::string title(); virtual std::string subtitle(); diff --git a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id index a3d466373a..ee1480acae 100644 --- a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id +++ b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id @@ -1 +1 @@ -4701ba8fb99f70629c5575dcf6fb3536543ac0b6 \ No newline at end of file +fdf35bd639fd5d617e5a280530d6aefe63b94857 \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.h b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.h index 413ba75e8b..ca08fb64e3 100644 --- a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.h +++ b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.h @@ -39,7 +39,7 @@ class SpriteBatchNode1: public SpriteTestDemo public: SpriteBatchNode1(); void addNewSpriteWithCoords(Point p); - virtual void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); virtual std::string title(); }; diff --git a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp index 1645d017d8..b922271656 100644 --- a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp +++ b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp @@ -126,14 +126,10 @@ void TextInputTest::onEnter() KeyboardNotificationLayer::KeyboardNotificationLayer() : _trackNode(0) { -//cjh setTouchEnabled(true); - // Register Touch Event auto listener = EventListenerTouchOneByOne::create(); - listener->onTouchBegan = CC_CALLBACK_2(KeyboardNotificationLayer::onTouchBegan, this); listener->onTouchEnded = CC_CALLBACK_2(KeyboardNotificationLayer::onTouchEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); } diff --git a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.h b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.h index 65cfb27d9a..7da7b893a1 100644 --- a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.h +++ b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.h @@ -37,7 +37,6 @@ public: virtual std::string subtitle() = 0; virtual void onClickTrackNode(bool bClicked) = 0; -// virtual void registerWithTouchDispatcher(); virtual void keyboardWillShow(IMEKeyboardNotificationInfo& info); // Layer diff --git a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp index 7be2b29c32..48ed771306 100644 --- a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp +++ b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp @@ -1430,7 +1430,9 @@ Layer* restartTileMapAction() TileDemo::TileDemo(void) : BaseTest() { -//cjh setTouchEnabled( true ); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesMoved = CC_CALLBACK_2(TileDemo::onTouchesMoved, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); } TileDemo::~TileDemo(void) diff --git a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.h b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.h index e0039525a3..3331292415 100644 --- a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.h +++ b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.h @@ -18,7 +18,7 @@ public: void nextCallback(Object* sender); void backCallback(Object* sender); - virtual void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); }; class TileMapTest : public TileDemo diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index c7b03f1acf..fcd140e4f3 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -120,8 +120,6 @@ TestController::TestController() _itemMenu->setPosition(s_tCurPos); addChild(_itemMenu); -//cjh setTouchEnabled(true); - addChild(menu, 1); // Register Touch Event From 6f9bee5b1a0b2ee66e6614e3f0a31817506b670e Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 16:28:38 +0800 Subject: [PATCH 024/144] bug fix in EventDispatcher. --- cocos/2d/CCEventDispatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 05a2a66ddf..ca28314d8c 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -436,7 +436,7 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority) auto found = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener); if (found != fixedPriorityListeners->end()) { - CCASSERT(listener->_node, "Can't set fixed priority with scene graph based listener."); + CCASSERT(listener->_node == nullptr, "Can't set fixed priority with scene graph based listener."); if (listener->_fixedPriority != fixedPriority) { From b131e8c5095cccaa97ce3d08729bef76a5875213 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 16:28:54 +0800 Subject: [PATCH 025/144] Update menu test. --- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp | 19 +++++++++---------- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.h | 1 + 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp index e1fb43cf39..7edfb6fe4e 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp @@ -25,13 +25,14 @@ enum { //------------------------------------------------------------------ MenuLayerMainMenu::MenuLayerMainMenu() { - auto listener = EventListenerTouchOneByOne::create(); - listener->onTouchBegan = CC_CALLBACK_2(MenuLayerMainMenu::onTouchBegan, this); - listener->onTouchMoved = CC_CALLBACK_2(MenuLayerMainMenu::onTouchMoved, this); - listener->onTouchEnded = CC_CALLBACK_2(MenuLayerMainMenu::onTouchEnded, this); - listener->onTouchCancelled = CC_CALLBACK_2(MenuLayerMainMenu::onTouchCancelled, this); + _touchListener = EventListenerTouchOneByOne::create(); + _touchListener->setSwallowTouches(true); + _touchListener->onTouchBegan = CC_CALLBACK_2(MenuLayerMainMenu::onTouchBegan, this); + _touchListener->onTouchMoved = CC_CALLBACK_2(MenuLayerMainMenu::onTouchMoved, this); + _touchListener->onTouchEnded = CC_CALLBACK_2(MenuLayerMainMenu::onTouchEnded, this); + _touchListener->onTouchCancelled = CC_CALLBACK_2(MenuLayerMainMenu::onTouchCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + EventDispatcher::getInstance()->addEventListenerWithFixedPriority(_touchListener, 1); // Font Item auto spriteNormal = Sprite::create(s_MenuItem, Rect(0,23*2,115,23)); @@ -152,8 +153,7 @@ void MenuLayerMainMenu::menuCallbackConfig(Object* sender) void MenuLayerMainMenu::allowTouches(float dt) { -// auto director = Director::getInstance(); -// director->getTouchDispatcher()->setPriority(Menu::HANDLER_PRIORITY+1, this); + EventDispatcher::getInstance()->setPriority(_touchListener, 1); unscheduleAllSelectors(); log("TOUCHES ALLOWED AGAIN"); } @@ -161,8 +161,7 @@ void MenuLayerMainMenu::allowTouches(float dt) void MenuLayerMainMenu::menuCallbackDisabled(Object* sender) { // hijack all touch events for 5 seconds -// auto director = Director::getInstance(); -// director->getTouchDispatcher()->setPriority(Menu::HANDLER_PRIORITY-1, this); + EventDispatcher::getInstance()->setPriority(_touchListener, -1); schedule(schedule_selector(MenuLayerMainMenu::allowTouches), 5.0f); log("TOUCHES DISABLED FOR 5 SECONDS"); } diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h index 127f8c1688..3a7b09eec9 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.h @@ -8,6 +8,7 @@ class MenuLayerMainMenu : public Layer { protected: MenuItem* _disabledItem; + EventListenerTouchOneByOne* _touchListener; public: MenuLayerMainMenu(void); From a56475e872f9c96a44596f72b9fdfabf1f6a24a8 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 16:35:37 +0800 Subject: [PATCH 026/144] Updating jsb. --- .../javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id | 2 +- cocos/scripting/javascript/bindings/cocos2d_specifics.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index 082d55b8bd..4caa15159c 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -33fef8c7bc7006ad55c27fd0ed9c9dd2c8064079 \ No newline at end of file +0d38b7e53d97995151ea296bdd1f4ed768ce2f9b \ No newline at end of file diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.hpp b/cocos/scripting/javascript/bindings/cocos2d_specifics.hpp index 2981a726a8..f7e9f2bdb4 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.hpp +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.hpp @@ -199,7 +199,8 @@ private: typedef std::pair TouchDelegatePair; static TouchDelegateMap sTouchDelegateMap; bool _needUnroot; - EventListenerTouch* _touchListener; + EventListenerTouchOneByOne* _touchListenerOneByOne; + EventListenerTouchAllAtOnce* _touchListenerAllAtOnce; }; From e59c49a5e3c06609877796d562c03e5776ff01db Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 17:13:03 +0800 Subject: [PATCH 027/144] fix crash. --- cocos/2d/CCEventDispatcher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index ca28314d8c..71e7b36704 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -232,7 +232,8 @@ void EventDispatcher::cleanTarget(Node* node) if (listenerIter != _nodeListenersMap.end()) { auto listeners = listenerIter->second; - for (auto& l : *listeners) + auto listenersCopy = *listeners; + for (auto& l : listenersCopy) { removeEventListener(l); } From aeef62d893be38a43e971112a8ffd219e1e9a351 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 23 Oct 2013 17:26:14 +0800 Subject: [PATCH 028/144] bug fix for EventDispatcher. --- cocos/2d/CCEventDispatcher.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 71e7b36704..9df198f8e2 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -161,11 +161,7 @@ void EventDispatcher::destroyInstance() } void EventDispatcher::visitTarget(Node* node) -{ - // Reset priority index - s_eventPriorityIndex = 0; - _nodePriorityMap.clear(); - +{ int i = 0; Array* children = node->getChildren(); int childrenCount = children ? children->count() : 0; @@ -898,20 +894,23 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(const std::string& return; Node* rootNode = (Node*)Director::getInstance()->getRunningScene(); - + // Reset priority index + s_eventPriorityIndex = 0; + _nodePriorityMap.clear(); + visitTarget(rootNode); // After sort: priority < 0, > 0 auto sceneGraphlisteners = listeners->getSceneGraphPriorityListeners(); std::sort(sceneGraphlisteners->begin(), sceneGraphlisteners->end(), [this](const EventListener* l1, const EventListener* l2) { - return _nodePriorityMap[l1->_node] >= _nodePriorityMap[l2->_node]; + return _nodePriorityMap[l1->_node] > _nodePriorityMap[l2->_node]; }); #if DUMP_LISTENER_ITEM_PRIORITY_INFO log("-----------------------------------"); for (auto& l : *sceneGraphlisteners) { - log("listener priority: node ([%s]%p), fixed (%d)", typeid(*l->_node).name(), l->_node, l->_fixedPriority); + log("listener priority: node ([%s]%p), priority (%d)", typeid(*l->_node).name(), l->_node, _nodePriorityMap[l->_node]); } #endif } From 5ecb664a58f34d80efa44846fab131234dad6008 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 11:17:29 +0800 Subject: [PATCH 029/144] crash and memory leak fix. --- cocos/2d/CCEventDispatcher.cpp | 17 +++++++++-------- cocos/2d/CCEventListener.h | 1 + cocos/2d/CCMenu.cpp | 4 ++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 9df198f8e2..607c82181f 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -367,14 +367,13 @@ void EventDispatcher::removeEventListener(EventListener* listener) auto l = *iter; if (l == listener) { - CC_SAFE_RETAIN(listener); + CC_SAFE_RETAIN(l); l->_isRegistered = false; if (l->_node != nullptr) { - dissociateNodeAndEventListener(l->_node, listener); + dissociateNodeAndEventListener(l->_node, l); } - l->release(); if (_inDispatch == 0) { listeners->erase(iter); @@ -391,7 +390,7 @@ void EventDispatcher::removeEventListener(EventListener* listener) auto listeners = iter->second; auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); - + removeListenerInVector(sceneGraphPriorityListeners); if (!isFound) { @@ -459,7 +458,7 @@ void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, s for (; !fixedPriorityListeners->empty() && i < listeners->getGt0Index(); ++i) { auto l = fixedPriorityListeners->at(i); - if (!l->isPaused() && onEvent(l)) + if (!l->isPaused() && l->isRegistered() && onEvent(l)) { shouldStopPropagation = true; break; @@ -472,9 +471,9 @@ void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, s if (!shouldStopPropagation) { // priority == 0, scene graph priority - for (auto& listener : *sceneGraphPriorityListeners) + for (auto& l : *sceneGraphPriorityListeners) { - if (!listener->isPaused() && onEvent(listener)) + if (!l->isPaused() && l->isRegistered() && onEvent(l)) { shouldStopPropagation = true; break; @@ -492,7 +491,7 @@ void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, s { auto l = fixedPriorityListeners->at(i); - if (!l->isPaused() && onEvent(fixedPriorityListeners->at(i))) + if (!l->isPaused() && l->isRegistered() && onEvent(fixedPriorityListeners->at(i))) { shouldStopPropagation = true; break; @@ -794,6 +793,7 @@ void EventDispatcher::updateListeners() if (!l->_isRegistered) { iter = sceneGraphPriorityListeners->erase(iter); + l->release(); } else { @@ -810,6 +810,7 @@ void EventDispatcher::updateListeners() if (!l->_isRegistered) { iter = fixedPriorityListeners->erase(iter); + l->release(); } else { diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index f68f9694f9..672d9c98d0 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -62,6 +62,7 @@ public: virtual EventListener* clone() = 0; inline bool isPaused() const { return _paused; }; + inline bool isRegistered() const { return _isRegistered; }; protected: std::function _onEvent; /// Event callback function diff --git a/cocos/2d/CCMenu.cpp b/cocos/2d/CCMenu.cpp index 3105a2d8a3..5a46765d91 100644 --- a/cocos/2d/CCMenu.cpp +++ b/cocos/2d/CCMenu.cpp @@ -259,22 +259,26 @@ bool Menu::onTouchBegan(Touch* touch, Event* event) void Menu::onTouchEnded(Touch* touch, Event* event) { CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchEnded] -- invalid state"); + this->retain(); if (_selectedItem) { _selectedItem->unselected(); _selectedItem->activate(); } _state = Menu::State::WAITING; + this->release(); } void Menu::onTouchCancelled(Touch* touch, Event* event) { CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchCancelled] -- invalid state"); + this->retain(); if (_selectedItem) { _selectedItem->unselected(); } _state = Menu::State::WAITING; + this->release(); } void Menu::onTouchMoved(Touch* touch, Event* event) From dc6e201eb61a7ae0bb099c21ad47bb8f55d36cc5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 17:27:22 +0800 Subject: [PATCH 030/144] bug fix for eventdispatcher. --- cocos/2d/CCEventDispatcher.cpp | 32 ++++++++++++++++++++++++++++---- cocos/2d/CCEventDispatcher.h | 2 ++ cocos/2d/CCNode.cpp | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 607c82181f..817134ec37 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -115,7 +115,7 @@ void EventDispatcher::EventListenerVector::push_back(EventListener* listener) } } -void EventDispatcher::EventListenerVector::clear() +void EventDispatcher::EventListenerVector::clearSceneGraphListeners() { if (_sceneGraphListeners) { @@ -123,7 +123,10 @@ void EventDispatcher::EventListenerVector::clear() delete _sceneGraphListeners; _sceneGraphListeners = nullptr; } - +} + +void EventDispatcher::EventListenerVector::clearFixedListeners() +{ if (_fixedListeners) { _fixedListeners->clear(); @@ -132,6 +135,12 @@ void EventDispatcher::EventListenerVector::clear() } } +void EventDispatcher::EventListenerVector::clear() +{ + clearSceneGraphListeners(); + clearFixedListeners(); +} + EventDispatcher::EventDispatcher() : _inDispatch(0) @@ -270,6 +279,7 @@ void EventDispatcher::dissociateNodeAndEventListener(Node* node, EventListener* if (listeners->empty()) { _nodeListenersMap.erase(found); + delete listeners; } } } @@ -317,7 +327,6 @@ void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* list return; listener->_node = node; -// listener->_node->retain(); listener->_fixedPriority = 0; listener->retain(); @@ -377,6 +386,7 @@ void EventDispatcher::removeEventListener(EventListener* listener) if (_inDispatch == 0) { listeners->erase(iter); + CC_SAFE_RELEASE(l); } isFound = true; @@ -819,6 +829,16 @@ void EventDispatcher::updateListeners() } } + if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty()) + { + listeners->clearSceneGraphListeners(); + } + + if (fixedPriorityListeners && fixedPriorityListeners->empty()) + { + listeners->clearFixedListeners(); + } + if (listenersIter->second->empty()) { _priorityDirtyFlagMap.erase(listenersIter->first); @@ -1047,7 +1067,11 @@ bool EventDispatcher::isEnabled() const void EventDispatcher::setDirtyForNode(Node* node) { - _dirtyNodes.insert(node); + // Mark the node dirty only when there was an eventlistener associates with it. + if (_nodeListenersMap.find(node) != _nodeListenersMap.end()) + { + _dirtyNodes.insert(node); + } } void EventDispatcher::setDirtyForEventType(const std::string& eventType, DirtyFlag flag) diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index dc70491075..75f4f658af 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -139,6 +139,8 @@ private: bool empty() const; void push_back(EventListener* item); + void clearSceneGraphListeners(); + void clearFixedListeners(); void clear(); inline std::vector* getFixedPriorityListeners() const { return _fixedListeners; }; diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 8b9d41f9ec..ee19921a8d 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -640,7 +640,7 @@ void Node::addChild(Node *child, int zOrder, int tag) } } - EventDispatcher::getInstance()->setDirtyForNode(this); + EventDispatcher::getInstance()->setDirtyForNode(child); } void Node::addChild(Node *child, int zOrder) From 9632cd7949fa516e031190ea2e0ad84d6e6f021e Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 17:27:57 +0800 Subject: [PATCH 031/144] memoryleak fix. --- cocos/2d/CCLayer.cpp | 9 ++++++++- cocos/2d/CCMenuItem.cpp | 18 +++++++++++++++++- cocos/2d/CCMenuItem.h | 4 ++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index 717570e6fe..ed5caf3a71 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -650,7 +650,14 @@ LayerMultiplex::LayerMultiplex() } LayerMultiplex::~LayerMultiplex() { - CC_SAFE_RELEASE(_layers); + if (_layers) + { + for (auto& item : *_layers) + { + static_cast(item)->cleanup(); + } + _layers->release(); + } } LayerMultiplex * LayerMultiplex::create(Layer * layer, ...) diff --git a/cocos/2d/CCMenuItem.cpp b/cocos/2d/CCMenuItem.cpp index c735677e9f..24ec16a3a7 100644 --- a/cocos/2d/CCMenuItem.cpp +++ b/cocos/2d/CCMenuItem.cpp @@ -410,6 +410,15 @@ MenuItemFont * MenuItemFont::create(const char *value) return pRet; } +MenuItemFont::MenuItemFont() + : _fontSize(0), _fontName("") +{} + +MenuItemFont::~MenuItemFont() +{ + CCLOGINFO("In the destructor of MenuItemFont (%p).", this); +} + // XXX: deprecated bool MenuItemFont::initWithString(const char *value, Object* target, SEL_MenuHandler selector) { @@ -925,7 +934,14 @@ void MenuItemToggle::addSubItem(MenuItem *item) MenuItemToggle::~MenuItemToggle() { - CC_SAFE_RELEASE(_subItems); + if (_subItems) + { + for (auto& item : *_subItems) + { + static_cast(item)->cleanup(); + } + _subItems->release(); + } } void MenuItemToggle::setSelectedIndex(unsigned int index) diff --git a/cocos/2d/CCMenuItem.h b/cocos/2d/CCMenuItem.h index 021832df30..78b8d333ef 100644 --- a/cocos/2d/CCMenuItem.h +++ b/cocos/2d/CCMenuItem.h @@ -241,12 +241,12 @@ public: /** * @js ctor */ - MenuItemFont() : _fontSize(0), _fontName(""){} + MenuItemFont(); /** * @js NA * @lua NA */ - virtual ~MenuItemFont(){} + virtual ~MenuItemFont(); /** initializes a menu item from a string with a target/selector */ CC_DEPRECATED_ATTRIBUTE bool initWithString(const char *value, Object* target, SEL_MenuHandler selector); From 7854a13278ef39c65bec236176a3de9957bde8a6 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 17:28:51 +0800 Subject: [PATCH 032/144] Small fix for Bug-422.cpp and MenuTest.cpp. --- samples/Cpp/TestCpp/Classes/BugsTest/Bug-422.cpp | 2 +- samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-422.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-422.cpp index 4ce9ce9190..6f5f7eb542 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-422.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-422.cpp @@ -28,7 +28,7 @@ void Bug422Layer::reset() // => CRASH BOOM BANG auto node = getChildByTag(localtag-1); log("Menu: %p", node); - removeChild(node, false); + removeChild(node, true); // [self removeChildByTag:localtag-1 cleanup:NO]; auto item1 = MenuItemFont::create("One", CC_CALLBACK_1(Bug422Layer::menuCallback, this) ); diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp index 7edfb6fe4e..d295de75bc 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp @@ -138,6 +138,7 @@ void MenuLayerMainMenu::onTouchMoved(Touch *touch, Event * event) MenuLayerMainMenu::~MenuLayerMainMenu() { + EventDispatcher::getInstance()->removeEventListener(_touchListener); _disabledItem->release(); } From 9c4bc9e8ede2095b57abe3843cd174c3b27303e6 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 17:46:13 +0800 Subject: [PATCH 033/144] Update physicsTest. --- samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp | 9 +++++++-- samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h | 6 ++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 59513a0835..f9b9d209de 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -511,7 +511,10 @@ PhysicsDemoRayCast::PhysicsDemoRayCast() void PhysicsDemoRayCast::onEnter() { PhysicsDemo::onEnter(); - setTouchEnabled(true); + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoRayCast::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); _scene->getPhysicsWorld()->setGravity(Point::ZERO); @@ -712,7 +715,9 @@ void PhysicsDemoJoints::onEnter() { PhysicsDemo::onEnter(); - setTouchEnabled(true); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoJoints::onTouchesEnded, this); + EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); _scene->getPhysicsWorld()->setGravity(Point::ZERO); diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index 7dbb28617b..6d0d9a46c0 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -90,7 +90,7 @@ public: void onEnter() override; std::string title() override; void update(float delta) override; - void onTouchesEnded(const std::vector& touches, Event* event) override; + void onTouchesEnded(const std::vector& touches, Event* event); void changeModeCallback(Object* sender); @@ -110,9 +110,7 @@ public: public: void onEnter() override; std::string title() override; - -private: - PhysicsShape* _touchesShape; + void onTouchesEnded(const std::vector& touches, Event* event) override; }; #endif From b5cac51f97ef1cd2f2fc3405c518dc4a6cf5d1dc Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 17:58:30 +0800 Subject: [PATCH 034/144] PhysicsTest update. --- samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp | 5 +++++ samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index f9b9d209de..874f5ebe61 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -722,6 +722,11 @@ void PhysicsDemoJoints::onEnter() _scene->getPhysicsWorld()->setGravity(Point::ZERO); +} + +void PhysicsDemoJoints::onTouchesEnded(const std::vector& touches, Event* event) +{ + } std::string PhysicsDemoJoints::title() diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index 6d0d9a46c0..bb737b497d 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -41,9 +41,9 @@ public: Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f)); Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f)); - void onTouchesBegan(const std::vector& touches, Event* event) override; - void onTouchesMoved(const std::vector& touches, Event* event) override; - void onTouchesEnded(const std::vector& touches, Event* event) override; + void onTouchesBegan(const std::vector& touches, Event* event); + void onTouchesMoved(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); protected: Texture2D* _spriteTexture; // weak ref @@ -110,7 +110,7 @@ public: public: void onEnter() override; std::string title() override; - void onTouchesEnded(const std::vector& touches, Event* event) override; + void onTouchesEnded(const std::vector& touches, Event* event); }; #endif From c4f9acbee71f37f7b43bc0f3a0fc165754540ab8 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 24 Oct 2013 20:50:21 +0800 Subject: [PATCH 035/144] disable DUMP_LISTENER_ITEM_PRIORITY_INFO. use std::unordered_map instead of std::map. --- cocos/2d/CCEventDispatcher.cpp | 3 ++- cocos/2d/CCEventDispatcher.h | 21 ++++++++++----------- cocos/2d/CCNode.cpp | 2 -- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 817134ec37..f7d593fb8f 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -31,7 +31,7 @@ #include -#define DUMP_LISTENER_ITEM_PRIORITY_INFO 1 +#define DUMP_LISTENER_ITEM_PRIORITY_INFO 0 namespace { @@ -229,6 +229,7 @@ void EventDispatcher::resumeTarget(Node* node) l->_paused = false; } } + setDirtyForNode(node); } void EventDispatcher::cleanTarget(Node* node) diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 75f4f658af..26d3154a65 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -114,12 +114,6 @@ public: void setDirtyForNode(Node* node); - void setDirtyForEventType(const std::string& eventType, DirtyFlag flag); - - DirtyFlag isDirtyForEventType(const std::string& eventType); - - void visitTarget(Node* node); - void pauseTarget(Node* node); void resumeTarget(Node* node); void cleanTarget(Node* node); @@ -181,16 +175,21 @@ private: void dispatchEventToListeners(EventListenerVector* listeners, std::function onEvent); + void setDirtyForEventType(const std::string& eventType, DirtyFlag flag); + DirtyFlag isDirtyForEventType(const std::string& eventType); + + void visitTarget(Node* node); + private: /** * Listeners map. */ - std::map _listeners; + std::unordered_map _listeners; - std::map _priorityDirtyFlagMap; + std::unordered_map _priorityDirtyFlagMap; - std::map*> _nodeListenersMap; - std::map _nodePriorityMap; + std::unordered_map*> _nodeListenersMap; + std::unordered_map _nodePriorityMap; std::vector _toAddedListeners; std::set _dirtyNodes; diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index ee19921a8d..427884abb0 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -639,8 +639,6 @@ void Node::addChild(Node *child, int zOrder, int tag) child->onEnterTransitionDidFinish(); } } - - EventDispatcher::getInstance()->setDirtyForNode(child); } void Node::addChild(Node *child, int zOrder) From 27b71ba73c7413896d64157790991894da0f2b07 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 10:35:48 +0800 Subject: [PATCH 036/144] Use integer as event type and listener type. --- cocos/2d/CCEvent.cpp | 2 +- cocos/2d/CCEvent.h | 16 +- cocos/2d/CCEventAcceleration.cpp | 4 +- cocos/2d/CCEventAcceleration.h | 3 +- cocos/2d/CCEventCustom.cpp | 6 +- cocos/2d/CCEventCustom.h | 2 +- cocos/2d/CCEventDispatcher.cpp | 190 ++++++++---------- cocos/2d/CCEventDispatcher.h | 29 +-- cocos/2d/CCEventKeyboard.h | 2 +- cocos/2d/CCEventListener.cpp | 2 +- cocos/2d/CCEventListener.h | 17 +- cocos/2d/CCEventListenerAcceleration.cpp | 2 +- cocos/2d/CCEventListenerCustom.cpp | 8 +- cocos/2d/CCEventListenerCustom.h | 4 +- cocos/2d/CCEventListenerKeyboard.cpp | 2 +- cocos/2d/CCEventListenerTouch.cpp | 4 +- cocos/2d/CCEventListenerTouch.h | 4 + cocos/2d/CCEventTouch.cpp | 4 - cocos/2d/CCEventTouch.h | 8 +- cocos/2d/platform/CCEGLViewProtocol.cpp | 6 +- .../NewEventDispatcherTest.cpp | 7 +- 21 files changed, 155 insertions(+), 167 deletions(-) diff --git a/cocos/2d/CCEvent.cpp b/cocos/2d/CCEvent.cpp index 87cce7ab7d..c74beef87e 100644 --- a/cocos/2d/CCEvent.cpp +++ b/cocos/2d/CCEvent.cpp @@ -26,7 +26,7 @@ NS_CC_BEGIN -Event::Event(const std::string& type) +Event::Event(Type type) : _type(type) , _isStopped(false) , _currentTarget(nullptr) diff --git a/cocos/2d/CCEvent.h b/cocos/2d/CCEvent.h index 1652066fd3..348c2ba1d3 100644 --- a/cocos/2d/CCEvent.h +++ b/cocos/2d/CCEvent.h @@ -40,15 +40,25 @@ class Node; */ class Event { +public: + enum EventType + { + TYPE_TOUCH = 1, + TYPE_KEYBOARD = 3, + TYPE_ACCELERATION, + TYPE_CUSTOM + }; + + typedef int Type; protected: /** Constructor */ - Event(const std::string& type); + Event(Type type); public: /** Destructor */ virtual ~Event(); /** Gets the event type */ - inline const std::string& getType() const { return _type; }; + inline int getType() const { return _type; }; /** Stops propagation for current event */ inline void stopPropagation() { _isStopped = true; }; @@ -67,7 +77,7 @@ protected: /** Sets current target */ inline void setCurrentTarget(Node* target) { _currentTarget = target; }; - std::string _type; ///< Event type + Type _type; ///< Event type bool _isStopped; ///< whether the event has been stopped. Node* _currentTarget; ///< Current target diff --git a/cocos/2d/CCEventAcceleration.cpp b/cocos/2d/CCEventAcceleration.cpp index 962408202d..7039c03ff8 100644 --- a/cocos/2d/CCEventAcceleration.cpp +++ b/cocos/2d/CCEventAcceleration.cpp @@ -26,10 +26,8 @@ NS_CC_BEGIN -const char* EventAcceleration::EVENT_TYPE = "AccelerometerEvent"; - EventAcceleration::EventAcceleration(Acceleration acc) -: Event(EVENT_TYPE) +: Event(TYPE_ACCELERATION) , _acc(acc) { } diff --git a/cocos/2d/CCEventAcceleration.h b/cocos/2d/CCEventAcceleration.h index c5dfbe9ef5..1480ee6b0c 100644 --- a/cocos/2d/CCEventAcceleration.h +++ b/cocos/2d/CCEventAcceleration.h @@ -33,8 +33,7 @@ NS_CC_BEGIN class EventAcceleration : public Event { public: - static const char* EVENT_TYPE; - + EventAcceleration(Acceleration acc); private: diff --git a/cocos/2d/CCEventCustom.cpp b/cocos/2d/CCEventCustom.cpp index f9fc9d4a0e..89e56a3a69 100644 --- a/cocos/2d/CCEventCustom.cpp +++ b/cocos/2d/CCEventCustom.cpp @@ -23,13 +23,15 @@ ****************************************************************************/ #include "CCEventCustom.h" +#include "ccMacros.h" NS_CC_BEGIN -EventCustom::EventCustom(const std::string& eventName) -: Event(eventName) +EventCustom::EventCustom(Type type) +: Event(type) , _userData(nullptr) { + CCASSERT(type >= TYPE_CUSTOM, "custom type should be greater than TYPE_CUSTOM."); } NS_CC_END diff --git a/cocos/2d/CCEventCustom.h b/cocos/2d/CCEventCustom.h index c4521e3bbf..96676cdbfd 100644 --- a/cocos/2d/CCEventCustom.h +++ b/cocos/2d/CCEventCustom.h @@ -33,7 +33,7 @@ class EventCustom : public Event { public: /** Constructor */ - EventCustom(const std::string& eventName); + EventCustom(Type type); /** Set user data */ inline void setUserData(void* data) { _userData = data; }; diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index f7d593fb8f..a0e58363a3 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -306,11 +306,11 @@ void EventDispatcher::addEventListener(EventListener* listener) if (listener->_fixedPriority == 0) { - setDirtyForEventType(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + setDirty(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); } else { - setDirtyForEventType(listener->_type, DirtyFlag::FIXED_PRITORY); + setDirty(listener->_type, DirtyFlag::FIXED_PRITORY); } } else @@ -448,7 +448,7 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority) if (listener->_fixedPriority != fixedPriority) { listener->_fixedPriority = fixedPriority; - setDirtyForEventType(listener->_type, DirtyFlag::FIXED_PRITORY); + setDirty(listener->_type, DirtyFlag::FIXED_PRITORY); } return; } @@ -519,31 +519,17 @@ void EventDispatcher::dispatchEvent(Event* event) updateDirtyFlagForSceneGraph(); - DirtyFlag dirtyFlag = DirtyFlag::NONE; - - auto dirtyIter = _priorityDirtyFlagMap.find(event->_type); - if (dirtyIter != _priorityDirtyFlagMap.end()) - { - dirtyFlag = dirtyIter->second; - } - - if (dirtyFlag != DirtyFlag::NONE) - { - if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY) - { - sortEventListenersOfFixedPriority(event->_type); - } - - if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY) - { - sortEventListenersOfSceneGraphPriority(event->_type); - } - - dirtyIter->second = DirtyFlag::NONE; - } DispatchGuard guard(_inDispatch); + if (event->getType() == Event::TYPE_TOUCH) + { + dispatchTouchEvent(static_cast(event)); + return; + } + + sortEventListeners(event->getType()); + auto iter = _listeners.find(event->getType()); if (iter != _listeners.end()) { @@ -558,49 +544,16 @@ void EventDispatcher::dispatchEvent(Event* event) dispatchEventToListeners(listeners, onEvent); } - updateListeners(); + updateListeners(event->getType()); } void EventDispatcher::dispatchTouchEvent(EventTouch* event) { - if (!_isEnabled) - return; + sortEventListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); + sortEventListeners(EventListener::TYPE_TOUCH_ALL_AT_ONCE); - updateDirtyFlagForSceneGraph(); - - auto sortTouchListeners = [this](const std::string& type){ - - DirtyFlag dirtyFlag = DirtyFlag::NONE; - auto dirtyIter = _priorityDirtyFlagMap.find(type); - if (dirtyIter != _priorityDirtyFlagMap.end()) - { - dirtyFlag = dirtyIter->second; - } - - if (dirtyFlag != DirtyFlag::NONE) - { - if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY) - { - sortEventListenersOfFixedPriority(type); - } - - if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY) - { - sortEventListenersOfSceneGraphPriority(type); - } - - dirtyIter->second = DirtyFlag::NONE; - } - - }; - - sortTouchListeners(EventTouch::MODE_ONE_BY_ONE); - sortTouchListeners(EventTouch::MODE_ALL_AT_ONCE); - - DispatchGuard guard(_inDispatch); - - auto oneByOnelisteners = getListeners(EventTouch::MODE_ONE_BY_ONE); - auto allAtOncelisteners = getListeners(EventTouch::MODE_ALL_AT_ONCE); + auto oneByOnelisteners = getListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); + auto allAtOncelisteners = getListeners(EventListener::TYPE_TOUCH_ALL_AT_ONCE); // If there aren't any touch listeners, return directly. if (nullptr == oneByOnelisteners && nullptr == allAtOncelisteners) @@ -691,7 +644,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // If the event was stopped, return directly. if (event->isStopped()) { - updateListeners(); + updateListeners(event->getType()); return true; } @@ -770,7 +723,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // If the event was stopped, return directly. if (event->isStopped()) { - updateListeners(); + updateListeners(event->getType()); return false; } @@ -784,14 +737,17 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) } } - updateListeners(); + updateListeners(event->getType()); } -void EventDispatcher::updateListeners() +void EventDispatcher::updateListeners(Event::Type eventType) { - auto listenersIter = _listeners.begin(); - while (listenersIter != _listeners.end()) + auto onUpdateListeners = [this](EventListener::Type listenerType) { + auto listenersIter = _listeners.find(listenerType); + if (listenersIter == _listeners.end()) + return; + auto listeners = listenersIter->second; auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); @@ -850,7 +806,18 @@ void EventDispatcher::updateListeners() { ++listenersIter; } + }; + + if (eventType == Event::TYPE_TOUCH) + { + onUpdateListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); + onUpdateListeners(EventListener::TYPE_TOUCH_ALL_AT_ONCE); } + else + { + onUpdateListeners(eventType); + } + if (!_toAddedListeners.empty()) { @@ -874,11 +841,11 @@ void EventDispatcher::updateListeners() if (listener->_fixedPriority == 0) { - setDirtyForEventType(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + setDirty(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); } else { - setDirtyForEventType(listener->_type, DirtyFlag::FIXED_PRITORY); + setDirty(listener->_type, DirtyFlag::FIXED_PRITORY); } } _toAddedListeners.clear(); @@ -896,7 +863,7 @@ void EventDispatcher::updateDirtyFlagForSceneGraph() { for (auto& l : *iter->second) { - setDirtyForEventType(l->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + setDirty(l->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); } } } @@ -905,12 +872,35 @@ void EventDispatcher::updateDirtyFlagForSceneGraph() } } -void EventDispatcher::sortEventListenersOfSceneGraphPriority(const std::string& eventType) +void EventDispatcher::sortEventListeners(EventListener::Type eventListenerType) { - if (eventType.empty()) - return; + DirtyFlag dirtyFlag = DirtyFlag::NONE; - auto listeners = getListeners(eventType); + auto dirtyIter = _priorityDirtyFlagMap.find(eventListenerType); + if (dirtyIter != _priorityDirtyFlagMap.end()) + { + dirtyFlag = dirtyIter->second; + } + + if (dirtyFlag != DirtyFlag::NONE) + { + if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY) + { + sortEventListenersOfFixedPriority(eventListenerType); + } + + if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY) + { + sortEventListenersOfSceneGraphPriority(eventListenerType); + } + + dirtyIter->second = DirtyFlag::NONE; + } +} + +void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::Type eventListenerType) +{ + auto listeners = getListeners(eventListenerType); if (listeners == nullptr) return; @@ -937,12 +927,9 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(const std::string& #endif } -void EventDispatcher::sortEventListenersOfFixedPriority(const std::string &eventType) +void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::Type eventListenerType) { - if (eventType.empty()) - return; - - auto listeners = getListeners(eventType); + auto listeners = getListeners(eventListenerType); if (listeners == nullptr) return; @@ -974,9 +961,9 @@ void EventDispatcher::sortEventListenersOfFixedPriority(const std::string &event } -EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const std::string &eventType) +EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListener::Type eventListenerType) { - auto iter = _listeners.find(eventType); + auto iter = _listeners.find(eventListenerType); if (iter != _listeners.end()) { return iter->second; @@ -985,12 +972,9 @@ EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const std::s return nullptr; } -void EventDispatcher::removeListenersForEventType(const std::string& eventType) +void EventDispatcher::removeListeners(EventListener::Type eventListenerType) { - if (eventType.empty()) - return; - - auto listenerItemIter = _listeners.find(eventType); + auto listenerItemIter = _listeners.find(eventListenerType); if (listenerItemIter != _listeners.end()) { auto listeners = listenerItemIter->second; @@ -1010,10 +994,10 @@ void EventDispatcher::removeListenersForEventType(const std::string& eventType) dissociateNodeAndEventListener(l->_node, l); } - l->release(); if (_inDispatch == 0) { iter = listenerVector->erase(iter); + CC_SAFE_RELEASE(l); } else { @@ -1030,14 +1014,14 @@ void EventDispatcher::removeListenersForEventType(const std::string& eventType) listeners->clear(); delete listeners; _listeners.erase(listenerItemIter); - _priorityDirtyFlagMap.erase(eventType); + _priorityDirtyFlagMap.erase(eventListenerType); } } } void EventDispatcher::removeAllListeners() { - std::vector types(_listeners.size()); + std::vector types(_listeners.size()); for (auto iter = _listeners.begin(); iter != _listeners.end(); ++iter) { @@ -1046,7 +1030,7 @@ void EventDispatcher::removeAllListeners() for (auto& type : types) { - removeListenersForEventType(type); + removeListeners(type); } if (!_inDispatch) @@ -1075,14 +1059,12 @@ void EventDispatcher::setDirtyForNode(Node* node) } } -void EventDispatcher::setDirtyForEventType(const std::string& eventType, DirtyFlag flag) -{ - CCASSERT(!eventType.empty(), "Invalid event type."); - - auto iter = _priorityDirtyFlagMap.find(eventType); +void EventDispatcher::setDirty(EventListener::Type eventListenerType, DirtyFlag flag) +{ + auto iter = _priorityDirtyFlagMap.find(eventListenerType); if (iter == _priorityDirtyFlagMap.end()) { - _priorityDirtyFlagMap.insert(std::make_pair(eventType, flag)); + _priorityDirtyFlagMap.insert(std::make_pair(eventListenerType, flag)); } else { @@ -1091,16 +1073,4 @@ void EventDispatcher::setDirtyForEventType(const std::string& eventType, DirtyFl } } -EventDispatcher::DirtyFlag EventDispatcher::isDirtyForEventType(const std::string& eventType) -{ - DirtyFlag flag = DirtyFlag::NONE; - auto iter = _priorityDirtyFlagMap.find(eventType); - if (iter != _priorityDirtyFlagMap.end()) - { - flag = iter->second; - } - - return flag; -} - NS_CC_END diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 26d3154a65..53f2224b2b 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -27,6 +27,7 @@ #include "CCPlatformMacros.h" #include "CCEventListener.h" +#include "CCEvent.h" #include #include @@ -80,7 +81,7 @@ public: void removeEventListener(EventListener* listener); /** Removes all listeners with the same event type */ - void removeListenersForEventType(const std::string& eventType); + void removeListeners(EventListener::Type eventListenerType); /** Removes all listeners */ void removeAllListeners(); @@ -100,9 +101,6 @@ public: */ void dispatchEvent(Event* event); - /** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */ - void dispatchTouchEvent(EventTouch* event); - /// Priority dirty flag enum class DirtyFlag { @@ -153,30 +151,35 @@ private: /** Adds event listener with item */ void addEventListener(EventListener* listener); - /** Gets event the listener list for the event type. */ - EventListenerVector* getListeners(const std::string& eventType); + /** Gets event the listener list for the event listener type. */ + EventListenerVector* getListeners(EventListener::Type eventListenerType); void updateDirtyFlagForSceneGraph(); + /** Sort event listener */ + void sortEventListeners(EventListener::Type eventListenerType); + /** Sorts the listeners of specified type by scene graph priority */ - void sortEventListenersOfSceneGraphPriority(const std::string& eventType); + void sortEventListenersOfSceneGraphPriority(EventListener::Type eventListenerType); /** Sorts the listeners of specified type by fixed priority */ - void sortEventListenersOfFixedPriority(const std::string& eventType); + void sortEventListenersOfFixedPriority(EventListener::Type eventListenerType); /** Updates all listeners * 1) Removes all listener items that have been marked as 'removed' when dispatching event. * 2) Adds all listener items that have been marked as 'added' when dispatching event. */ - void updateListeners(); + void updateListeners(Event::Type eventType); + /** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */ + void dispatchTouchEvent(EventTouch* event); + void associateNodeAndEventListener(Node* node, EventListener* listener); void dissociateNodeAndEventListener(Node* node, EventListener* listener); void dispatchEventToListeners(EventListenerVector* listeners, std::function onEvent); - void setDirtyForEventType(const std::string& eventType, DirtyFlag flag); - DirtyFlag isDirtyForEventType(const std::string& eventType); + void setDirty(EventListener::Type listenerType, DirtyFlag flag); void visitTarget(Node* node); @@ -184,9 +187,9 @@ private: /** * Listeners map. */ - std::unordered_map _listeners; + std::unordered_map _listeners; - std::unordered_map _priorityDirtyFlagMap; + std::unordered_map _priorityDirtyFlagMap; std::unordered_map*> _nodeListenersMap; std::unordered_map _nodePriorityMap; diff --git a/cocos/2d/CCEventKeyboard.h b/cocos/2d/CCEventKeyboard.h index fffc76e0ac..b8cf7f8976 100644 --- a/cocos/2d/CCEventKeyboard.h +++ b/cocos/2d/CCEventKeyboard.h @@ -199,7 +199,7 @@ public: static const char* EVENT_TYPE; EventKeyboard(KeyCode keyCode, bool isPressed) - : Event(EVENT_TYPE) + : Event(TYPE_KEYBOARD) , _keyCode(keyCode) , _isPressed(isPressed) {}; diff --git a/cocos/2d/CCEventListener.cpp b/cocos/2d/CCEventListener.cpp index 8b34ca5173..9040593e0e 100644 --- a/cocos/2d/CCEventListener.cpp +++ b/cocos/2d/CCEventListener.cpp @@ -35,7 +35,7 @@ EventListener::~EventListener() CCLOGINFO("In the destructor of EventListener. %p", this); } -bool EventListener::init(const std::string& t, std::function callback) +bool EventListener::init(Type t, std::function callback) { _onEvent = callback; _type = t; diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index 672d9c98d0..bcedcec0c8 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -44,13 +44,24 @@ class Node; * For instance, you could refer to EventListenerAcceleration, EventListenerKeyboard, EventListenerTouchOneByOne, EventListenerCustom. */ class EventListener : public Object -{ +{ +public: + enum EventListenerType + { + TYPE_TOUCH_ONE_BY_ONE = 1, + TYPE_TOUCH_ALL_AT_ONCE, + TYPE_KEYBOARD, + TYPE_ACCELERATION, + TYPE_CUSTOM + }; + + typedef int Type; protected: /** Constructor */ EventListener(); /** Initializes event with type and callback function */ - bool init(const std::string& t, std::functioncallback); + bool init(Type t, std::functioncallback); public: /** Destructor */ virtual ~EventListener(); @@ -66,7 +77,7 @@ public: protected: std::function _onEvent; /// Event callback function - std::string _type; /// Event type + Type _type; /// Event type bool _isRegistered; /// Whether the listener has been added to dispatcher. // The priority of event listener diff --git a/cocos/2d/CCEventListenerAcceleration.cpp b/cocos/2d/CCEventListenerAcceleration.cpp index d8b01fc4ce..01a9ef6398 100644 --- a/cocos/2d/CCEventListenerAcceleration.cpp +++ b/cocos/2d/CCEventListenerAcceleration.cpp @@ -59,7 +59,7 @@ bool EventListenerAcceleration::init(std::functiononAccelerationEvent(&accEvent->_acc, event); }; - if (EventListener::init(EventAcceleration::EVENT_TYPE, listener)) + if (EventListener::init(TYPE_ACCELERATION, listener)) { onAccelerationEvent = callback; return true; diff --git a/cocos/2d/CCEventListenerCustom.cpp b/cocos/2d/CCEventListenerCustom.cpp index abe4153198..05e562b567 100644 --- a/cocos/2d/CCEventListenerCustom.cpp +++ b/cocos/2d/CCEventListenerCustom.cpp @@ -32,10 +32,10 @@ EventListenerCustom::EventListenerCustom() { } -EventListenerCustom* EventListenerCustom::create(const std::string& eventName, std::function callback) +EventListenerCustom* EventListenerCustom::create(int type, std::function callback) { EventListenerCustom* ret = new EventListenerCustom(); - if (ret && ret->init(eventName, callback)) + if (ret && ret->init(type, callback)) { ret->autorelease(); } @@ -46,7 +46,7 @@ EventListenerCustom* EventListenerCustom::create(const std::string& eventName, s return ret; } -bool EventListenerCustom::init(const std::string& eventName, std::functioncallback) +bool EventListenerCustom::init(int type, std::functioncallback) { bool ret = false; @@ -59,7 +59,7 @@ bool EventListenerCustom::init(const std::string& eventName, std::function callback); + static EventListenerCustom* create(int type, std::function callback); /// Overrides virtual bool checkAvailable() override; @@ -67,7 +67,7 @@ protected: EventListenerCustom(); /** Initializes event with type and callback function */ - bool init(const std::string& eventName, std::function callback); + bool init(int type, std::function callback); std::function _onCustomEvent; }; diff --git a/cocos/2d/CCEventListenerKeyboard.cpp b/cocos/2d/CCEventListenerKeyboard.cpp index a6e3b617ae..fb733ed442 100644 --- a/cocos/2d/CCEventListenerKeyboard.cpp +++ b/cocos/2d/CCEventListenerKeyboard.cpp @@ -88,7 +88,7 @@ bool EventListenerKeyboard::init() } }; - if (EventListener::init(EventKeyboard::EVENT_TYPE, listener)) + if (EventListener::init(TYPE_KEYBOARD, listener)) { return true; } diff --git a/cocos/2d/CCEventListenerTouch.cpp b/cocos/2d/CCEventListenerTouch.cpp index 49ec1462c9..e753a113d0 100644 --- a/cocos/2d/CCEventListenerTouch.cpp +++ b/cocos/2d/CCEventListenerTouch.cpp @@ -46,7 +46,7 @@ EventListenerTouchOneByOne::~EventListenerTouchOneByOne() bool EventListenerTouchOneByOne::init() { - if (EventListener::init(EventTouch::MODE_ONE_BY_ONE, nullptr)) + if (EventListener::init(TYPE_TOUCH_ONE_BY_ONE, nullptr)) { return true; } @@ -123,7 +123,7 @@ EventListenerTouchAllAtOnce::~EventListenerTouchAllAtOnce() bool EventListenerTouchAllAtOnce::init() { - if (EventListener::init(EventTouch::MODE_ALL_AT_ONCE, nullptr)) + if (EventListener::init(TYPE_TOUCH_ALL_AT_ONCE, nullptr)) { return true; } diff --git a/cocos/2d/CCEventListenerTouch.h b/cocos/2d/CCEventListenerTouch.h index 09e6e6fe0c..a73dc1e992 100644 --- a/cocos/2d/CCEventListenerTouch.h +++ b/cocos/2d/CCEventListenerTouch.h @@ -36,6 +36,8 @@ NS_CC_BEGIN class EventListenerTouchOneByOne : public EventListener { public: + static const int TYPE = 0x01; + static EventListenerTouchOneByOne* create(); virtual ~EventListenerTouchOneByOne(); @@ -67,6 +69,8 @@ private: class EventListenerTouchAllAtOnce : public EventListener { public: + static const int TYPE = 0x02; + static EventListenerTouchAllAtOnce* create(); virtual ~EventListenerTouchAllAtOnce(); diff --git a/cocos/2d/CCEventTouch.cpp b/cocos/2d/CCEventTouch.cpp index 987d87d0e9..d0df614973 100644 --- a/cocos/2d/CCEventTouch.cpp +++ b/cocos/2d/CCEventTouch.cpp @@ -26,9 +26,5 @@ NS_CC_BEGIN -const char* EventTouch::MODE_ONE_BY_ONE = "TouchEventOneByOne"; -const char* EventTouch::MODE_ALL_AT_ONCE = "TouchEventAllAtOnce"; - -const char* EventTouch::EVENT_TYPE = "TouchEvent"; NS_CC_END diff --git a/cocos/2d/CCEventTouch.h b/cocos/2d/CCEventTouch.h index 558bfe0593..100d67cf95 100644 --- a/cocos/2d/CCEventTouch.h +++ b/cocos/2d/CCEventTouch.h @@ -36,12 +36,6 @@ NS_CC_BEGIN class EventTouch : public Event { public: - static const char* MODE_ONE_BY_ONE; - static const char* MODE_ALL_AT_ONCE; - - static const char* EVENT_TYPE; - - static const int MAX_TOUCHES = 5; enum class EventCode @@ -53,7 +47,7 @@ public: }; EventTouch() - : Event(EVENT_TYPE) + : Event(TYPE_TOUCH) { _touches.reserve(MAX_TOUCHES); } diff --git a/cocos/2d/platform/CCEGLViewProtocol.cpp b/cocos/2d/platform/CCEGLViewProtocol.cpp index 094e584e97..9b1e943019 100644 --- a/cocos/2d/platform/CCEGLViewProtocol.cpp +++ b/cocos/2d/platform/CCEGLViewProtocol.cpp @@ -247,7 +247,7 @@ void EGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float y } touchEvent._eventCode = EventTouch::EventCode::BEGAN; - EventDispatcher::getInstance()->dispatchTouchEvent(&touchEvent); + EventDispatcher::getInstance()->dispatchEvent(&touchEvent); } void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[]) @@ -294,7 +294,7 @@ void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys } touchEvent._eventCode = EventTouch::EventCode::MOVED; - EventDispatcher::getInstance()->dispatchTouchEvent(&touchEvent); + EventDispatcher::getInstance()->dispatchEvent(&touchEvent); } void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, int ids[], float xs[], float ys[]) @@ -347,7 +347,7 @@ void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode } touchEvent._eventCode = eventCode; - EventDispatcher::getInstance()->dispatchTouchEvent(&touchEvent); + EventDispatcher::getInstance()->dispatchEvent(&touchEvent); for (auto& touch : touchEvent._touches) { diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index d44129aee5..d4b5f9988e 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -189,7 +189,7 @@ void TouchableSpriteTest::onEnter() auto senderItem = static_cast(sender); senderItem->setString("Only Next item could be clicked"); - EventDispatcher::getInstance()->removeListenersForEventType(EventTouch::EVENT_TYPE); + EventDispatcher::getInstance()->removeListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); auto nextItem = MenuItemFont::create("Next", [=](Object* sender){ nextCallback(nullptr); @@ -427,7 +427,8 @@ void CustomEventTest::onEnter() statusLabel->setPosition(origin + Point(size.width/2, size.height-90)); addChild(statusLabel); - _listener = EventListenerCustom::create("game_custom_event", [=](EventCustom* event){ + const int game_custom_event = EventListener::TYPE_CUSTOM + 1; + _listener = EventListenerCustom::create(game_custom_event, [=](EventCustom* event){ std::string str("Custom event received, "); char* buf = static_cast(event->getUserData()); str += buf; @@ -443,7 +444,7 @@ void CustomEventTest::onEnter() ++count; char* buf = new char[10]; sprintf(buf, "%d", count); - EventCustom event("game_custom_event"); + EventCustom event(game_custom_event); event.setUserData(buf); dispatcher->dispatchEvent(&event); }); From 30a3199a9132499143142dfbac9bca6c8908739a Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 15:19:04 +0800 Subject: [PATCH 037/144] [Dispatcher] Removing unused codes. --- cocos/2d/CCEventKeyboard.cpp | 1 - cocos/2d/CCEventListenerAcceleration.cpp | 2 +- cocos/2d/CCEventListenerAcceleration.h | 2 +- cocos/2d/CCEventListenerKeyboard.h | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cocos/2d/CCEventKeyboard.cpp b/cocos/2d/CCEventKeyboard.cpp index ceb2b49a8f..b02312fce1 100644 --- a/cocos/2d/CCEventKeyboard.cpp +++ b/cocos/2d/CCEventKeyboard.cpp @@ -27,6 +27,5 @@ NS_CC_BEGIN -const char* EventKeyboard::EVENT_TYPE = "KeyboardEvent"; NS_CC_END diff --git a/cocos/2d/CCEventListenerAcceleration.cpp b/cocos/2d/CCEventListenerAcceleration.cpp index 01a9ef6398..d1d5d22206 100644 --- a/cocos/2d/CCEventListenerAcceleration.cpp +++ b/cocos/2d/CCEventListenerAcceleration.cpp @@ -37,7 +37,7 @@ EventListenerAcceleration::~EventListenerAcceleration() CCLOGINFO("In the destructor of AccelerationEventListener. %p", this); } -EventListenerAcceleration* EventListenerAcceleration::create(std::function callback) +EventListenerAcceleration* EventListenerAcceleration::create(std::function callback) { EventListenerAcceleration* ret = new EventListenerAcceleration(); if (ret && ret->init(callback)) diff --git a/cocos/2d/CCEventListenerAcceleration.h b/cocos/2d/CCEventListenerAcceleration.h index 2905df9486..59ce3d8439 100644 --- a/cocos/2d/CCEventListenerAcceleration.h +++ b/cocos/2d/CCEventListenerAcceleration.h @@ -33,7 +33,7 @@ NS_CC_BEGIN class EventListenerAcceleration : public EventListener { public: - static EventListenerAcceleration* create(std::function callback); + static EventListenerAcceleration* create(std::function callback); virtual ~EventListenerAcceleration(); /// Overrides diff --git a/cocos/2d/CCEventListenerKeyboard.h b/cocos/2d/CCEventListenerKeyboard.h index dd223da533..c34d2add0d 100644 --- a/cocos/2d/CCEventListenerKeyboard.h +++ b/cocos/2d/CCEventListenerKeyboard.h @@ -42,8 +42,8 @@ public: virtual EventListenerKeyboard* clone() override; virtual bool checkAvailable() override; - std::function onKeyPressed; - std::function onKeyReleased; + std::function onKeyPressed; + std::function onKeyReleased; private: EventListenerKeyboard(); bool init(); From efa5afb1c3f6a67a287c436fd453344159e6be71 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 15:19:25 +0800 Subject: [PATCH 038/144] [Dispatcher] Removing unused codes in Layer. --- cocos/2d/CCLayer.cpp | 25 ------------------------- cocos/2d/CCLayer.h | 7 ------- 2 files changed, 32 deletions(-) diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index ed5caf3a71..127261efd5 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -87,31 +87,6 @@ Layer *Layer::create() } } -int Layer::executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* touch) -{ - if (kScriptTypeNone != _scriptType) - { - TouchScriptData data(eventType, this, touch); - ScriptEvent event(kTouchEvent, &data); - return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); - } - - //can not reach it - return 0; -} - -int Layer::executeScriptTouchesHandler(EventTouch::EventCode eventType, const std::vector& touches) -{ - if (kScriptTypeNone != _scriptType) - { - TouchesScriptData data(eventType, this, touches); - ScriptEvent event(kTouchesEvent, &data); - return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); - } - - return 0; -} - #ifdef CC_USE_PHYSICS void Layer::addChild(Node* child) { diff --git a/cocos/2d/CCLayer.h b/cocos/2d/CCLayer.h index 09effe2fcd..e94224b580 100644 --- a/cocos/2d/CCLayer.h +++ b/cocos/2d/CCLayer.h @@ -118,13 +118,6 @@ public: virtual void addChild(Node* child, int zOrder) override; virtual void addChild(Node* child, int zOrder, int tag) override; #endif // CC_USE_PHYSICS - -private: - Touch::DispatchMode _touchMode; - bool _swallowsTouches; - - int executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* touch); - int executeScriptTouchesHandler(EventTouch::EventCode eventType, const std::vector& touches); }; #ifdef __apple__ From 1339ef7ecbb21c31a55ddcc895dbf62c5e694de3 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 15:20:06 +0800 Subject: [PATCH 039/144] [JSB] These are only for v2.x JSB compatibility after removing controller codes in Layer. --- .../javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index 4caa15159c..25626c360d 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -0d38b7e53d97995151ea296bdd1f4ed768ce2f9b \ No newline at end of file +c4104d83bf7e5cc0b0eab7bb3753f9f053358054 \ No newline at end of file From 312e1bd27c14899288dc3e0d090d8f9f15030582 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 15:40:21 +0800 Subject: [PATCH 040/144] [Dispatcher] Updating comments. --- cocos/2d/CCEventDispatcher.h | 54 ++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 53f2224b2b..25f1d8a509 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -80,7 +80,7 @@ public: */ void removeEventListener(EventListener* listener); - /** Removes all listeners with the same event type */ + /** Removes all listeners with the same event listener type */ void removeListeners(EventListener::Type eventListenerType); /** Removes all listeners */ @@ -101,19 +101,16 @@ public: */ void dispatchEvent(Event* event); - /// Priority dirty flag - enum class DirtyFlag - { - NONE = 0, - FIXED_PRITORY = 1 << 0, - SCENE_GRAPH_PRIORITY = 1 << 1, - ALL = FIXED_PRITORY | SCENE_GRAPH_PRIORITY - }; - + /** Sets the dirty flag for a node. */ void setDirtyForNode(Node* node); + /** Notifys event dispatcher that the node has been paused. */ void pauseTarget(Node* node); + + /** Notifys event dispatcher that the node has been resumed. */ void resumeTarget(Node* node); + + /** Notifys event dispatcher that the node has been deleted. */ void cleanTarget(Node* node); public: @@ -122,6 +119,9 @@ public: private: + /** + * The vector to store event listeners with scene graph based priority and fixed priority. + */ class EventListenerVector { public: @@ -154,6 +154,7 @@ private: /** Gets event the listener list for the event listener type. */ EventListenerVector* getListeners(EventListener::Type eventListenerType); + /** Update dirty flag */ void updateDirtyFlagForSceneGraph(); /** Sort event listener */ @@ -174,31 +175,54 @@ private: /** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */ void dispatchTouchEvent(EventTouch* event); + /** Associates node with event listener */ void associateNodeAndEventListener(Node* node, EventListener* listener); + + /** Dissociates node with event listener */ void dissociateNodeAndEventListener(Node* node, EventListener* listener); + /** Dispatches event to listeners with a specified listener type */ void dispatchEventToListeners(EventListenerVector* listeners, std::function onEvent); + /// Priority dirty flag + enum class DirtyFlag + { + NONE = 0, + FIXED_PRITORY = 1 << 0, + SCENE_GRAPH_PRIORITY = 1 << 1, + ALL = FIXED_PRITORY | SCENE_GRAPH_PRIORITY + }; + + /** Sets the dirty flag for a specified listener type */ void setDirty(EventListener::Type listenerType, DirtyFlag flag); + /** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */ void visitTarget(Node* node); private: - /** - * Listeners map. - */ + /** Listeners map */ std::unordered_map _listeners; + /** The map of dirty flag */ std::unordered_map _priorityDirtyFlagMap; + /** The map of node and event listeners */ std::unordered_map*> _nodeListenersMap; + + /** The map of node and its event priority */ std::unordered_map _nodePriorityMap; + /** The listeners to be added after dispatching event */ std::vector _toAddedListeners; + + /** The nodes were associated with scene graph based priority listeners */ std::set _dirtyNodes; - int _inDispatch; ///< Whether it's in dispatching event - bool _isEnabled; ///< Whether to enable dispatching event + /** Whether the dispatcher is dispatching event */ + int _inDispatch; + + /** Whether to enable dispatching event */ + bool _isEnabled; }; From 262b54eef2cccb4d4b825f262b5c7ac3640b72b3 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 16:06:52 +0800 Subject: [PATCH 041/144] issue #3069: Updating ScrollView. --- extensions/GUI/CCScrollView/CCScrollView.cpp | 43 ++++++++++++-------- extensions/GUI/CCScrollView/CCScrollView.h | 5 ++- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/extensions/GUI/CCScrollView/CCScrollView.cpp b/extensions/GUI/CCScrollView/CCScrollView.cpp index ecc17ef0e7..35287bb9ce 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.cpp +++ b/extensions/GUI/CCScrollView/CCScrollView.cpp @@ -56,6 +56,7 @@ ScrollView::ScrollView() , _touchLength(0.0f) , _minScale(0.0f) , _maxScale(0.0f) +, _touchListener(nullptr) { } @@ -109,14 +110,7 @@ bool ScrollView::initWithViewSize(Size size, Node *container/* = NULL*/) this->setViewSize(size); - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchOneByOne::create(); - listener->onTouchBegan = CC_CALLBACK_2(ScrollView::onTouchBegan, this); - listener->onTouchMoved = CC_CALLBACK_2(ScrollView::onTouchMoved, this); - listener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this); - listener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this); - - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + setTouchEnabled(true); _touches.reserve(EventTouch::MAX_TOUCHES); @@ -183,16 +177,29 @@ void ScrollView::resume(Object* sender) _container->resumeSchedulerAndActions(); } -//void ScrollView::setTouchEnabled(bool e) -//{ -// Layer::setTouchEnabled(e); -// if (!e) -// { -// _dragging = false; -// _touchMoved = false; -// _touches.clear(); -// } -//} +void ScrollView::setTouchEnabled(bool enabled) +{ + auto dispatcher = EventDispatcher::getInstance(); + + dispatcher->removeEventListener(_touchListener); + + if (enabled) + { + _touchListener = EventListenerTouchOneByOne::create(); + _touchListener->onTouchBegan = CC_CALLBACK_2(ScrollView::onTouchBegan, this); + _touchListener->onTouchMoved = CC_CALLBACK_2(ScrollView::onTouchMoved, this); + _touchListener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this); + _touchListener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this); + + dispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this); + } + else + { + _dragging = false; + _touchMoved = false; + _touches.clear(); + } +} void ScrollView::setContentOffset(Point offset, bool animated/* = false*/) { diff --git a/extensions/GUI/CCScrollView/CCScrollView.h b/extensions/GUI/CCScrollView/CCScrollView.h index 42b9d78425..bd24efc8fb 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.h +++ b/extensions/GUI/CCScrollView/CCScrollView.h @@ -166,7 +166,7 @@ public: */ void resume(Object* sender); - + void setTouchEnabled(bool enabled); bool isDragging() const {return _dragging;} bool isTouchMoved() const { return _touchMoved; } bool isBounceable() const { return _bounceable; } @@ -347,6 +347,9 @@ protected: */ Rect _parentScissorRect; bool _scissorRestored; + + /** Touch listener */ + EventListenerTouchOneByOne* _touchListener; }; // end of GUI group From 0d2d522f12c3eca2b56c1412450b0171f48f04f6 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 16:15:37 +0800 Subject: [PATCH 042/144] issue #3069: int --> EventListener::Type. --- cocos/2d/CCEventListenerCustom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/CCEventListenerCustom.cpp b/cocos/2d/CCEventListenerCustom.cpp index 05e562b567..3875f61c94 100644 --- a/cocos/2d/CCEventListenerCustom.cpp +++ b/cocos/2d/CCEventListenerCustom.cpp @@ -32,7 +32,7 @@ EventListenerCustom::EventListenerCustom() { } -EventListenerCustom* EventListenerCustom::create(int type, std::function callback) +EventListenerCustom* EventListenerCustom::create(Type type, std::function callback) { EventListenerCustom* ret = new EventListenerCustom(); if (ret && ret->init(type, callback)) From cf20329b71aaa175407175673acbd58351449f14 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 16:33:54 +0800 Subject: [PATCH 043/144] issue #3069: Removing unused codes in UILayer. --- cocos/gui/UILayer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cocos/gui/UILayer.cpp b/cocos/gui/UILayer.cpp index 891301bf5b..d3a4e69fc5 100644 --- a/cocos/gui/UILayer.cpp +++ b/cocos/gui/UILayer.cpp @@ -89,7 +89,6 @@ void UILayer::onEnter() void UILayer::onExit() { -// setTouchEnabled(false); CCLayer::onExit(); } From 9bf44a6c83e67413bb9e245f03358be2e137340f Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 16:34:26 +0800 Subject: [PATCH 044/144] issue #3069: Renaming 'removeListeners' to 'removeEventListeners'. --- cocos/2d/CCEventDispatcher.cpp | 8 ++++---- cocos/2d/CCEventDispatcher.h | 4 ++-- .../NewEventDispatcherTest/NewEventDispatcherTest.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index a0e58363a3..386191f8a6 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -151,7 +151,7 @@ EventDispatcher::EventDispatcher() EventDispatcher::~EventDispatcher() { - removeAllListeners(); + removeAllEventListeners(); } EventDispatcher* EventDispatcher::getInstance() @@ -972,7 +972,7 @@ EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListene return nullptr; } -void EventDispatcher::removeListeners(EventListener::Type eventListenerType) +void EventDispatcher::removeEventListeners(EventListener::Type eventListenerType) { auto listenerItemIter = _listeners.find(eventListenerType); if (listenerItemIter != _listeners.end()) @@ -1019,7 +1019,7 @@ void EventDispatcher::removeListeners(EventListener::Type eventListenerType) } } -void EventDispatcher::removeAllListeners() +void EventDispatcher::removeAllEventListeners() { std::vector types(_listeners.size()); @@ -1030,7 +1030,7 @@ void EventDispatcher::removeAllListeners() for (auto& type : types) { - removeListeners(type); + removeEventListeners(type); } if (!_inDispatch) diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 25f1d8a509..a678431f7d 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -81,10 +81,10 @@ public: void removeEventListener(EventListener* listener); /** Removes all listeners with the same event listener type */ - void removeListeners(EventListener::Type eventListenerType); + void removeEventListeners(EventListener::Type eventListenerType); /** Removes all listeners */ - void removeAllListeners(); + void removeAllEventListeners(); /** Sets listener's priority with fixed value. */ void setPriority(EventListener* listener, int fixedPriority); diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index d4b5f9988e..cecb32a6d8 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -189,7 +189,7 @@ void TouchableSpriteTest::onEnter() auto senderItem = static_cast(sender); senderItem->setString("Only Next item could be clicked"); - EventDispatcher::getInstance()->removeListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); + EventDispatcher::getInstance()->removeEventListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); auto nextItem = MenuItemFont::create("Next", [=](Object* sender){ nextCallback(nullptr); From cb7e0b391bffcc32098be8c0fc520cb86e71170f Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 16:37:40 +0800 Subject: [PATCH 045/144] issue #3069: Removing unused variables in CCEventListenerTouch.h. --- cocos/2d/CCEventListenerTouch.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cocos/2d/CCEventListenerTouch.h b/cocos/2d/CCEventListenerTouch.h index a73dc1e992..09e6e6fe0c 100644 --- a/cocos/2d/CCEventListenerTouch.h +++ b/cocos/2d/CCEventListenerTouch.h @@ -36,8 +36,6 @@ NS_CC_BEGIN class EventListenerTouchOneByOne : public EventListener { public: - static const int TYPE = 0x01; - static EventListenerTouchOneByOne* create(); virtual ~EventListenerTouchOneByOne(); @@ -69,8 +67,6 @@ private: class EventListenerTouchAllAtOnce : public EventListener { public: - static const int TYPE = 0x02; - static EventListenerTouchAllAtOnce* create(); virtual ~EventListenerTouchAllAtOnce(); From 063b012a9c692576cf4f6d87f6e00a57448df39e Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 16:43:04 +0800 Subject: [PATCH 046/144] int --> Event::Type --- cocos/2d/CCEvent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/CCEvent.h b/cocos/2d/CCEvent.h index 348c2ba1d3..eecd7f396c 100644 --- a/cocos/2d/CCEvent.h +++ b/cocos/2d/CCEvent.h @@ -58,7 +58,7 @@ public: virtual ~Event(); /** Gets the event type */ - inline int getType() const { return _type; }; + inline Type getType() const { return _type; }; /** Stops propagation for current event */ inline void stopPropagation() { _isStopped = true; }; From 6c6757a04e3d4af114fa279a4930f3ce7b27d390 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 25 Oct 2013 17:03:50 +0800 Subject: [PATCH 047/144] issue #3069: Moving s_eventPriorityIndex to member variable of EventDispatcher. --- cocos/2d/CCEventDispatcher.cpp | 9 +++++---- cocos/2d/CCEventDispatcher.h | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 386191f8a6..e8d6331c0a 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -59,7 +59,7 @@ private: NS_CC_BEGIN static EventDispatcher* g_instance = nullptr; -static int s_eventPriorityIndex = 0; + EventDispatcher::EventListenerVector::EventListenerVector() : _sceneGraphListeners(nullptr) @@ -145,6 +145,7 @@ void EventDispatcher::EventListenerVector::clear() EventDispatcher::EventDispatcher() : _inDispatch(0) , _isEnabled(true) +, _nodePriorityIndex(0) { _toAddedListeners.reserve(50); } @@ -190,7 +191,7 @@ void EventDispatcher::visitTarget(Node* node) break; } - _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); + _nodePriorityMap.insert(std::make_pair(node, ++_nodePriorityIndex)); for( ; i < childrenCount; i++ ) { @@ -201,7 +202,7 @@ void EventDispatcher::visitTarget(Node* node) } else { - _nodePriorityMap.insert(std::make_pair(node, ++s_eventPriorityIndex)); + _nodePriorityMap.insert(std::make_pair(node, ++_nodePriorityIndex)); } } @@ -907,7 +908,7 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::Type Node* rootNode = (Node*)Director::getInstance()->getRunningScene(); // Reset priority index - s_eventPriorityIndex = 0; + _nodePriorityIndex = 0; _nodePriorityMap.clear(); visitTarget(rootNode); diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index a678431f7d..60baf25222 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -223,6 +223,8 @@ private: /** Whether to enable dispatching event */ bool _isEnabled; + + int _nodePriorityIndex; }; From 9ecc0c6db862c1ef09cfef4862a10bbdb2d7ba22 Mon Sep 17 00:00:00 2001 From: psi Date: Sat, 26 Oct 2013 13:33:31 +0900 Subject: [PATCH 048/144] include climits for UINT_MAX --- cocos/physics/CCPhysicsBody.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cocos/physics/CCPhysicsBody.cpp b/cocos/physics/CCPhysicsBody.cpp index 109fac9d6f..f1eb18e754 100644 --- a/cocos/physics/CCPhysicsBody.cpp +++ b/cocos/physics/CCPhysicsBody.cpp @@ -24,6 +24,7 @@ #include "CCPhysicsBody.h" #ifdef CC_USE_PHYSICS +#include #include #if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) From 48ce5e39fe6d4394c4c175c2690ef3ed119d9e40 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 26 Oct 2013 15:04:01 +0800 Subject: [PATCH 049/144] EventDispatcher is managed by Director now, like Scheduler and ActionManager. --- cocos/2d/CCDirector.cpp | 23 +++++++-- cocos/2d/CCDirector.h | 21 ++++++-- cocos/2d/CCEventDispatcher.cpp | 18 ------- cocos/2d/CCEventDispatcher.h | 14 ++---- cocos/2d/CCMenu.cpp | 4 +- cocos/2d/CCNode.cpp | 48 ++++++++++++++----- cocos/2d/CCNode.h | 28 ++++++++--- cocos/2d/CCTransition.cpp | 8 +--- cocos/2d/platform/CCEGLViewProtocol.cpp | 9 ++-- cocos/2d/platform/ios/CCDevice.mm | 2 +- cocos/2d/platform/mac/CCEGLView.mm | 3 +- .../cocostudio/CCInputDelegate.cpp | 16 ++++--- cocos/gui/UILayer.cpp | 2 +- .../cocos2d_specifics.cpp.REMOVED.git-id | 2 +- .../GUI/CCControlExtension/CCControl.cpp | 2 +- extensions/GUI/CCScrollView/CCScrollView.cpp | 14 +++--- .../AccelerometerTest/AccelerometerTest.cpp | 4 +- .../Classes/ActionsTest/ActionsTest.cpp | 2 +- .../Classes/Box2DTestBed/Box2dView.cpp | 8 ++-- .../Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp | 6 +-- .../Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp | 3 +- .../Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp | 2 +- .../Classes/ChipmunkTest/ChipmunkTest.cpp | 4 +- .../ClickAndMoveTest/ClickAndMoveTest.cpp | 3 +- .../ClippingNodeTest/ClippingNodeTest.cpp | 6 +-- .../CocosDenshionTest/CocosDenshionTest.cpp | 2 +- .../Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp | 2 +- .../CocoStudioArmatureTest/ArmatureScene.cpp | 6 +-- .../Classes/ExtensionsTest/ExtensionsTest.cpp | 2 +- .../Classes/KeyboardTest/KeyboardTest.cpp | 2 +- .../TestCpp/Classes/KeypadTest/KeypadTest.cpp | 2 +- .../TestCpp/Classes/LabelTest/LabelTest.cpp | 2 +- .../Classes/LabelTest/LabelTestNew.cpp | 2 +- .../TestCpp/Classes/LayerTest/LayerTest.cpp | 4 +- .../Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp | 12 ++--- .../MotionStreakTest/MotionStreakTest.cpp | 2 +- .../Classes/MutiTouchTest/MutiTouchTest.cpp | 2 +- .../NewEventDispatcherTest.cpp | 47 +++++++----------- .../Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp | 2 +- .../Classes/ParallaxTest/ParallaxTest.cpp | 2 +- .../Classes/ParticleTest/ParticleTest.cpp | 2 +- .../PerformanceTouchesTest.cpp | 12 ++--- .../Classes/PhysicsTest/PhysicsTest.cpp | 8 ++-- .../RenderTextureTest/RenderTextureTest.cpp | 6 +-- .../SpriteTest/SpriteTest.cpp.REMOVED.git-id | 2 +- .../Classes/TextInputTest/TextInputTest.cpp | 2 +- .../Classes/TileMapTest/TileMapTest.cpp | 2 +- .../TestCpp/Classes/TouchesTest/Paddle.cpp | 2 +- samples/Cpp/TestCpp/Classes/controller.cpp | 2 +- 49 files changed, 199 insertions(+), 182 deletions(-) diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index 9dc388ea11..ef8b38f423 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -59,7 +59,7 @@ THE SOFTWARE. #include "platform/CCImage.h" #include "CCEGLView.h" #include "CCConfiguration.h" - +#include "CCEventDispatcher.h" /** Position of the FPS @@ -143,6 +143,8 @@ bool Director::init(void) _actionManager = new ActionManager(); _scheduler->scheduleUpdateForTarget(_actionManager, Scheduler::PRIORITY_SYSTEM, false); + _eventDispatcher = new EventDispatcher(); + // create autorelease pool PoolManager::sharedPoolManager()->push(); @@ -162,7 +164,8 @@ Director::~Director(void) CC_SAFE_RELEASE(_scenesStack); CC_SAFE_RELEASE(_scheduler); CC_SAFE_RELEASE(_actionManager); - + CC_SAFE_RELEASE(_eventDispatcher); + // pop the autorelease pool PoolManager::sharedPoolManager()->pop(); PoolManager::purgePoolManager(); @@ -695,7 +698,6 @@ void Director::purgeDirector() // cocos2d-x specific data structures UserDefault::destroyInstance(); NotificationCenter::destroyInstance(); - EventDispatcher::destroyInstance(); GL::invalidateStateCache(); @@ -966,6 +968,21 @@ ActionManager* Director::getActionManager() const return _actionManager; } +EventDispatcher* Director::getEventDispatcher() const +{ + return _eventDispatcher; +} + +void Director::setEventDispatcher(EventDispatcher* dispatcher) +{ + if (_eventDispatcher != dispatcher) + { + CC_SAFE_RETAIN(dispatcher); + CC_SAFE_RELEASE(_eventDispatcher); + _eventDispatcher = dispatcher; + } +} + /*************************************************** * implementation of DisplayLinkDirector **************************************************/ diff --git a/cocos/2d/CCDirector.h b/cocos/2d/CCDirector.h index 4da35a96a8..5f0d6eb0a8 100644 --- a/cocos/2d/CCDirector.h +++ b/cocos/2d/CCDirector.h @@ -53,10 +53,7 @@ class DirectorDelegate; class Node; class Scheduler; class ActionManager; -class TouchDispatcher; -class KeyboardDispatcher; -class KeypadDispatcher; -class Accelerometer; +class EventDispatcher; /** @brief Class that creates and handles the main Window and manages how @@ -351,6 +348,17 @@ public: @since v2.0 */ void setActionManager(ActionManager* actionManager); + + /** Gets the EventDispatcher associated with this director + @since v3.0 + */ + EventDispatcher* getEventDispatcher() const; + + /** Sets the EventDispatcher associated with this director + @since v3.0 + */ + void setEventDispatcher(EventDispatcher* dispatcher); + /* Gets delta time since last tick to main loop */ float getDeltaTime() const; @@ -383,6 +391,11 @@ protected: @since v2.0 */ ActionManager* _actionManager; + + /** EventDispatcher associated with this director + @since v3.0 + */ + EventDispatcher* _eventDispatcher; /* delta time since last tick to main loop */ float _deltaTime; diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index e8d6331c0a..e0922b0796 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -58,9 +58,6 @@ private: NS_CC_BEGIN -static EventDispatcher* g_instance = nullptr; - - EventDispatcher::EventListenerVector::EventListenerVector() : _sceneGraphListeners(nullptr) , _fixedListeners(nullptr) @@ -155,21 +152,6 @@ EventDispatcher::~EventDispatcher() removeAllEventListeners(); } -EventDispatcher* EventDispatcher::getInstance() -{ - if (g_instance == nullptr) - { - g_instance = new EventDispatcher(); - } - - return g_instance; -} - -void EventDispatcher::destroyInstance() -{ - CC_SAFE_DELETE(g_instance); -} - void EventDispatcher::visitTarget(Node* node) { int i = 0; diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 60baf25222..e3650a1fae 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -50,15 +50,9 @@ event listeners can be added and removed even from within an EventListener, while events are being dispatched. */ -class EventDispatcher +class EventDispatcher : public Object { public: - /** Gets the singleton of EventDispatcher */ - static EventDispatcher* getInstance(); - - /** Destroys the singleton of EventDispatcher */ - static void destroyInstance(); - /** Adds a event listener for a specified event with the priority of scene graph. * @param listener The listener of a specified event. * @param node The priority of the listener is based on the draw order of this node. @@ -113,7 +107,8 @@ public: /** Notifys event dispatcher that the node has been deleted. */ void cleanTarget(Node* node); -public: + /** Constructor of EventDispatcher */ + EventDispatcher(); /** Destructor of EventDispatcher */ ~EventDispatcher(); @@ -144,9 +139,6 @@ private: std::vector* _sceneGraphListeners; int _gt0Index; }; - - /** Constructor of EventDispatcher */ - EventDispatcher(); /** Adds event listener with item */ void addEventListener(EventListener* listener); diff --git a/cocos/2d/CCMenu.cpp b/cocos/2d/CCMenu.cpp index 5a46765d91..3b0cefbec3 100644 --- a/cocos/2d/CCMenu.cpp +++ b/cocos/2d/CCMenu.cpp @@ -185,8 +185,6 @@ void Menu::onEnter() { Layer::onEnter(); - auto eventDispatcher = EventDispatcher::getInstance(); - auto touchListener = EventListenerTouchOneByOne::create(); touchListener->setSwallowTouches(true); @@ -195,7 +193,7 @@ void Menu::onEnter() touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this); touchListener->onTouchCancelled = CC_CALLBACK_2(Menu::onTouchCancelled, this); - eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); } void Menu::onExit() diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 427884abb0..5302648923 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -139,7 +139,9 @@ Node::Node(void) _actionManager->retain(); _scheduler = director->getScheduler(); _scheduler->retain(); - + _eventDispatcher = director->getEventDispatcher(); + _eventDispatcher->retain(); + ScriptEngineProtocol* pEngine = ScriptEngineManager::getInstance()->getScriptEngine(); _scriptType = pEngine != NULL ? pEngine->getScriptType() : kScriptTypeNone; } @@ -155,6 +157,10 @@ Node::~Node() CC_SAFE_RELEASE(_actionManager); CC_SAFE_RELEASE(_scheduler); + + _eventDispatcher->cleanTarget(this); + CC_SAFE_RELEASE(_eventDispatcher); + // attributes CC_SAFE_RELEASE(_camera); @@ -182,8 +188,6 @@ Node::~Node() CC_SAFE_DELETE(_componentContainer); - EventDispatcher::getInstance()->cleanTarget(this); - #ifdef CC_USE_PHYSICS CC_SAFE_RELEASE(_physicsBody); #endif @@ -238,7 +242,7 @@ void Node::setZOrder(int z) _parent->reorderChild(this, z); } - EventDispatcher::getInstance()->setDirtyForNode(this); + _eventDispatcher->setDirtyForNode(this); } /// vertexZ getter @@ -931,8 +935,7 @@ void Node::onEnter() arrayMakeObjectsPerformSelector(_children, onEnter, Node*); - this->resumeSchedulerAndActions(); - EventDispatcher::getInstance()->resumeTarget(this); + this->resume(); _running = true; @@ -974,9 +977,7 @@ void Node::onExitTransitionDidStart() void Node::onExit() { - EventDispatcher::getInstance()->pauseTarget(this); - - this->pauseSchedulerAndActions(); + this->pause(); _running = false; if (_scriptType != kScriptTypeNone) @@ -990,6 +991,17 @@ void Node::onExit() arrayMakeObjectsPerformSelector(_children, onExit, Node*); } +void Node::setEventDispatcher(EventDispatcher* dispatcher) +{ + if (dispatcher != _eventDispatcher) + { + _eventDispatcher->cleanTarget(this); + CC_SAFE_RETAIN(dispatcher); + CC_SAFE_RELEASE(_eventDispatcher); + _eventDispatcher = dispatcher; + } +} + void Node::setActionManager(ActionManager* actionManager) { if( actionManager != _actionManager ) { @@ -1115,16 +1127,28 @@ void Node::unscheduleAllSelectors() _scheduler->unscheduleAllForTarget(this); } -void Node::resumeSchedulerAndActions() +void Node::resume() { _scheduler->resumeTarget(this); _actionManager->resumeTarget(this); + _eventDispatcher->resumeTarget(this); +} + +void Node::pause() +{ + _scheduler->pauseTarget(this); + _actionManager->pauseTarget(this); + _eventDispatcher->pauseTarget(this); +} + +void Node::resumeSchedulerAndActions() +{ + resume(); } void Node::pauseSchedulerAndActions() { - _scheduler->pauseTarget(this); - _actionManager->pauseTarget(this); + pause(); } // override me diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index fcc38b23b5..cde05c34c3 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -995,6 +995,9 @@ public: /** @deprecated Use getBoundingBox instead */ CC_DEPRECATED_ATTRIBUTE inline virtual Rect boundingBox() const { return getBoundingBox(); } + virtual void setEventDispatcher(EventDispatcher* dispatcher); + virtual EventDispatcher* getEventDispatcher() const { return _eventDispatcher; }; + /// @{ /// @name Actions @@ -1192,16 +1195,27 @@ public: */ void unscheduleAllSelectors(void); - /** - * Resumes all scheduled selectors and actions. + /** + * Resumes all scheduled selectors, actions and event listeners. * This method is called internally by onEnter */ - void resumeSchedulerAndActions(void); - /** - * Pauses all scheduled selectors and actions. + void resume(void); + /** + * Pauses all scheduled selectors, actions and event listeners.. * This method is called internally by onExit */ - void pauseSchedulerAndActions(void); + void pause(void); + + /** + * Resumes all scheduled selectors, actions and event listeners. + * This method is called internally by onEnter + */ + CC_DEPRECATED_ATTRIBUTE void resumeSchedulerAndActions(void); + /** + * Pauses all scheduled selectors, actions and event listeners.. + * This method is called internally by onExit + */ + CC_DEPRECATED_ATTRIBUTE void pauseSchedulerAndActions(void); /* * Update method will be called automatically every frame if "scheduleUpdate" is called, and the node is "live" @@ -1461,6 +1475,8 @@ protected: ActionManager *_actionManager; ///< a pointer to ActionManager singleton, which is used to handle all the actions + EventDispatcher* _eventDispatcher; ///< event dispatcher used to dispatch all kinds of events + bool _running; ///< is running bool _visible; ///< is this node visible diff --git a/cocos/2d/CCTransition.cpp b/cocos/2d/CCTransition.cpp index 5dea9ae721..4642b7404b 100644 --- a/cocos/2d/CCTransition.cpp +++ b/cocos/2d/CCTransition.cpp @@ -160,9 +160,7 @@ void TransitionScene::onEnter() Scene::onEnter(); // disable events while transitions -// Director::getInstance()->getTouchDispatcher()->setDispatchEvents(false); - - EventDispatcher::getInstance()->setEnabled(false); + _eventDispatcher->setEnabled(false); // outScene should not receive the onEnter callback // only the onExitTransitionDidStart @@ -177,9 +175,7 @@ void TransitionScene::onExit() Scene::onExit(); // enable events while transitions -// Director::getInstance()->getTouchDispatcher()->setDispatchEvents(true); - - EventDispatcher::getInstance()->setEnabled(true); + _eventDispatcher->setEnabled(true); _outScene->onExit(); // _inScene should not receive the onEnter callback diff --git a/cocos/2d/platform/CCEGLViewProtocol.cpp b/cocos/2d/platform/CCEGLViewProtocol.cpp index 9b1e943019..17eafdf0d6 100644 --- a/cocos/2d/platform/CCEGLViewProtocol.cpp +++ b/cocos/2d/platform/CCEGLViewProtocol.cpp @@ -247,7 +247,8 @@ void EGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float y } touchEvent._eventCode = EventTouch::EventCode::BEGAN; - EventDispatcher::getInstance()->dispatchEvent(&touchEvent); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&touchEvent); } void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[]) @@ -294,7 +295,8 @@ void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys } touchEvent._eventCode = EventTouch::EventCode::MOVED; - EventDispatcher::getInstance()->dispatchEvent(&touchEvent); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&touchEvent); } void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, int ids[], float xs[], float ys[]) @@ -347,7 +349,8 @@ void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode } touchEvent._eventCode = eventCode; - EventDispatcher::getInstance()->dispatchEvent(&touchEvent); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&touchEvent); for (auto& touch : touchEvent._touches) { diff --git a/cocos/2d/platform/ios/CCDevice.mm b/cocos/2d/platform/ios/CCDevice.mm index 83212d575d..fdc9448849 100644 --- a/cocos/2d/platform/ios/CCDevice.mm +++ b/cocos/2d/platform/ios/CCDevice.mm @@ -100,7 +100,7 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher; } cocos2d::EventAcceleration event(*_acceleration); - cocos2d::EventDispatcher::getInstance()->dispatchEvent(&event); + cocos2d::_eventDispatcherdispatchEvent(&event); } @end diff --git a/cocos/2d/platform/mac/CCEGLView.mm b/cocos/2d/platform/mac/CCEGLView.mm index d8dce7ba57..bd3ba3b5c5 100644 --- a/cocos/2d/platform/mac/CCEGLView.mm +++ b/cocos/2d/platform/mac/CCEGLView.mm @@ -239,7 +239,8 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); - EventDispatcher::getInstance()->dispatchEvent(&event); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWCharCallback(GLFWwindow *window, unsigned int character) diff --git a/cocos/editor-support/cocostudio/CCInputDelegate.cpp b/cocos/editor-support/cocostudio/CCInputDelegate.cpp index 968645bc4e..a134e3cdfe 100644 --- a/cocos/editor-support/cocostudio/CCInputDelegate.cpp +++ b/cocos/editor-support/cocostudio/CCInputDelegate.cpp @@ -43,7 +43,7 @@ InputDelegate::InputDelegate(void) InputDelegate::~InputDelegate(void) { - auto dispatcher = EventDispatcher::getInstance(); + auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->removeEventListener(_touchListener); dispatcher->removeEventListener(_keyboardListener); dispatcher->removeEventListener(_accelerometerListener); @@ -107,6 +107,7 @@ void InputDelegate::setTouchEnabled(bool enabled) { if (_touchEnabled != enabled) { + auto dispatcher = Director::getInstance()->getEventDispatcher(); _touchEnabled = enabled; if (enabled) { @@ -119,7 +120,7 @@ void InputDelegate::setTouchEnabled(bool enabled) listener->onTouchesEnded = CC_CALLBACK_2(InputDelegate::onTouchesEnded, this); listener->onTouchesCancelled = CC_CALLBACK_2(InputDelegate::onTouchesCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, _touchPriority); + dispatcher->addEventListenerWithFixedPriority(listener, _touchPriority); _touchListener = listener; } else { // Register Touch Event @@ -131,13 +132,13 @@ void InputDelegate::setTouchEnabled(bool enabled) listener->onTouchEnded = CC_CALLBACK_2(InputDelegate::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(InputDelegate::onTouchCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, _touchPriority); + dispatcher->addEventListenerWithFixedPriority(listener, _touchPriority); _touchListener = listener; } } else { - EventDispatcher::getInstance()->removeEventListener(_touchListener); + dispatcher->removeEventListener(_touchListener); } } } @@ -191,7 +192,7 @@ void InputDelegate::setAccelerometerEnabled(bool enabled) { _accelerometerEnabled = enabled; - auto dispatcher = EventDispatcher::getInstance(); + auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->removeEventListener(_accelerometerListener); _accelerometerListener = nullptr; @@ -215,7 +216,8 @@ void InputDelegate::setKeypadEnabled(bool enabled) { _keypadEnabled = enabled; - EventDispatcher::getInstance()->removeEventListener(_keyboardListener); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->removeEventListener(_keyboardListener); if (enabled) { @@ -223,7 +225,7 @@ void InputDelegate::setKeypadEnabled(bool enabled) listener->onKeyPressed = CC_CALLBACK_2(InputDelegate::onKeyPressed, this); listener->onKeyReleased = CC_CALLBACK_2(InputDelegate::onKeyReleased, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, -1); + dispatcher->addEventListenerWithFixedPriority(listener, -1); _keyboardListener = listener; } } diff --git a/cocos/gui/UILayer.cpp b/cocos/gui/UILayer.cpp index d3a4e69fc5..bfdea4094f 100644 --- a/cocos/gui/UILayer.cpp +++ b/cocos/gui/UILayer.cpp @@ -84,7 +84,7 @@ void UILayer::onEnter() listener->onTouchEnded = CC_CALLBACK_2(UILayer::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(UILayer::onTouchCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void UILayer::onExit() diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index 25626c360d..c661a05129 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -c4104d83bf7e5cc0b0eab7bb3753f9f053358054 \ No newline at end of file +1475f1478d176a00cc8d0f9b3302881dee7a8437 \ No newline at end of file diff --git a/extensions/GUI/CCControlExtension/CCControl.cpp b/extensions/GUI/CCControlExtension/CCControl.cpp index 1419edbc36..2b97094acc 100644 --- a/extensions/GUI/CCControlExtension/CCControl.cpp +++ b/extensions/GUI/CCControlExtension/CCControl.cpp @@ -97,7 +97,7 @@ void Control::onEnter() { Layer::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); + auto dispatcher = Director::getInstance()->getEventDispatcher(); auto touchListener = EventListenerTouchOneByOne::create(); touchListener->onTouchBegan = CC_CALLBACK_2(Control::onTouchBegan, this); touchListener->onTouchMoved = CC_CALLBACK_2(Control::onTouchMoved, this); diff --git a/extensions/GUI/CCScrollView/CCScrollView.cpp b/extensions/GUI/CCScrollView/CCScrollView.cpp index 35287bb9ce..8db57d6377 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.cpp +++ b/extensions/GUI/CCScrollView/CCScrollView.cpp @@ -151,7 +151,7 @@ bool ScrollView::isNodeVisible(Node* node) void ScrollView::pause(Object* sender) { - _container->pauseSchedulerAndActions(); + _container->pause(); Object* pObj = NULL; Array* pChildren = _container->getChildren(); @@ -159,7 +159,7 @@ void ScrollView::pause(Object* sender) CCARRAY_FOREACH(pChildren, pObj) { Node* pChild = static_cast(pObj); - pChild->pauseSchedulerAndActions(); + pChild->pause(); } } @@ -171,17 +171,15 @@ void ScrollView::resume(Object* sender) CCARRAY_FOREACH(pChildren, pObj) { Node* pChild = static_cast(pObj); - pChild->resumeSchedulerAndActions(); + pChild->resume(); } - _container->resumeSchedulerAndActions(); + _container->resume(); } void ScrollView::setTouchEnabled(bool enabled) { - auto dispatcher = EventDispatcher::getInstance(); - - dispatcher->removeEventListener(_touchListener); + _eventDispatcher->removeEventListener(_touchListener); if (enabled) { @@ -191,7 +189,7 @@ void ScrollView::setTouchEnabled(bool enabled) _touchListener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this); _touchListener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this); - dispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this); } else { diff --git a/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp b/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp index ada7540cc6..db535fe321 100644 --- a/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp +++ b/samples/Cpp/TestCpp/Classes/AccelerometerTest/AccelerometerTest.cpp @@ -32,10 +32,8 @@ void AccelerometerTest::onEnter() { Layer::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(AccelerometerTest::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto label = LabelTTF::create(title().c_str(), "Arial", 32); addChild(label, 1); diff --git a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp index c41f06c377..703e8bf40b 100644 --- a/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ActionsTest/ActionsTest.cpp @@ -1377,7 +1377,7 @@ void ActionStacked::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(ActionStacked::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); this->addNewSpriteWithCoords(Point(s.width/2, s.height/2)); diff --git a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp index 0cfbabd90c..e50611afda 100644 --- a/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp +++ b/samples/Cpp/TestCpp/Classes/Box2DTestBed/Box2dView.cpp @@ -33,7 +33,7 @@ MenuLayer::MenuLayer(void) MenuLayer::~MenuLayer(void) { - EventDispatcher::getInstance()->removeEventListener(_touchListener); + _eventDispatcher->removeEventListener(_touchListener); } MenuLayer* MenuLayer::menuWithEntryID(int entryId) @@ -86,7 +86,7 @@ bool MenuLayer::initWithEntryID(int entryId) listener->onTouchBegan = CC_CALLBACK_2(MenuLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(MenuLayer::onTouchMoved, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, 1); + _eventDispatcher->addEventListenerWithFixedPriority(listener, 1); _touchListener = listener; @@ -190,7 +190,7 @@ bool Box2DView::initWithEntryID(int entryId) listener->onTouchMoved = CC_CALLBACK_2(Box2DView::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(Box2DView::onTouchEnded, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, -10); + _eventDispatcher->addEventListenerWithFixedPriority(listener, -10); _touchListener = listener; return true; @@ -224,7 +224,7 @@ void Box2DView::draw() Box2DView::~Box2DView() { // Removes Touch Event Listener - EventDispatcher::getInstance()->removeEventListener(_touchListener); + _eventDispatcher->removeEventListener(_touchListener); delete m_test; } // diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp index 9eb6d6ab5c..e0c4ba23ed 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-624.cpp @@ -20,9 +20,8 @@ bool Bug624Layer::init() label->setPosition(Point(size.width/2, size.height/2)); addChild(label); - auto dispatcher = EventDispatcher::getInstance(); auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); schedule(schedule_selector(Bug624Layer::switchLayer), 5.0f); @@ -61,9 +60,8 @@ bool Bug624Layer2::init() label->setPosition(Point(size.width/2, size.height/2)); addChild(label); - auto dispatcher = EventDispatcher::getInstance(); auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(Bug624Layer2::onAcceleration, this)); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); schedule(schedule_selector(Bug624Layer2::switchLayer), 5.0f); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp index 76ab5b3b31..1064524e1c 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/Bug-914.cpp @@ -30,11 +30,10 @@ bool Bug914Layer::init() // Apple recommends to re-assign "self" with the "super" return value if (BugsTestBaseLayer::init()) { - auto dispatcher = EventDispatcher::getInstance(); auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = CC_CALLBACK_2(Bug914Layer::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(Bug914Layer::onTouchesMoved, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp index 1d81217bbb..096ca45d21 100644 --- a/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/BugsTest/BugsTest.cpp @@ -72,7 +72,7 @@ void BugsTestMainLayer::onEnter() listener->onTouchesBegan = CC_CALLBACK_2(BugsTestMainLayer::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(BugsTestMainLayer::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void BugsTestMainLayer::onTouchesBegan(const std::vector& touches, Event *event) diff --git a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp index bb3ef0e12f..50d5dc7252 100644 --- a/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ChipmunkTest/ChipmunkTest.cpp @@ -24,10 +24,10 @@ ChipmunkTestLayer::ChipmunkTestLayer() auto touchListener = EventListenerTouchAllAtOnce::create(); touchListener->onTouchesEnded = CC_CALLBACK_2(ChipmunkTestLayer::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(touchListener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(ChipmunkTestLayer::onAcceleration, this)); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(accListener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(accListener, this); // title auto label = LabelTTF::create("Multi touch the screen", "Marker Felt", 36); diff --git a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp index 408188925f..6b45dd9c32 100644 --- a/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ClickAndMoveTest/ClickAndMoveTest.cpp @@ -17,11 +17,10 @@ void ClickAndMoveTestScene::runThisTest() MainLayer::MainLayer() { - auto dispatcher = EventDispatcher::getInstance(); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan, this); listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto sprite = Sprite::create(s_pathGrossini); diff --git a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp index 56ad34de68..93e26514a2 100644 --- a/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ClippingNodeTest/ClippingNodeTest.cpp @@ -449,10 +449,9 @@ void HoleDemo::setup() this->addChild(_outerClipper); - auto dispatcher = EventDispatcher::getInstance(); auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = CC_CALLBACK_2(HoleDemo::onTouchesBegan, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void HoleDemo::pokeHoleAtPoint(Point point) @@ -529,12 +528,11 @@ void ScrollViewDemo::setup() _scrolling = false; - auto dispatcher = EventDispatcher::getInstance(); auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = CC_CALLBACK_2(ScrollViewDemo::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(ScrollViewDemo::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(ScrollViewDemo::onTouchesEnded, this); - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void ScrollViewDemo::onTouchesBegan(const std::vector& touches, Event *event) diff --git a/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp b/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp index e83cb001f1..63959537d8 100644 --- a/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp +++ b/samples/Cpp/TestCpp/Classes/CocosDenshionTest/CocosDenshionTest.cpp @@ -72,7 +72,7 @@ private: listener->onTouchEnded = CC_CALLBACK_2(Button::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(Button::onTouchCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } diff --git a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp index f3ad65db63..8d92edf249 100644 --- a/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp +++ b/samples/Cpp/TestCpp/Classes/CurlTest/CurlTest.cpp @@ -11,7 +11,7 @@ CurlTest::CurlTest() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(CurlTest::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // create a label to display the tip string _label = LabelTTF::create("Touch the screen to connect", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp index fef387ac01..1cd233ffd2 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp @@ -480,7 +480,7 @@ void TestParticleDisplay::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(TestParticleDisplay::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); animationID = 0; @@ -540,7 +540,7 @@ void TestUseMutiplePicture::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(TestUseMutiplePicture::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); displayIndex = 0; @@ -944,7 +944,7 @@ void TestArmatureNesting::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(TestArmatureNesting::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); armature = Armature::create("cyborg"); armature->getAnimation()->playByIndex(1); diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp index 5ba010f2a9..96089e9a2c 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp @@ -122,7 +122,7 @@ void ExtensionsMainLayer::onEnter() listener->onTouchesBegan = CC_CALLBACK_2(ExtensionsMainLayer::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(ExtensionsMainLayer::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); addChild(_itemMenu); } diff --git a/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp b/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp index a8a164da01..24b95f0df6 100644 --- a/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp +++ b/samples/Cpp/TestCpp/Classes/KeyboardTest/KeyboardTest.cpp @@ -11,7 +11,7 @@ KeyboardTest::KeyboardTest() listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this); listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // create a label to display the tip string _label = LabelTTF::create("Please press any key and see console log...", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp index c3191d5724..b025680265 100644 --- a/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp +++ b/samples/Cpp/TestCpp/Classes/KeypadTest/KeypadTest.cpp @@ -10,7 +10,7 @@ KeypadTest::KeypadTest() auto listener = EventListenerKeyboard::create(); listener->onKeyReleased = CC_CALLBACK_2(KeypadTest::onKeyReleased, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // create a label to display the tip string _label = LabelTTF::create("Please press any key...", "Arial", 22); diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp index f95831074e..ea9405eabe 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTest.cpp @@ -1140,7 +1140,7 @@ BitmapFontMultiLineAlignment::BitmapFontMultiLineAlignment() listener->onTouchesMoved = CC_CALLBACK_2(BitmapFontMultiLineAlignment::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(BitmapFontMultiLineAlignment::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp index d6d5777ada..f22c5a7864 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp @@ -655,7 +655,7 @@ LabelFNTMultiLineAlignment::LabelFNTMultiLineAlignment() listener->onTouchesMoved = CC_CALLBACK_2(LabelFNTMultiLineAlignment::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(LabelFNTMultiLineAlignment::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // ask director the the window size auto size = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp index 9fcc560cdf..581928a4f3 100644 --- a/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp +++ b/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp @@ -454,7 +454,7 @@ void LayerTest1::onEnter() listener->onTouchesMoved = CC_CALLBACK_2(LayerTest1::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(LayerTest1::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); auto layer = LayerColor::create( Color4B(0xFF, 0x00, 0x00, 0x80), 200, 200); @@ -597,7 +597,7 @@ LayerGradientTest::LayerGradientTest() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(LayerGradientTest::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto label1 = LabelTTF::create("Compressed Interpolation: Enabled", "Marker Felt", 26); auto label2 = LabelTTF::create("Compressed Interpolation: Disabled", "Marker Felt", 26); diff --git a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp index d295de75bc..f85bb260cd 100644 --- a/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MenuTest/MenuTest.cpp @@ -32,7 +32,7 @@ MenuLayerMainMenu::MenuLayerMainMenu() _touchListener->onTouchEnded = CC_CALLBACK_2(MenuLayerMainMenu::onTouchEnded, this); _touchListener->onTouchCancelled = CC_CALLBACK_2(MenuLayerMainMenu::onTouchCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(_touchListener, 1); + _eventDispatcher->addEventListenerWithFixedPriority(_touchListener, 1); // Font Item auto spriteNormal = Sprite::create(s_MenuItem, Rect(0,23*2,115,23)); @@ -138,7 +138,7 @@ void MenuLayerMainMenu::onTouchMoved(Touch *touch, Event * event) MenuLayerMainMenu::~MenuLayerMainMenu() { - EventDispatcher::getInstance()->removeEventListener(_touchListener); + _eventDispatcher->removeEventListener(_touchListener); _disabledItem->release(); } @@ -154,7 +154,7 @@ void MenuLayerMainMenu::menuCallbackConfig(Object* sender) void MenuLayerMainMenu::allowTouches(float dt) { - EventDispatcher::getInstance()->setPriority(_touchListener, 1); + _eventDispatcher->setPriority(_touchListener, 1); unscheduleAllSelectors(); log("TOUCHES ALLOWED AGAIN"); } @@ -162,7 +162,7 @@ void MenuLayerMainMenu::allowTouches(float dt) void MenuLayerMainMenu::menuCallbackDisabled(Object* sender) { // hijack all touch events for 5 seconds - EventDispatcher::getInstance()->setPriority(_touchListener, -1); + _eventDispatcher->setPriority(_touchListener, -1); schedule(schedule_selector(MenuLayerMainMenu::allowTouches), 5.0f); log("TOUCHES DISABLED FOR 5 SECONDS"); } @@ -583,7 +583,7 @@ RemoveMenuItemWhenMove::RemoveMenuItemWhenMove() _touchListener->onTouchBegan = CC_CALLBACK_2(RemoveMenuItemWhenMove::onTouchBegan, this); _touchListener->onTouchMoved = CC_CALLBACK_2(RemoveMenuItemWhenMove::onTouchMoved, this); - EventDispatcher::getInstance()->addEventListenerWithFixedPriority(_touchListener, -129); + _eventDispatcher->addEventListenerWithFixedPriority(_touchListener, -129); } @@ -594,7 +594,7 @@ void RemoveMenuItemWhenMove::goBack(Object *pSender) RemoveMenuItemWhenMove::~RemoveMenuItemWhenMove() { - EventDispatcher::getInstance()->removeEventListener(_touchListener); + _eventDispatcher->removeEventListener(_touchListener); CC_SAFE_RELEASE(item); } diff --git a/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp b/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp index 13a376ec29..9d9057c3e7 100644 --- a/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MotionStreakTest/MotionStreakTest.cpp @@ -123,7 +123,7 @@ void MotionStreakTest2::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(MotionStreakTest2::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp index 42e6634de5..2287ff517a 100644 --- a/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp +++ b/samples/Cpp/TestCpp/Classes/MutiTouchTest/MutiTouchTest.cpp @@ -60,7 +60,7 @@ bool MutiTouchTestLayer::init() listener->onTouchesBegan = CC_CALLBACK_2(MutiTouchTestLayer::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(MutiTouchTestLayer::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(MutiTouchTestLayer::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto title = LabelTTF::create("Please touch the screen!", "", 24); title->setPosition(VisibleRect::top()+Point(0, -40)); diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index cecb32a6d8..aa45afa24d 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -124,8 +124,6 @@ void TouchableSpriteTest::onEnter() { EventDispatcherTestDemo::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); @@ -180,16 +178,16 @@ void TouchableSpriteTest::onEnter() } }; - dispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); - dispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2); - dispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3); auto removeAllTouchItem = MenuItemFont::create("Remove All Touch Listeners", [this](Object* sender){ auto senderItem = static_cast(sender); senderItem->setString("Only Next item could be clicked"); - EventDispatcher::getInstance()->removeEventListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); + _eventDispatcher->removeEventListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); auto nextItem = MenuItemFont::create("Next", [=](Object* sender){ nextCallback(nullptr); @@ -242,8 +240,6 @@ public: { Sprite::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); @@ -271,19 +267,18 @@ public: if (_useNodePriority) { - dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } else { - dispatcher->addEventListenerWithFixedPriority(listener, _fixedPriority); + _eventDispatcher->addEventListenerWithFixedPriority(listener, _fixedPriority); } _listener = listener; } void onExit() override { - auto dispatcher = EventDispatcher::getInstance(); - dispatcher->removeEventListener(_listener); + _eventDispatcher->removeEventListener(_listener); Sprite::onExit(); } @@ -339,8 +334,6 @@ void RemoveListenerWhenDispatching::onEnter() { EventDispatcherTestDemo::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); @@ -372,7 +365,7 @@ void RemoveListenerWhenDispatching::onEnter() sprite1->setColor(Color3B::WHITE); }; - dispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); auto statusLabel = LabelTTF::create("The sprite could be touched!", "", 20); statusLabel->setPosition(origin + Point(size.width/2, size.height-90)); @@ -382,14 +375,14 @@ void RemoveListenerWhenDispatching::onEnter() auto toggleItem = MenuItemToggle::createWithCallback([=](Object* sender){ if (*enable) { - dispatcher->removeEventListener(listener1); + _eventDispatcher->removeEventListener(listener1); statusLabel->setString("The sprite could not be touched!"); (*enable) = false; } else { - dispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); statusLabel->setString("The sprite could be touched!"); (*enable) = true; @@ -418,8 +411,6 @@ void CustomEventTest::onEnter() { EventDispatcherTestDemo::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); @@ -437,7 +428,7 @@ void CustomEventTest::onEnter() delete[] buf; }); - dispatcher->addEventListenerWithFixedPriority(_listener, 1); + _eventDispatcher->addEventListenerWithFixedPriority(_listener, 1); auto sendItem = MenuItemFont::create("Send Custom Event", [=](Object* sender){ static int count = 0; @@ -446,7 +437,7 @@ void CustomEventTest::onEnter() sprintf(buf, "%d", count); EventCustom event(game_custom_event); event.setUserData(buf); - dispatcher->dispatchEvent(&event); + _eventDispatcher->dispatchEvent(&event); }); sendItem->setPosition(origin + Point(size.width/2, size.height/2)); auto menu = Menu::create(sendItem, nullptr); @@ -457,7 +448,7 @@ void CustomEventTest::onEnter() void CustomEventTest::onExit() { - EventDispatcher::getInstance()->removeEventListener(_listener); + _eventDispatcher->removeEventListener(_listener); EventDispatcherTestDemo::onExit(); } @@ -476,8 +467,6 @@ void LabelKeyboardEventTest::onEnter() { EventDispatcherTestDemo::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); @@ -500,7 +489,7 @@ void LabelKeyboardEventTest::onEnter() label->setString(buf); }; - dispatcher->addEventListenerWithSceneGraphPriority(listener, statusLabel); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, statusLabel); } std::string LabelKeyboardEventTest::title() @@ -524,8 +513,6 @@ _pos = _max; \ EventDispatcherTestDemo::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); @@ -550,7 +537,7 @@ _pos = _max; \ sprite->setPosition(ptNow); }); - dispatcher->addEventListenerWithSceneGraphPriority(listener, sprite); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite); } void SpriteAccelerationEventTest::onExit() @@ -576,8 +563,6 @@ void RemoveAndRetainNodeTest::onEnter() EventDispatcherTestDemo::onEnter(); - auto dispatcher = EventDispatcher::getInstance(); - Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); @@ -616,7 +601,7 @@ void RemoveAndRetainNodeTest::onEnter() target->setOpacity(255); }; - dispatcher->addEventListenerWithSceneGraphPriority(listener1, _sprite); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, _sprite); this->runAction(Sequence::create(DelayTime::create(5.0f), CallFunc::create([this](){ diff --git a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp index 3276a9b620..82a8a6ebcb 100644 --- a/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NodeTest/NodeTest.cpp @@ -725,7 +725,7 @@ ConvertToNode::ConvertToNode() { auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(ConvertToNode::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp index e14105b62e..5f58111b6c 100644 --- a/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ParallaxTest/ParallaxTest.cpp @@ -89,7 +89,7 @@ Parallax2::Parallax2() { auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(Parallax2::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // Top Layer, a simple image auto cocosImage = Sprite::create(s_Power); diff --git a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp index 9e35114538..d238482244 100644 --- a/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ParticleTest/ParticleTest.cpp @@ -1072,7 +1072,7 @@ void ParticleDemo::onEnter(void) listener->onTouchesBegan = CC_CALLBACK_2(ParticleDemo::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(ParticleDemo::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(ParticleDemo::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp index 5f1e9566ab..f3a804d907 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTouchesTest.cpp @@ -125,7 +125,7 @@ void TouchesPerformTest1::onEnter() listener->onTouchMoved = CC_CALLBACK_2(TouchesPerformTest1::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(TouchesPerformTest1::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(TouchesPerformTest1::onTouchCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } std::string TouchesPerformTest1::title() @@ -168,7 +168,7 @@ void TouchesPerformTest2::onEnter() listener->onTouchesMoved = CC_CALLBACK_2(TouchesPerformTest2::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(TouchesPerformTest2::onTouchesEnded, this); listener->onTouchesCancelled = CC_CALLBACK_2(TouchesPerformTest2::onTouchesCancelled, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } std::string TouchesPerformTest2::title() @@ -242,14 +242,14 @@ void TouchesPerformTest3::onEnter() listener->onTouchMoved = CC_CALLBACK_2(TouchableLayer::onTouchMoved, layer); listener->onTouchEnded = CC_CALLBACK_2(TouchableLayer::onTouchEnded, layer); listener->onTouchCancelled = CC_CALLBACK_2(TouchableLayer::onTouchCancelled, layer); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, layer); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, layer); addChild(layer, zorder); layer->release(); } auto emitEventlabel = LabelTTF::create("Emit Touch Event", "", 24); - auto menuItem = MenuItemLabel::create(emitEventlabel, [](Object* sender){ + auto menuItem = MenuItemLabel::create(emitEventlabel, [this](Object* sender){ CC_PROFILER_PURGE_ALL(); @@ -265,13 +265,11 @@ void TouchesPerformTest3::onEnter() event.setEventCode(EventTouch::EventCode::BEGAN); event.setTouches(touches); - auto dispatcher = EventDispatcher::getInstance(); - for (int i = 0; i < 100; ++i) { CC_PROFILER_START(TOUCH_PROFILER_NAME); - dispatcher->dispatchEvent(&event); + _eventDispatcher->dispatchEvent(&event); CC_PROFILER_STOP(TOUCH_PROFILER_NAME); } diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 874f5ebe61..fab2a82437 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -200,10 +200,10 @@ void PhysicsDemoClickAdd::onEnter() auto touchListener = EventListenerTouchAllAtOnce::create(); touchListener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoClickAdd::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(touchListener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(PhysicsDemoClickAdd::onAcceleration, this)); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(accListener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(accListener, this); auto node = Node::create(); node->setPhysicsBody(PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size)); @@ -514,7 +514,7 @@ void PhysicsDemoRayCast::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoRayCast::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); _scene->getPhysicsWorld()->setGravity(Point::ZERO); @@ -717,7 +717,7 @@ void PhysicsDemoJoints::onEnter() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoJoints::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); _scene->getPhysicsWorld()->setGravity(Point::ZERO); diff --git a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp index 113d4adad3..baf174ac9b 100644 --- a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp +++ b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp @@ -114,7 +114,7 @@ RenderTextureSave::RenderTextureSave() auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(RenderTextureSave::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // Save Image menu MenuItemFont::setFontSize(16); @@ -303,7 +303,7 @@ RenderTextureZbuffer::RenderTextureZbuffer() listener->onTouchesBegan = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesBegan, this); listener->onTouchesMoved = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesMoved, this); listener->onTouchesEnded = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto size = Director::getInstance()->getWinSize(); auto label = LabelTTF::create("vertexZ = 50", "Marker Felt", 64); @@ -637,7 +637,7 @@ SpriteRenderTextureBug::SpriteRenderTextureBug() { auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesEnded = CC_CALLBACK_2(SpriteRenderTextureBug::onTouchesEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); auto s = Director::getInstance()->getWinSize(); addNewSpriteWithCoords(Point(s.width/2, s.height/2)); diff --git a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id index ee1480acae..499b1b8dfe 100644 --- a/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id +++ b/samples/Cpp/TestCpp/Classes/SpriteTest/SpriteTest.cpp.REMOVED.git-id @@ -1 +1 @@ -fdf35bd639fd5d617e5a280530d6aefe63b94857 \ No newline at end of file +71aa9486e8535b9bd65cae247bb86de59c83f522 \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp index b922271656..d0ac2cb6b6 100644 --- a/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp +++ b/samples/Cpp/TestCpp/Classes/TextInputTest/TextInputTest.cpp @@ -130,7 +130,7 @@ KeyboardNotificationLayer::KeyboardNotificationLayer() auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(KeyboardNotificationLayer::onTouchBegan, this); listener->onTouchEnded = CC_CALLBACK_2(KeyboardNotificationLayer::onTouchEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } //void KeyboardNotificationLayer::registerWithTouchDispatcher() diff --git a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp index 48ed771306..8b18e2de4c 100644 --- a/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp +++ b/samples/Cpp/TestCpp/Classes/TileMapTest/TileMapTest.cpp @@ -1432,7 +1432,7 @@ TileDemo::TileDemo(void) { auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(TileDemo::onTouchesMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } TileDemo::~TileDemo(void) diff --git a/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp b/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp index e168d7a1bc..0919b771eb 100644 --- a/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp +++ b/samples/Cpp/TestCpp/Classes/TouchesTest/Paddle.cpp @@ -45,7 +45,7 @@ void Paddle::onEnter() listener->onTouchMoved = CC_CALLBACK_2(Paddle::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(Paddle::onTouchEnded, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } void Paddle::onExit() diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index fcd140e4f3..32051bbd1b 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -129,7 +129,7 @@ TestController::TestController() listener->onTouchBegan = CC_CALLBACK_2(TestController::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(TestController::onTouchMoved, this); - EventDispatcher::getInstance()->addEventListenerWithSceneGraphPriority(listener, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); } TestController::~TestController() From 0622434321b4b3620f6242ca35b77ef028f30614 Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 28 Oct 2013 10:49:21 +0800 Subject: [PATCH 050/144] issue #3069: Using `std::string` to initialize `EventCustom`. It will be easier for editor parser to emit callback event. --- cocos/2d/CCEventCustom.cpp | 7 ++++--- cocos/2d/CCEventCustom.h | 2 +- cocos/2d/CCEventListenerCustom.cpp | 6 +++--- cocos/2d/CCEventListenerCustom.h | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/cocos/2d/CCEventCustom.cpp b/cocos/2d/CCEventCustom.cpp index 89e56a3a69..8960b9fd87 100644 --- a/cocos/2d/CCEventCustom.cpp +++ b/cocos/2d/CCEventCustom.cpp @@ -24,14 +24,15 @@ #include "CCEventCustom.h" #include "ccMacros.h" +#include NS_CC_BEGIN -EventCustom::EventCustom(Type type) -: Event(type) +EventCustom::EventCustom(const std::string& eventName) +: Event(std::hash()(eventName)) , _userData(nullptr) { - CCASSERT(type >= TYPE_CUSTOM, "custom type should be greater than TYPE_CUSTOM."); +// CCASSERT(type >= TYPE_CUSTOM, "custom type should be greater than TYPE_CUSTOM."); } NS_CC_END diff --git a/cocos/2d/CCEventCustom.h b/cocos/2d/CCEventCustom.h index 96676cdbfd..c4521e3bbf 100644 --- a/cocos/2d/CCEventCustom.h +++ b/cocos/2d/CCEventCustom.h @@ -33,7 +33,7 @@ class EventCustom : public Event { public: /** Constructor */ - EventCustom(Type type); + EventCustom(const std::string& eventName); /** Set user data */ inline void setUserData(void* data) { _userData = data; }; diff --git a/cocos/2d/CCEventListenerCustom.cpp b/cocos/2d/CCEventListenerCustom.cpp index 3875f61c94..048fede198 100644 --- a/cocos/2d/CCEventListenerCustom.cpp +++ b/cocos/2d/CCEventListenerCustom.cpp @@ -32,10 +32,10 @@ EventListenerCustom::EventListenerCustom() { } -EventListenerCustom* EventListenerCustom::create(Type type, std::function callback) +EventListenerCustom* EventListenerCustom::create(const std::string& eventName, std::function callback) { EventListenerCustom* ret = new EventListenerCustom(); - if (ret && ret->init(type, callback)) + if (ret && ret->init(std::hash()(eventName), callback)) { ret->autorelease(); } @@ -46,7 +46,7 @@ EventListenerCustom* EventListenerCustom::create(Type type, std::functioncallback) +bool EventListenerCustom::init(Type type, std::functioncallback) { bool ret = false; diff --git a/cocos/2d/CCEventListenerCustom.h b/cocos/2d/CCEventListenerCustom.h index 285d257cd3..0bd5bec700 100644 --- a/cocos/2d/CCEventListenerCustom.h +++ b/cocos/2d/CCEventListenerCustom.h @@ -56,7 +56,7 @@ public: * @param eventType The type of the event. * @param callback The callback function when the specified event was emitted. */ - static EventListenerCustom* create(int type, std::function callback); + static EventListenerCustom* create(const std::string& eventName, std::function callback); /// Overrides virtual bool checkAvailable() override; @@ -67,7 +67,7 @@ protected: EventListenerCustom(); /** Initializes event with type and callback function */ - bool init(int type, std::function callback); + bool init(Type type, std::function callback); std::function _onCustomEvent; }; From e6b0134080d5fe64f22d384259a2cc2f1b9b2947 Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 28 Oct 2013 10:49:43 +0800 Subject: [PATCH 051/144] issue #3069: Updating Custom event test. --- .../NewEventDispatcherTest.cpp | 45 +++++++++++++++---- .../NewEventDispatcherTest.h | 1 + 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index aa45afa24d..1e7c746a56 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -414,33 +414,61 @@ void CustomEventTest::onEnter() Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); - auto statusLabel = LabelTTF::create("No custom event received!", "", 20); + MenuItemFont::setFontSize(20); + + auto statusLabel = LabelTTF::create("No custom event 1 received!", "", 20); statusLabel->setPosition(origin + Point(size.width/2, size.height-90)); addChild(statusLabel); - const int game_custom_event = EventListener::TYPE_CUSTOM + 1; - _listener = EventListenerCustom::create(game_custom_event, [=](EventCustom* event){ - std::string str("Custom event received, "); + _listener = EventListenerCustom::create("game_custom_event1", [=](EventCustom* event){ + std::string str("Custom event 1 received, "); char* buf = static_cast(event->getUserData()); str += buf; str += " times"; statusLabel->setString(str.c_str()); - delete[] buf; }); _eventDispatcher->addEventListenerWithFixedPriority(_listener, 1); - auto sendItem = MenuItemFont::create("Send Custom Event", [=](Object* sender){ + auto sendItem = MenuItemFont::create("Send Custom Event 1", [=](Object* sender){ static int count = 0; ++count; char* buf = new char[10]; sprintf(buf, "%d", count); - EventCustom event(game_custom_event); + EventCustom event("game_custom_event1"); event.setUserData(buf); _eventDispatcher->dispatchEvent(&event); + CC_SAFE_DELETE_ARRAY(buf); }); sendItem->setPosition(origin + Point(size.width/2, size.height/2)); - auto menu = Menu::create(sendItem, nullptr); + + auto statusLabel2 = LabelTTF::create("No custom event 2 received!", "", 20); + statusLabel2->setPosition(origin + Point(size.width/2, size.height-120)); + addChild(statusLabel2); + + _listener2 = EventListenerCustom::create("game_custom_event2", [=](EventCustom* event){ + std::string str("Custom event 2 received, "); + char* buf = static_cast(event->getUserData()); + str += buf; + str += " times"; + statusLabel2->setString(str.c_str()); + }); + + _eventDispatcher->addEventListenerWithFixedPriority(_listener2, 1); + + auto sendItem2 = MenuItemFont::create("Send Custom Event 2", [=](Object* sender){ + static int count = 0; + ++count; + char* buf = new char[10]; + sprintf(buf, "%d", count); + EventCustom event("game_custom_event2"); + event.setUserData(buf); + _eventDispatcher->dispatchEvent(&event); + CC_SAFE_DELETE_ARRAY(buf); + }); + sendItem2->setPosition(origin + Point(size.width/2, size.height/2 - 40)); + + auto menu = Menu::create(sendItem, sendItem2, nullptr); menu->setPosition(Point(0, 0)); menu->setAnchorPoint(Point(0, 0)); addChild(menu, -1); @@ -449,6 +477,7 @@ void CustomEventTest::onEnter() void CustomEventTest::onExit() { _eventDispatcher->removeEventListener(_listener); + _eventDispatcher->removeEventListener(_listener2); EventDispatcherTestDemo::onExit(); } diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index 9af7022bde..080e623008 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -64,6 +64,7 @@ public: virtual std::string subtitle() override; private: EventListenerCustom* _listener; + EventListenerCustom* _listener2; }; class LabelKeyboardEventTest : public EventDispatcherTestDemo From 8d11f484a96cee937761254617b61bea2dccabfc Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 28 Oct 2013 10:52:23 +0800 Subject: [PATCH 052/144] issue #3069: Removing unused comments. --- cocos/2d/CCEventCustom.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cocos/2d/CCEventCustom.cpp b/cocos/2d/CCEventCustom.cpp index 8960b9fd87..29d8afc551 100644 --- a/cocos/2d/CCEventCustom.cpp +++ b/cocos/2d/CCEventCustom.cpp @@ -32,7 +32,6 @@ EventCustom::EventCustom(const std::string& eventName) : Event(std::hash()(eventName)) , _userData(nullptr) { -// CCASSERT(type >= TYPE_CUSTOM, "custom type should be greater than TYPE_CUSTOM."); } NS_CC_END From 8b7d1934c81ac1c59ae46c5a3db91f0d3384d9f7 Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 28 Oct 2013 16:00:01 +0800 Subject: [PATCH 053/144] issue #3069: Using enum class for define Event type and EventListener type. --- cocos/2d/CCEvent.h | 12 +- cocos/2d/CCEventAcceleration.cpp | 2 +- cocos/2d/CCEventCustom.cpp | 3 +- cocos/2d/CCEventCustom.h | 7 +- cocos/2d/CCEventDispatcher.cpp | 190 ++++++++++++++--------- cocos/2d/CCEventDispatcher.h | 22 +-- cocos/2d/CCEventKeyboard.cpp | 5 + cocos/2d/CCEventKeyboard.h | 8 +- cocos/2d/CCEventListener.cpp | 3 +- cocos/2d/CCEventListener.h | 42 +++-- cocos/2d/CCEventListenerAcceleration.cpp | 2 +- cocos/2d/CCEventListenerAcceleration.h | 2 + cocos/2d/CCEventListenerCustom.cpp | 6 +- cocos/2d/CCEventListenerCustom.h | 2 +- cocos/2d/CCEventListenerKeyboard.cpp | 2 +- cocos/2d/CCEventListenerKeyboard.h | 2 + cocos/2d/CCEventListenerTouch.cpp | 4 +- cocos/2d/CCEventListenerTouch.h | 4 + cocos/2d/CCEventTouch.cpp | 5 + cocos/2d/CCEventTouch.h | 6 +- 20 files changed, 197 insertions(+), 132 deletions(-) diff --git a/cocos/2d/CCEvent.h b/cocos/2d/CCEvent.h index eecd7f396c..cd2be49adb 100644 --- a/cocos/2d/CCEvent.h +++ b/cocos/2d/CCEvent.h @@ -41,15 +41,14 @@ class Node; class Event { public: - enum EventType + enum class Type { - TYPE_TOUCH = 1, - TYPE_KEYBOARD = 3, - TYPE_ACCELERATION, - TYPE_CUSTOM + TOUCH, + KEYBOARD, + ACCELERATION, + CUSTOM }; - typedef int Type; protected: /** Constructor */ Event(Type type); @@ -78,6 +77,7 @@ protected: inline void setCurrentTarget(Node* target) { _currentTarget = target; }; Type _type; ///< Event type + bool _isStopped; ///< whether the event has been stopped. Node* _currentTarget; ///< Current target diff --git a/cocos/2d/CCEventAcceleration.cpp b/cocos/2d/CCEventAcceleration.cpp index 7039c03ff8..1a8a075d88 100644 --- a/cocos/2d/CCEventAcceleration.cpp +++ b/cocos/2d/CCEventAcceleration.cpp @@ -27,7 +27,7 @@ NS_CC_BEGIN EventAcceleration::EventAcceleration(Acceleration acc) -: Event(TYPE_ACCELERATION) +: Event(Type::ACCELERATION) , _acc(acc) { } diff --git a/cocos/2d/CCEventCustom.cpp b/cocos/2d/CCEventCustom.cpp index 29d8afc551..65e9d4c2f5 100644 --- a/cocos/2d/CCEventCustom.cpp +++ b/cocos/2d/CCEventCustom.cpp @@ -29,8 +29,9 @@ NS_CC_BEGIN EventCustom::EventCustom(const std::string& eventName) -: Event(std::hash()(eventName)) +: Event(Type::CUSTOM) , _userData(nullptr) +, _eventName(eventName) { } diff --git a/cocos/2d/CCEventCustom.h b/cocos/2d/CCEventCustom.h index c4521e3bbf..4a7d750940 100644 --- a/cocos/2d/CCEventCustom.h +++ b/cocos/2d/CCEventCustom.h @@ -35,14 +35,17 @@ public: /** Constructor */ EventCustom(const std::string& eventName); - /** Set user data */ + /** Sets user data */ inline void setUserData(void* data) { _userData = data; }; - /** Get user data */ + /** Gets user data */ inline void* getUserData() const { return _userData; }; + /** Gets event name */ + inline const std::string& getEventName() const { return _eventName; }; protected: void* _userData; ///< User data + std::string _eventName; }; NS_CC_END diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index e0922b0796..1ebadf9b74 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -24,6 +24,7 @@ #include "CCEventDispatcher.h" #include "CCEvent.h" #include "CCEventTouch.h" +#include "CCEventCustom.h" #include "CCEventListenerTouch.h" #include "CCNode.h" #include "CCDirector.h" @@ -58,6 +59,37 @@ private: NS_CC_BEGIN +static EventListener::ListenerID getListenerID(Event* event) +{ + EventListener::ListenerID ret; + switch (event->getType()) + { + case Event::Type::ACCELERATION: + ret = static_cast(EventListener::Type::ACCELERATION); + break; + case Event::Type::CUSTOM: + { + auto customEvent = static_cast(event); + auto listenerID = std::hash()(customEvent->getEventName()); + ret = static_cast(listenerID); + } + break; + case Event::Type::KEYBOARD: + ret = static_cast(EventListener::Type::KEYBOARD); + break; + case Event::Type::TOUCH: + // Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce. + // return UNKNOW instead. + ret = static_cast(EventListener::Type::UNKNOWN); + break; + default: + CCASSERT(false, "Invalid type!"); + break; + } + + return ret; +} + EventDispatcher::EventListenerVector::EventListenerVector() : _sceneGraphListeners(nullptr) , _fixedListeners(nullptr) @@ -90,7 +122,7 @@ bool EventDispatcher::EventListenerVector::empty() const void EventDispatcher::EventListenerVector::push_back(EventListener* listener) { - if (listener->_fixedPriority == 0) + if (listener->getFixedPriority() == 0) { if (_sceneGraphListeners == nullptr) { @@ -196,7 +228,7 @@ void EventDispatcher::pauseTarget(Node* node) auto listeners = listenerIter->second; for (auto& l : *listeners) { - l->_paused = true; + l->setPaused(true); } } } @@ -209,7 +241,7 @@ void EventDispatcher::resumeTarget(Node* node) auto listeners = listenerIter->second; for (auto& l : *listeners) { - l->_paused = false; + l->setPaused(false); } } setDirtyForNode(node); @@ -274,11 +306,11 @@ void EventDispatcher::addEventListener(EventListener* listener) { EventListenerVector* listenerList = nullptr; - auto iter = _listeners.find(listener->_type); + auto iter = _listeners.find(listener->getListenerID()); if (iter == _listeners.end()) { listenerList = new EventListenerVector(); - _listeners.insert(std::make_pair(listener->_type, listenerList)); + _listeners.insert(std::make_pair(listener->getListenerID(), listenerList)); } else { @@ -287,13 +319,13 @@ void EventDispatcher::addEventListener(EventListener* listener) listenerList->push_back(listener); - if (listener->_fixedPriority == 0) + if (listener->getFixedPriority() == 0) { - setDirty(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + setDirty(listener->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY); } else { - setDirty(listener->_type, DirtyFlag::FIXED_PRITORY); + setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRITORY); } } else @@ -305,17 +337,16 @@ void EventDispatcher::addEventListener(EventListener* listener) void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node) { CCASSERT(listener && node, "Invalid parameters."); - CCASSERT(!listener->_isRegistered, "The listener has been registered."); + CCASSERT(!listener->isRegistered(), "The listener has been registered."); if (!listener->checkAvailable()) return; - listener->_node = node; - listener->_fixedPriority = 0; - + listener->setSceneGraphPriority(node); + listener->setFixedPriority(0); + listener->setRegistered(true); + listener->retain(); - listener->_isRegistered = true; - addEventListener(listener); associateNodeAndEventListener(node, listener); @@ -329,17 +360,18 @@ void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* list void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority) { CCASSERT(listener, "Invalid parameters."); - CCASSERT(!listener->_isRegistered, "The listener has been registered."); + CCASSERT(!listener->isRegistered(), "The listener has been registered."); CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority."); if (!listener->checkAvailable()) return; - listener->_node = nullptr; - listener->_fixedPriority = fixedPriority; + listener->setSceneGraphPriority(nullptr); + listener->setFixedPriority(fixedPriority); + listener->setRegistered(true); + listener->setPaused(false); + listener->retain(); - listener->_isRegistered = true; - listener->_paused = false; addEventListener(listener); } @@ -361,10 +393,10 @@ void EventDispatcher::removeEventListener(EventListener* listener) if (l == listener) { CC_SAFE_RETAIN(l); - l->_isRegistered = false; - if (l->_node != nullptr) + l->setRegistered(false); + if (l->getSceneGraphPriority() != nullptr) { - dissociateNodeAndEventListener(l->_node, l); + dissociateNodeAndEventListener(l->getSceneGraphPriority(), l); } if (_inDispatch == 0) @@ -393,7 +425,7 @@ void EventDispatcher::removeEventListener(EventListener* listener) if (iter->second->empty()) { - _priorityDirtyFlagMap.erase(listener->_type); + _priorityDirtyFlagMap.erase(listener->getListenerID()); auto list = iter->second; iter = _listeners.erase(iter); CC_SAFE_DELETE(list); @@ -426,12 +458,12 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority) auto found = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener); if (found != fixedPriorityListeners->end()) { - CCASSERT(listener->_node == nullptr, "Can't set fixed priority with scene graph based listener."); + CCASSERT(listener->getSceneGraphPriority() == nullptr, "Can't set fixed priority with scene graph based listener."); - if (listener->_fixedPriority != fixedPriority) + if (listener->getFixedPriority() != fixedPriority) { - listener->_fixedPriority = fixedPriority; - setDirty(listener->_type, DirtyFlag::FIXED_PRITORY); + listener->setFixedPriority(fixedPriority); + setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRITORY); } return; } @@ -505,21 +537,23 @@ void EventDispatcher::dispatchEvent(Event* event) DispatchGuard guard(_inDispatch); - if (event->getType() == Event::TYPE_TOUCH) + if (event->getType() == Event::Type::TOUCH) { dispatchTouchEvent(static_cast(event)); return; } - sortEventListeners(event->getType()); + auto listenerID = getListenerID(event); - auto iter = _listeners.find(event->getType()); + sortEventListeners(listenerID); + + auto iter = _listeners.find(listenerID); if (iter != _listeners.end()) { auto listeners = iter->second; auto onEvent = [&event](EventListener* listener) -> bool{ - event->setCurrentTarget(listener->_node); + event->setCurrentTarget(listener->getSceneGraphPriority()); listener->_onEvent(event); return event->isStopped(); }; @@ -527,16 +561,19 @@ void EventDispatcher::dispatchEvent(Event* event) dispatchEventToListeners(listeners, onEvent); } - updateListeners(event->getType()); + updateListeners(event); } void EventDispatcher::dispatchTouchEvent(EventTouch* event) { - sortEventListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); - sortEventListeners(EventListener::TYPE_TOUCH_ALL_AT_ONCE); + auto touchOneByOneID = static_cast(EventListener::Type::TOUCH_ONE_BY_ONE); + auto touchAllAtOnceID = static_cast(EventListener::Type::TOUCH_ALL_AT_ONCE); - auto oneByOnelisteners = getListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); - auto allAtOncelisteners = getListeners(EventListener::TYPE_TOUCH_ALL_AT_ONCE); + sortEventListeners(touchOneByOneID); + sortEventListeners(touchAllAtOnceID); + + auto oneByOnelisteners = getListeners(touchOneByOneID); + auto allAtOncelisteners = getListeners(touchAllAtOnceID); // If there aren't any touch listeners, return directly. if (nullptr == oneByOnelisteners && nullptr == allAtOncelisteners) @@ -627,7 +664,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // If the event was stopped, return directly. if (event->isStopped()) { - updateListeners(event->getType()); + updateListeners(event); return true; } @@ -706,7 +743,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) // If the event was stopped, return directly. if (event->isStopped()) { - updateListeners(event->getType()); + updateListeners(event); return false; } @@ -720,14 +757,14 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) } } - updateListeners(event->getType()); + updateListeners(event); } -void EventDispatcher::updateListeners(Event::Type eventType) +void EventDispatcher::updateListeners(Event* event) { - auto onUpdateListeners = [this](EventListener::Type listenerType) + auto onUpdateListeners = [this](EventListener::ListenerID listenerID) { - auto listenersIter = _listeners.find(listenerType); + auto listenersIter = _listeners.find(listenerID); if (listenersIter == _listeners.end()) return; @@ -740,7 +777,7 @@ void EventDispatcher::updateListeners(Event::Type eventType) for (auto iter = sceneGraphPriorityListeners->begin(); iter != sceneGraphPriorityListeners->end();) { auto l = *iter; - if (!l->_isRegistered) + if (!l->isRegistered()) { iter = sceneGraphPriorityListeners->erase(iter); l->release(); @@ -757,7 +794,7 @@ void EventDispatcher::updateListeners(Event::Type eventType) for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();) { auto l = *iter; - if (!l->_isRegistered) + if (!l->isRegistered()) { iter = fixedPriorityListeners->erase(iter); l->release(); @@ -791,14 +828,14 @@ void EventDispatcher::updateListeners(Event::Type eventType) } }; - if (eventType == Event::TYPE_TOUCH) + if (event->getType() == Event::Type::TOUCH) { - onUpdateListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); - onUpdateListeners(EventListener::TYPE_TOUCH_ALL_AT_ONCE); + onUpdateListeners(static_cast(EventListener::Type::TOUCH_ONE_BY_ONE)); + onUpdateListeners(static_cast(EventListener::Type::TOUCH_ALL_AT_ONCE)); } else { - onUpdateListeners(eventType); + onUpdateListeners(getListenerID(event)); } @@ -808,12 +845,13 @@ void EventDispatcher::updateListeners(Event::Type eventType) for (auto& listener : _toAddedListeners) { - auto itr = _listeners.find(listener->_type); + EventListener::ListenerID listenerID = listener->getListenerID(); + auto itr = _listeners.find(listenerID); if (itr == _listeners.end()) { listeners = new EventListenerVector(); - _listeners.insert(std::make_pair(listener->_type, listeners)); + _listeners.insert(std::make_pair(listenerID, listeners)); } else { @@ -822,13 +860,13 @@ void EventDispatcher::updateListeners(Event::Type eventType) listeners->push_back(listener); - if (listener->_fixedPriority == 0) + if (listener->getFixedPriority() == 0) { - setDirty(listener->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY); } else { - setDirty(listener->_type, DirtyFlag::FIXED_PRITORY); + setDirty(listenerID, DirtyFlag::FIXED_PRITORY); } } _toAddedListeners.clear(); @@ -846,7 +884,7 @@ void EventDispatcher::updateDirtyFlagForSceneGraph() { for (auto& l : *iter->second) { - setDirty(l->_type, DirtyFlag::SCENE_GRAPH_PRIORITY); + setDirty(l->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY); } } } @@ -855,11 +893,11 @@ void EventDispatcher::updateDirtyFlagForSceneGraph() } } -void EventDispatcher::sortEventListeners(EventListener::Type eventListenerType) +void EventDispatcher::sortEventListeners(EventListener::ListenerID listenerID) { DirtyFlag dirtyFlag = DirtyFlag::NONE; - auto dirtyIter = _priorityDirtyFlagMap.find(eventListenerType); + auto dirtyIter = _priorityDirtyFlagMap.find(listenerID); if (dirtyIter != _priorityDirtyFlagMap.end()) { dirtyFlag = dirtyIter->second; @@ -869,21 +907,21 @@ void EventDispatcher::sortEventListeners(EventListener::Type eventListenerType) { if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRITORY) { - sortEventListenersOfFixedPriority(eventListenerType); + sortEventListenersOfFixedPriority(listenerID); } if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY) { - sortEventListenersOfSceneGraphPriority(eventListenerType); + sortEventListenersOfSceneGraphPriority(listenerID); } dirtyIter->second = DirtyFlag::NONE; } } -void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::Type eventListenerType) +void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::ListenerID listenerID) { - auto listeners = getListeners(eventListenerType); + auto listeners = getListeners(listenerID); if (listeners == nullptr) return; @@ -898,7 +936,7 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::Type // After sort: priority < 0, > 0 auto sceneGraphlisteners = listeners->getSceneGraphPriorityListeners(); std::sort(sceneGraphlisteners->begin(), sceneGraphlisteners->end(), [this](const EventListener* l1, const EventListener* l2) { - return _nodePriorityMap[l1->_node] > _nodePriorityMap[l2->_node]; + return _nodePriorityMap[l1->getSceneGraphPriority()] > _nodePriorityMap[l2->getSceneGraphPriority()]; }); #if DUMP_LISTENER_ITEM_PRIORITY_INFO @@ -910,9 +948,9 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::Type #endif } -void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::Type eventListenerType) +void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::ListenerID listenerID) { - auto listeners = getListeners(eventListenerType); + auto listeners = getListeners(listenerID); if (listeners == nullptr) return; @@ -920,14 +958,14 @@ void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::Type even // After sort: priority < 0, > 0 auto fixedlisteners = listeners->getFixedPriorityListeners(); std::sort(fixedlisteners->begin(), fixedlisteners->end(), [](const EventListener* l1, const EventListener* l2) { - return l1->_fixedPriority < l2->_fixedPriority; + return l1->getFixedPriority() < l2->getFixedPriority(); }); // FIXME: Should use binary search int index = 0; for (auto& listener : *fixedlisteners) { - if (listener->_fixedPriority >= 0) + if (listener->getFixedPriority() >= 0) break; ++index; } @@ -944,9 +982,9 @@ void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::Type even } -EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListener::Type eventListenerType) +EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListener::ListenerID listenerID) { - auto iter = _listeners.find(eventListenerType); + auto iter = _listeners.find(listenerID); if (iter != _listeners.end()) { return iter->second; @@ -955,9 +993,9 @@ EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListene return nullptr; } -void EventDispatcher::removeEventListeners(EventListener::Type eventListenerType) +void EventDispatcher::removeEventListeners(EventListener::ListenerID listenerID) { - auto listenerItemIter = _listeners.find(eventListenerType); + auto listenerItemIter = _listeners.find(listenerID); if (listenerItemIter != _listeners.end()) { auto listeners = listenerItemIter->second; @@ -971,10 +1009,10 @@ void EventDispatcher::removeEventListeners(EventListener::Type eventListenerType for (auto iter = listenerVector->begin(); iter != listenerVector->end();) { auto l = *iter; - l->_isRegistered = false; - if (l->_node != nullptr) + l->setRegistered(false); + if (l->getSceneGraphPriority() != nullptr) { - dissociateNodeAndEventListener(l->_node, l); + dissociateNodeAndEventListener(l->getSceneGraphPriority(), l); } if (_inDispatch == 0) @@ -997,7 +1035,7 @@ void EventDispatcher::removeEventListeners(EventListener::Type eventListenerType listeners->clear(); delete listeners; _listeners.erase(listenerItemIter); - _priorityDirtyFlagMap.erase(eventListenerType); + _priorityDirtyFlagMap.erase(listenerID); } } } @@ -1042,12 +1080,12 @@ void EventDispatcher::setDirtyForNode(Node* node) } } -void EventDispatcher::setDirty(EventListener::Type eventListenerType, DirtyFlag flag) +void EventDispatcher::setDirty(EventListener::ListenerID listenerID, DirtyFlag flag) { - auto iter = _priorityDirtyFlagMap.find(eventListenerType); + auto iter = _priorityDirtyFlagMap.find(listenerID); if (iter == _priorityDirtyFlagMap.end()) { - _priorityDirtyFlagMap.insert(std::make_pair(eventListenerType, flag)); + _priorityDirtyFlagMap.insert(std::make_pair(listenerID, flag)); } else { diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index e3650a1fae..3609c7a591 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -74,8 +74,8 @@ public: */ void removeEventListener(EventListener* listener); - /** Removes all listeners with the same event listener type */ - void removeEventListeners(EventListener::Type eventListenerType); + /** Removes all listeners with the same event listener ID */ + void removeEventListeners(EventListener::ListenerID listenerID); /** Removes all listeners */ void removeAllEventListeners(); @@ -144,25 +144,25 @@ private: void addEventListener(EventListener* listener); /** Gets event the listener list for the event listener type. */ - EventListenerVector* getListeners(EventListener::Type eventListenerType); + EventListenerVector* getListeners(EventListener::ListenerID listenerID); /** Update dirty flag */ void updateDirtyFlagForSceneGraph(); /** Sort event listener */ - void sortEventListeners(EventListener::Type eventListenerType); + void sortEventListeners(EventListener::ListenerID listenerID); /** Sorts the listeners of specified type by scene graph priority */ - void sortEventListenersOfSceneGraphPriority(EventListener::Type eventListenerType); + void sortEventListenersOfSceneGraphPriority(EventListener::ListenerID listenerID); /** Sorts the listeners of specified type by fixed priority */ - void sortEventListenersOfFixedPriority(EventListener::Type eventListenerType); + void sortEventListenersOfFixedPriority(EventListener::ListenerID listenerID); /** Updates all listeners * 1) Removes all listener items that have been marked as 'removed' when dispatching event. * 2) Adds all listener items that have been marked as 'added' when dispatching event. */ - void updateListeners(Event::Type eventType); + void updateListeners(Event* event); /** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */ void dispatchTouchEvent(EventTouch* event); @@ -185,18 +185,18 @@ private: ALL = FIXED_PRITORY | SCENE_GRAPH_PRIORITY }; - /** Sets the dirty flag for a specified listener type */ - void setDirty(EventListener::Type listenerType, DirtyFlag flag); + /** Sets the dirty flag for a specified listener ID */ + void setDirty(EventListener::ListenerID listenerID, DirtyFlag flag); /** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */ void visitTarget(Node* node); private: /** Listeners map */ - std::unordered_map _listeners; + std::unordered_map _listeners; /** The map of dirty flag */ - std::unordered_map _priorityDirtyFlagMap; + std::unordered_map _priorityDirtyFlagMap; /** The map of node and event listeners */ std::unordered_map*> _nodeListenersMap; diff --git a/cocos/2d/CCEventKeyboard.cpp b/cocos/2d/CCEventKeyboard.cpp index b02312fce1..83bf0a8d0a 100644 --- a/cocos/2d/CCEventKeyboard.cpp +++ b/cocos/2d/CCEventKeyboard.cpp @@ -27,5 +27,10 @@ NS_CC_BEGIN +EventKeyboard::EventKeyboard(KeyCode keyCode, bool isPressed) +: Event(Type::KEYBOARD) +, _keyCode(keyCode) +, _isPressed(isPressed) +{} NS_CC_END diff --git a/cocos/2d/CCEventKeyboard.h b/cocos/2d/CCEventKeyboard.h index b8cf7f8976..e0533e62fd 100644 --- a/cocos/2d/CCEventKeyboard.h +++ b/cocos/2d/CCEventKeyboard.h @@ -196,13 +196,7 @@ public: KEY_SEARCH = 0xFFAA }; - static const char* EVENT_TYPE; - - EventKeyboard(KeyCode keyCode, bool isPressed) - : Event(TYPE_KEYBOARD) - , _keyCode(keyCode) - , _isPressed(isPressed) - {}; + EventKeyboard(KeyCode keyCode, bool isPressed); private: KeyCode _keyCode; diff --git a/cocos/2d/CCEventListener.cpp b/cocos/2d/CCEventListener.cpp index 9040593e0e..b4f9fdd499 100644 --- a/cocos/2d/CCEventListener.cpp +++ b/cocos/2d/CCEventListener.cpp @@ -35,10 +35,11 @@ EventListener::~EventListener() CCLOGINFO("In the destructor of EventListener. %p", this); } -bool EventListener::init(Type t, std::function callback) +bool EventListener::init(Type t, ListenerID listenerID, std::function callback) { _onEvent = callback; _type = t; + _listenerID = listenerID; _isRegistered = false; _paused = true; diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index bcedcec0c8..bbf5121149 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -46,22 +46,24 @@ class Node; class EventListener : public Object { public: - enum EventListenerType + enum class Type { - TYPE_TOUCH_ONE_BY_ONE = 1, - TYPE_TOUCH_ALL_AT_ONCE, - TYPE_KEYBOARD, - TYPE_ACCELERATION, - TYPE_CUSTOM + UNKNOWN, + TOUCH_ONE_BY_ONE, + TOUCH_ALL_AT_ONCE, + KEYBOARD, + ACCELERATION, + CUSTOM }; - typedef int Type; + typedef int ListenerID; + protected: /** Constructor */ EventListener(); /** Initializes event with type and callback function */ - bool init(Type t, std::functioncallback); + bool init(Type t, ListenerID listenerID, std::functioncallback); public: /** Destructor */ virtual ~EventListener(); @@ -72,21 +74,33 @@ public: /** Clones the listener, its subclasses have to override this method. */ virtual EventListener* clone() = 0; + inline void setPaused(bool paused) { _paused = paused; }; inline bool isPaused() const { return _paused; }; + + inline void setRegistered(bool registered) { _isRegistered = registered; }; inline bool isRegistered() const { return _isRegistered; }; -protected: + inline Type getType() const { return _type; }; + inline ListenerID getListenerID() const { return _listenerID; }; + + inline void setFixedPriority(int fixedPriority) { _fixedPriority = fixedPriority; }; + inline int getFixedPriority() const { return _fixedPriority; }; + + inline void setSceneGraphPriority(Node* node) { _node = node; }; + inline Node* getSceneGraphPriority() const { return _node; }; + std::function _onEvent; /// Event callback function - Type _type; /// Event type - bool _isRegistered; /// Whether the listener has been added to dispatcher. + +protected: + + Type _type; /// Event listener type + ListenerID _listenerID; /// Event listener ID + bool _isRegistered; /// Whether the listener has been added to dispatcher. // The priority of event listener int _fixedPriority; // The higher the number, the higher the priority, 0 is for scene graph base priority. Node* _node; // scene graph based priority bool _paused; - -private: - friend class EventDispatcher; }; NS_CC_END diff --git a/cocos/2d/CCEventListenerAcceleration.cpp b/cocos/2d/CCEventListenerAcceleration.cpp index d1d5d22206..258af5929e 100644 --- a/cocos/2d/CCEventListenerAcceleration.cpp +++ b/cocos/2d/CCEventListenerAcceleration.cpp @@ -59,7 +59,7 @@ bool EventListenerAcceleration::init(std::functiononAccelerationEvent(&accEvent->_acc, event); }; - if (EventListener::init(TYPE_ACCELERATION, listener)) + if (EventListener::init(Type::ACCELERATION, static_cast(Type::ACCELERATION), listener)) { onAccelerationEvent = callback; return true; diff --git a/cocos/2d/CCEventListenerAcceleration.h b/cocos/2d/CCEventListenerAcceleration.h index 59ce3d8439..213bac646e 100644 --- a/cocos/2d/CCEventListenerAcceleration.h +++ b/cocos/2d/CCEventListenerAcceleration.h @@ -33,6 +33,8 @@ NS_CC_BEGIN class EventListenerAcceleration : public EventListener { public: + static const ListenerID ID = static_cast(Type::ACCELERATION); + static EventListenerAcceleration* create(std::function callback); virtual ~EventListenerAcceleration(); diff --git a/cocos/2d/CCEventListenerCustom.cpp b/cocos/2d/CCEventListenerCustom.cpp index 048fede198..09e657a9fc 100644 --- a/cocos/2d/CCEventListenerCustom.cpp +++ b/cocos/2d/CCEventListenerCustom.cpp @@ -46,7 +46,7 @@ EventListenerCustom* EventListenerCustom::create(const std::string& eventName, s return ret; } -bool EventListenerCustom::init(Type type, std::functioncallback) +bool EventListenerCustom::init(ListenerID listenerId, std::functioncallback) { bool ret = false; @@ -59,7 +59,7 @@ bool EventListenerCustom::init(Type type, std::functioncallb } }; - if (EventListener::init(type, listener)) + if (EventListener::init(EventListener::Type::CUSTOM, listenerId, listener)) { ret = true; } @@ -69,7 +69,7 @@ bool EventListenerCustom::init(Type type, std::functioncallb EventListenerCustom* EventListenerCustom::clone() { EventListenerCustom* ret = new EventListenerCustom(); - if (ret && ret->init(_type, _onCustomEvent)) + if (ret && ret->init(_listenerID, _onCustomEvent)) { ret->autorelease(); } diff --git a/cocos/2d/CCEventListenerCustom.h b/cocos/2d/CCEventListenerCustom.h index 0bd5bec700..eb7e875165 100644 --- a/cocos/2d/CCEventListenerCustom.h +++ b/cocos/2d/CCEventListenerCustom.h @@ -67,7 +67,7 @@ protected: EventListenerCustom(); /** Initializes event with type and callback function */ - bool init(Type type, std::function callback); + bool init(ListenerID listenerId, std::function callback); std::function _onCustomEvent; }; diff --git a/cocos/2d/CCEventListenerKeyboard.cpp b/cocos/2d/CCEventListenerKeyboard.cpp index fb733ed442..c947a43e36 100644 --- a/cocos/2d/CCEventListenerKeyboard.cpp +++ b/cocos/2d/CCEventListenerKeyboard.cpp @@ -88,7 +88,7 @@ bool EventListenerKeyboard::init() } }; - if (EventListener::init(TYPE_KEYBOARD, listener)) + if (EventListener::init(Type::KEYBOARD, static_cast(Type::KEYBOARD), listener)) { return true; } diff --git a/cocos/2d/CCEventListenerKeyboard.h b/cocos/2d/CCEventListenerKeyboard.h index c34d2add0d..6c59f69121 100644 --- a/cocos/2d/CCEventListenerKeyboard.h +++ b/cocos/2d/CCEventListenerKeyboard.h @@ -36,6 +36,8 @@ class Event; class EventListenerKeyboard : public EventListener { public: + static const ListenerID ID = static_cast(Type::KEYBOARD); + static EventListenerKeyboard* create(); /// Overrides diff --git a/cocos/2d/CCEventListenerTouch.cpp b/cocos/2d/CCEventListenerTouch.cpp index e753a113d0..1367645452 100644 --- a/cocos/2d/CCEventListenerTouch.cpp +++ b/cocos/2d/CCEventListenerTouch.cpp @@ -46,7 +46,7 @@ EventListenerTouchOneByOne::~EventListenerTouchOneByOne() bool EventListenerTouchOneByOne::init() { - if (EventListener::init(TYPE_TOUCH_ONE_BY_ONE, nullptr)) + if (EventListener::init(Type::TOUCH_ONE_BY_ONE, static_cast(Type::TOUCH_ONE_BY_ONE), nullptr)) { return true; } @@ -123,7 +123,7 @@ EventListenerTouchAllAtOnce::~EventListenerTouchAllAtOnce() bool EventListenerTouchAllAtOnce::init() { - if (EventListener::init(TYPE_TOUCH_ALL_AT_ONCE, nullptr)) + if (EventListener::init(Type::TOUCH_ALL_AT_ONCE, static_cast(Type::TOUCH_ALL_AT_ONCE), nullptr)) { return true; } diff --git a/cocos/2d/CCEventListenerTouch.h b/cocos/2d/CCEventListenerTouch.h index 09e6e6fe0c..94b0bd65b7 100644 --- a/cocos/2d/CCEventListenerTouch.h +++ b/cocos/2d/CCEventListenerTouch.h @@ -36,6 +36,8 @@ NS_CC_BEGIN class EventListenerTouchOneByOne : public EventListener { public: + static const ListenerID ID = static_cast(Type::TOUCH_ONE_BY_ONE); + static EventListenerTouchOneByOne* create(); virtual ~EventListenerTouchOneByOne(); @@ -67,6 +69,8 @@ private: class EventListenerTouchAllAtOnce : public EventListener { public: + static const ListenerID ID = static_cast(Type::TOUCH_ALL_AT_ONCE); + static EventListenerTouchAllAtOnce* create(); virtual ~EventListenerTouchAllAtOnce(); diff --git a/cocos/2d/CCEventTouch.cpp b/cocos/2d/CCEventTouch.cpp index d0df614973..9cfa0edd8d 100644 --- a/cocos/2d/CCEventTouch.cpp +++ b/cocos/2d/CCEventTouch.cpp @@ -26,5 +26,10 @@ NS_CC_BEGIN +EventTouch::EventTouch() +: Event(Type::TOUCH) +{ + _touches.reserve(MAX_TOUCHES); +} NS_CC_END diff --git a/cocos/2d/CCEventTouch.h b/cocos/2d/CCEventTouch.h index 100d67cf95..3bc18f55ca 100644 --- a/cocos/2d/CCEventTouch.h +++ b/cocos/2d/CCEventTouch.h @@ -46,11 +46,7 @@ public: CANCELLED }; - EventTouch() - : Event(TYPE_TOUCH) - { - _touches.reserve(MAX_TOUCHES); - } + EventTouch(); EventCode getEventCode() { return _eventCode; }; std::vector getTouches() { return _touches; }; From a82932524068dbc3caf1fa4cf55d06d267599dc2 Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 28 Oct 2013 16:00:19 +0800 Subject: [PATCH 054/144] issue #3069: Updating EventDispatcherTest. --- .../Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 1e7c746a56..8aa31bb82f 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -187,7 +187,7 @@ void TouchableSpriteTest::onEnter() auto senderItem = static_cast(sender); senderItem->setString("Only Next item could be clicked"); - _eventDispatcher->removeEventListeners(EventListener::TYPE_TOUCH_ONE_BY_ONE); + _eventDispatcher->removeEventListeners(EventListenerTouchOneByOne::ID); auto nextItem = MenuItemFont::create("Next", [=](Object* sender){ nextCallback(nullptr); @@ -664,5 +664,5 @@ std::string RemoveAndRetainNodeTest::title() std::string RemoveAndRetainNodeTest::subtitle() { - return ""; + return "Sprite should be removed after 5s, add to scene again after 5s"; } \ No newline at end of file From 06bd7fafd51a164c11894f5f44659cd2fcb386ea Mon Sep 17 00:00:00 2001 From: Andrew Glass Date: Mon, 28 Oct 2013 18:40:58 +0000 Subject: [PATCH 055/144] Clear NoSuchMethodError Exception when JniHelper fails to find methodID When calling GetMethodID a NoSuchMethodError will be raised if the method cannot be found. See http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp16660 This exception should be cleared if JNI execution is to be continued. Currently JniHelper informs that the method is not found, but there is no way to continue execution without manually clearing the exception. This prevents checking for the existence of a method and recovering from it being missing. This fix will clear the exception if JniHelper fails to find the method. --- cocos/2d/platform/android/jni/JniHelper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cocos/2d/platform/android/jni/JniHelper.cpp b/cocos/2d/platform/android/jni/JniHelper.cpp index ab3bfc3855..9555643d7a 100644 --- a/cocos/2d/platform/android/jni/JniHelper.cpp +++ b/cocos/2d/platform/android/jni/JniHelper.cpp @@ -213,6 +213,7 @@ namespace cocos2d { jmethodID methodID = pEnv->GetMethodID(classID, methodName, paramCode); if (! methodID) { LOGD("Failed to find method id of %s", methodName); + pEnv->ExceptionClear(); return false; } @@ -247,6 +248,7 @@ namespace cocos2d { jmethodID methodID = pEnv->GetMethodID(classID, methodName, paramCode); if (! methodID) { LOGD("Failed to find method id of %s", methodName); + pEnv->ExceptionClear(); return false; } From fe180078f07b086c686659f1a192fb6707b229dc Mon Sep 17 00:00:00 2001 From: Michael Contento Date: Mon, 28 Oct 2013 23:12:51 +0100 Subject: [PATCH 056/144] Android: add xlargeScreens="true" to supports-screens --- .../Cpp/AssetsManagerTest/proj.android/AndroidManifest.xml | 7 ++++--- samples/Cpp/HelloCpp/proj.android/AndroidManifest.xml | 7 ++++--- samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml | 7 ++++--- samples/Cpp/TestCpp/proj.android/AndroidManifest.xml | 7 ++++--- .../CocosDragonJS/proj.android/AndroidManifest.xml | 7 ++++--- .../CrystalCraze/proj.android/AndroidManifest.xml | 7 ++++--- .../MoonWarriors/proj.android/AndroidManifest.xml | 7 ++++--- .../TestJavascript/proj.android/AndroidManifest.xml | 7 ++++--- .../WatermelonWithMe/proj.android/AndroidManifest.xml | 7 ++++--- samples/Lua/HelloLua/proj.android/AndroidManifest.xml | 7 ++++--- samples/Lua/TestLua/proj.android/AndroidManifest.xml | 7 ++++--- .../multi-platform-cpp/proj.android/AndroidManifest.xml | 7 ++++--- .../multi-platform-js/proj.android/AndroidManifest.xml | 7 ++++--- .../multi-platform-lua/proj.android/AndroidManifest.xml | 7 ++++--- 14 files changed, 56 insertions(+), 42 deletions(-) diff --git a/samples/Cpp/AssetsManagerTest/proj.android/AndroidManifest.xml b/samples/Cpp/AssetsManagerTest/proj.android/AndroidManifest.xml index 7f20e0ba1f..764617b6cd 100644 --- a/samples/Cpp/AssetsManagerTest/proj.android/AndroidManifest.xml +++ b/samples/Cpp/AssetsManagerTest/proj.android/AndroidManifest.xml @@ -26,9 +26,10 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Cpp/HelloCpp/proj.android/AndroidManifest.xml b/samples/Cpp/HelloCpp/proj.android/AndroidManifest.xml index d2e4591587..dc1995c822 100644 --- a/samples/Cpp/HelloCpp/proj.android/AndroidManifest.xml +++ b/samples/Cpp/HelloCpp/proj.android/AndroidManifest.xml @@ -26,8 +26,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml b/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml index 2436e1cf1f..840bcce203 100644 --- a/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml +++ b/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml @@ -28,8 +28,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Cpp/TestCpp/proj.android/AndroidManifest.xml b/samples/Cpp/TestCpp/proj.android/AndroidManifest.xml index 6641325276..43c07631f9 100644 --- a/samples/Cpp/TestCpp/proj.android/AndroidManifest.xml +++ b/samples/Cpp/TestCpp/proj.android/AndroidManifest.xml @@ -27,10 +27,11 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Javascript/CocosDragonJS/proj.android/AndroidManifest.xml b/samples/Javascript/CocosDragonJS/proj.android/AndroidManifest.xml index 34607944fc..d68537fcf2 100644 --- a/samples/Javascript/CocosDragonJS/proj.android/AndroidManifest.xml +++ b/samples/Javascript/CocosDragonJS/proj.android/AndroidManifest.xml @@ -26,8 +26,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Javascript/CrystalCraze/proj.android/AndroidManifest.xml b/samples/Javascript/CrystalCraze/proj.android/AndroidManifest.xml index 6fa336830f..8a38988fae 100644 --- a/samples/Javascript/CrystalCraze/proj.android/AndroidManifest.xml +++ b/samples/Javascript/CrystalCraze/proj.android/AndroidManifest.xml @@ -26,8 +26,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Javascript/MoonWarriors/proj.android/AndroidManifest.xml b/samples/Javascript/MoonWarriors/proj.android/AndroidManifest.xml index 8c1aa00cc0..f61fe3e0db 100644 --- a/samples/Javascript/MoonWarriors/proj.android/AndroidManifest.xml +++ b/samples/Javascript/MoonWarriors/proj.android/AndroidManifest.xml @@ -26,8 +26,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Javascript/TestJavascript/proj.android/AndroidManifest.xml b/samples/Javascript/TestJavascript/proj.android/AndroidManifest.xml index 3797ac08e2..7beabd487a 100644 --- a/samples/Javascript/TestJavascript/proj.android/AndroidManifest.xml +++ b/samples/Javascript/TestJavascript/proj.android/AndroidManifest.xml @@ -28,8 +28,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Javascript/WatermelonWithMe/proj.android/AndroidManifest.xml b/samples/Javascript/WatermelonWithMe/proj.android/AndroidManifest.xml index aae0c2ff1d..6bbdd131cb 100644 --- a/samples/Javascript/WatermelonWithMe/proj.android/AndroidManifest.xml +++ b/samples/Javascript/WatermelonWithMe/proj.android/AndroidManifest.xml @@ -26,8 +26,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Lua/HelloLua/proj.android/AndroidManifest.xml b/samples/Lua/HelloLua/proj.android/AndroidManifest.xml index 56e3d50105..95394a531e 100644 --- a/samples/Lua/HelloLua/proj.android/AndroidManifest.xml +++ b/samples/Lua/HelloLua/proj.android/AndroidManifest.xml @@ -26,8 +26,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/samples/Lua/TestLua/proj.android/AndroidManifest.xml b/samples/Lua/TestLua/proj.android/AndroidManifest.xml index e131aee1a3..fb1ec4abb6 100644 --- a/samples/Lua/TestLua/proj.android/AndroidManifest.xml +++ b/samples/Lua/TestLua/proj.android/AndroidManifest.xml @@ -26,9 +26,10 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/template/multi-platform-cpp/proj.android/AndroidManifest.xml b/template/multi-platform-cpp/proj.android/AndroidManifest.xml index dc7f8640b6..466677da86 100644 --- a/template/multi-platform-cpp/proj.android/AndroidManifest.xml +++ b/template/multi-platform-cpp/proj.android/AndroidManifest.xml @@ -28,10 +28,11 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/template/multi-platform-js/proj.android/AndroidManifest.xml b/template/multi-platform-js/proj.android/AndroidManifest.xml index e37a9e90f9..0977e3eb08 100644 --- a/template/multi-platform-js/proj.android/AndroidManifest.xml +++ b/template/multi-platform-js/proj.android/AndroidManifest.xml @@ -27,8 +27,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> diff --git a/template/multi-platform-lua/proj.android/AndroidManifest.xml b/template/multi-platform-lua/proj.android/AndroidManifest.xml index b8964e7a15..17a26a9913 100644 --- a/template/multi-platform-lua/proj.android/AndroidManifest.xml +++ b/template/multi-platform-lua/proj.android/AndroidManifest.xml @@ -27,8 +27,9 @@ - + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> From d11854c11175b8442cae4b4559437abf2022bcf5 Mon Sep 17 00:00:00 2001 From: minggo Date: Tue, 29 Oct 2013 09:04:11 +0800 Subject: [PATCH 057/144] Update AUTHORS --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index 9357213fb6..89cb90728d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -630,6 +630,9 @@ Developers: lite3 Fixed a bug that Node's anchor point was changed after being added to ScrollView. + superrad + Clear NoSuchMethodError Exception when JniHelper fails to find methodID + Retired Core Developers: WenSheng Yang Author of windows port, CCTextField, From f2c229c722a60382678d92504a10a0bb4886671d Mon Sep 17 00:00:00 2001 From: minggo Date: Tue, 29 Oct 2013 09:05:04 +0800 Subject: [PATCH 058/144] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 567b572bc1..13c23de97a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] Added EGL_RENDERABLE_TYPE to OpenGL attributes [NEW] Added Cocos2dxHelper.runOnGLThread(Runnable) again [FIX] Fixed application will crash when pause and resume. + [FIX] Clear NoSuchMethodError Exception when JniHelper fails to find method id [Mac] [FIX] Removed unused CCLOG() from GL initialization [iOS] From d4995a8c9c3b09a48e428d60f705f637aa5115aa Mon Sep 17 00:00:00 2001 From: minggo Date: Tue, 29 Oct 2013 10:06:32 +0800 Subject: [PATCH 059/144] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 89cb90728d..469f299f7c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -592,6 +592,7 @@ Developers: Prevent nullptr access in AssetsManager [Android] re-introduce Cocos2dxHelper.runOnGLThread(Runnable) [Android] added EGL_RENDERABLE_TYPE to OpenGL attributes + Android: add xlargeScreens="true" to supports-screens bmanGH Use gl caching functions in TexturePVR::createGLTexture() From df3ebf84519c8337329eaf5fc3ca5abbcdfaf313 Mon Sep 17 00:00:00 2001 From: minggo Date: Tue, 29 Oct 2013 10:07:43 +0800 Subject: [PATCH 060/144] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 13c23de97a..8fc9c367ee 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [NEW] Added Cocos2dxHelper.runOnGLThread(Runnable) again [FIX] Fixed application will crash when pause and resume. [FIX] Clear NoSuchMethodError Exception when JniHelper fails to find method id + [NEW] Added xlargeScreens="true" to supports-screens [Mac] [FIX] Removed unused CCLOG() from GL initialization [iOS] From a4d028e905c31a8884bed780b158683370e4b500 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 11:40:41 +0800 Subject: [PATCH 061/144] issue #3409:Add XMLHttpRequest lua binding and corresponding test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/scripting/lua/bindings/CCLuaStack.cpp | 4 + .../lua/bindings/LuaScriptHandlerMgr.h | 2 + .../lua/bindings/lua_xml_http_request.cpp | 195 ++++++++- .../lua/bindings/lua_xml_http_request.h | 10 +- cocos/scripting/lua/script/json.lua | 376 ++++++++++++++++++ .../XMLHttpRequestTest/XMLHttpRequestTest.lua | 147 +++++++ .../TestLua/Resources/luaScript/mainMenu.lua | 4 +- 8 files changed, 723 insertions(+), 17 deletions(-) create mode 100755 cocos/scripting/lua/script/json.lua create mode 100644 samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 70bb169acc..a937cb6412 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -83265c81797ca614f19372a96adf326aeb21b396 \ No newline at end of file +8a22c92b099f198f28124f0d7c6dd031b07d0154 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/CCLuaStack.cpp b/cocos/scripting/lua/bindings/CCLuaStack.cpp index be2aa86dd9..bad774b677 100644 --- a/cocos/scripting/lua/bindings/CCLuaStack.cpp +++ b/cocos/scripting/lua/bindings/CCLuaStack.cpp @@ -53,6 +53,7 @@ extern "C" { #include "LuaBasicConversions.h" #include "lua_cocos2dx_extension_manual.h" #include "lua_cocos2dx_deprecated.h" +#include "lua_xml_http_request.h" namespace { int lua_print(lua_State * luastate) @@ -148,6 +149,9 @@ bool LuaStack::init(void) #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) tolua_web_socket_open(_state); #endif + + register_xml_http_request(_state); + tolua_script_handler_mgr_open(_state); // add cocos2dx loader diff --git a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h index 44ea6fa103..82bcfee944 100644 --- a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h +++ b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h @@ -95,6 +95,8 @@ public: TABLECELL_SIZE_FOR_INDEX, TABLECELL_AT_INDEX, TABLEVIEW_NUMS_OF_CELLS, + + XMLHTTPREQUEST_READY_STATE_CHANGE, }; typedef int Handler; diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp index eaf2202ba0..f63e55c0b1 100644 --- a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp @@ -7,7 +7,13 @@ extern "C" } #include +#include "CCLuaStack.h" +#include "CCLuaValue.h" +#include "CCLuaEngine.h" +#include "LuaScriptHandlerMgr.h" + +using namespace cocos2d; using namespace std; LuaMinXmlHttpRequest::LuaMinXmlHttpRequest():_isNetwork(true) @@ -203,9 +209,12 @@ void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, n /** get the response data **/ std::vector *buffer = response->getResponseData(); +// for (unsigned int i = 0; i < buffer->size(); i++) +// { +// printf("%c", (*buffer)[i]); +// } char* concatenated = (char*) malloc(buffer->size() + 1); std::string s2(buffer->begin(), buffer->end()); - strcpy(concatenated, s2.c_str()); if (statusCode == 200) @@ -225,7 +234,19 @@ void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, n free((void*) concatenated); // call back lua function --TODO - int handler = 0; + int handler = cocos2d::ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE ); + + if (0 != handler) + { + cocos2d::CommonScriptData data(handler,""); + cocos2d::ScriptEvent event(cocos2d::ScriptEventType::kCommonEvent,(void*)&data); + cocos2d::ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); + } +} + +void LuaMinXmlHttpRequest::getByteData(unsigned char* byteData) +{ + _data.read((char*)byteData, _dataSize); } /* function to regType */ @@ -258,6 +279,7 @@ static int lua_cocos2dx_XMLHttpRequest_constructor(lua_State* L) int ID = self? (int)self->_ID : -1; int* luaID = self? &self->_luaID : NULL; toluafix_pushusertype_ccobject(L, ID, luaID, (void*)self, "XMLHttpRequest"); + return 1; } CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "XMLHttpRequest",argc, 0); @@ -567,6 +589,33 @@ tolua_lerror: #endif } +static int lua_get_XMLHttpRequest_responseText(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_responseText'\n", nullptr); + return 0; + } +#endif + lua_pushstring(L, self->getDataStr().c_str()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_responseText'.",&tolua_err); + return 0; +#endif +} + static int lua_get_XMLHttpRequest_response(lua_State* L) { LuaMinXmlHttpRequest* self = nullptr; @@ -587,17 +636,46 @@ static int lua_get_XMLHttpRequest_response(lua_State* L) if (self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::JSON) { - //TODO - return 0; + lua_pushstring(L, self->getDataStr().c_str()); + return 1; } else if(self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::ARRAY_BUFFER) { - //TODO - return 0; + LuaStack *pStack = LuaEngine::getInstance()->getLuaStack(); + if (NULL == pStack) { + return 0; + } + + lua_State *tolua_s = pStack->getLuaState(); + if (NULL == tolua_s) { + return 0; + } + + int nRet = 0; + LuaValueArray array; + + uint8_t* tmpData = new uint8_t[self->getDataSize()]; + if (nullptr == tmpData) + { + return 0; + } + + self->getByteData(tmpData); + + for (int i = 0 ; i < self->getDataSize(); i++) + { + LuaValue value = LuaValue::intValue(tmpData[i]); + array.push_back(value); + } + + pStack->pushLuaValueArray(array); + + CC_SAFE_DELETE_ARRAY(tmpData); + return 1; } else { - lua_pushstring(L, self->getStatusText().c_str()); + lua_pushstring(L, self->getDataStr().c_str()); return 1; } @@ -694,7 +772,9 @@ static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L) { int argc = 0; LuaMinXmlHttpRequest* self = nullptr; - std::string data = ""; + //std::string data = ""; + const char* data = NULL; + size_t size = 0; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; @@ -718,14 +798,15 @@ static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L) if (!tolua_isstring(L, 2, 0, &tolua_err)) goto tolua_lerror; #endif - data = tolua_tostring(L, 2, ""); + //data = tolua_tostring(L, 2, ""); + data = (const char*) lua_tolstring(L, 2, &size); } - if (data.length() > 0 && + if (size > 0 && (self->getMethod().compare("post") == 0 || self->getMethod().compare("POST") == 0) && nullptr != self->getHttpRequest()) { - self->getHttpRequest()->setRequestData(data.c_str(), data.length()); + self->getHttpRequest()->setRequestData(data,size); } self->_setHttpRequestHeader(); @@ -894,13 +975,98 @@ tolua_lerror: #endif } -TOLUA_API int lua_xml_http_request_open(lua_State* L) +static int lua_cocos2dx_XMLHttpRequest_registerScriptHandler(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_registerScriptHandler'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!toluafix_isfunction(L,2,"LUA_FUNCTION",0,&tolua_err)) + goto tolua_lerror; +#endif + + int handler = ( toluafix_ref_function(L,2,0)); + cocos2d::ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE); + return 0; + } + + CCLOG("'registerScriptHandler' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_registerScriptHandler'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (0 == argc) + { + cocos2d::ScriptHandlerMgr::getInstance()->removeObjectHandler((void*)self, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE); + + return 0; + } + + CCLOG("'unregisterScriptHandler' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler'.",&tolua_err); + return 0; +#endif + +} + + +TOLUA_API int register_xml_http_request(lua_State* L) { tolua_open(L); lua_reg_xml_http_request(L); tolua_module(L,NULL,0); tolua_beginmodule(L,NULL); - tolua_cclass(L,"XMLHttpRequest","XMLHttpRequest","",lua_collect_xml_http_request); + tolua_cclass(L,"XMLHttpRequest","XMLHttpRequest","Object",lua_collect_xml_http_request); tolua_beginmodule(L,"XMLHttpRequest"); tolua_variable(L, "responseType", lua_get_XMLHttpRequest_responseType, lua_set_XMLHttpRequest_responseType); tolua_variable(L, "withCredentials", lua_get_XMLHttpRequest_withCredentials, lua_set_XMLHttpRequest_withCredentials); @@ -908,6 +1074,7 @@ TOLUA_API int lua_xml_http_request_open(lua_State* L) tolua_variable(L, "readyState", lua_get_XMLHttpRequest_readyState, nullptr); tolua_variable(L, "status",lua_get_XMLHttpRequest_status,nullptr); tolua_variable(L, "statusText", lua_get_XMLHttpRequest_statusText, nullptr); + tolua_variable(L, "responseText", lua_get_XMLHttpRequest_responseText, nullptr); tolua_variable(L, "response", lua_get_XMLHttpRequest_response, nullptr); tolua_function(L, "new", lua_cocos2dx_XMLHttpRequest_constructor); tolua_function(L, "open", lua_cocos2dx_XMLHttpRequest_open); @@ -916,6 +1083,8 @@ TOLUA_API int lua_xml_http_request_open(lua_State* L) tolua_function(L, "setRequestHeader", lua_cocos2dx_XMLHttpRequest_setRequestHeader); tolua_function(L, "getAllResponseHeaders", lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders); tolua_function(L, "getResponseHeader", lua_cocos2dx_XMLHttpRequest_getResponseHeader); + tolua_function(L, "registerScriptHandler", lua_cocos2dx_XMLHttpRequest_registerScriptHandler); + tolua_function(L, "unregisterScriptHandler", lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler); tolua_endmodule(L); tolua_endmodule(L); return 1; diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.h b/cocos/scripting/lua/bindings/lua_xml_http_request.h index 2b5a3a2f17..900ec6db35 100644 --- a/cocos/scripting/lua/bindings/lua_xml_http_request.h +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.h @@ -66,11 +66,17 @@ public: void setRequestHeader(const char* field, const char* value); std::map getHttpHeader() { return _httpHeader ;} + + void getByteData(unsigned char* byteData); + + inline std::string getDataStr() { return _data.str(); } + + inline size_t getDataSize() { return _dataSize; } + private: void _gotHeader(std::string header); - std::string _url; std::string _meth; std::string _type; @@ -89,6 +95,6 @@ private: std::map _requestHeader; }; -TOLUA_API int lua_xml_http_request_open(lua_State* L); +TOLUA_API int register_xml_http_request(lua_State* L); #endif //#ifndef __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ diff --git a/cocos/scripting/lua/script/json.lua b/cocos/scripting/lua/script/json.lua new file mode 100755 index 0000000000..e0b3d17c3e --- /dev/null +++ b/cocos/scripting/lua/script/json.lua @@ -0,0 +1,376 @@ +----------------------------------------------------------------------------- +-- JSON4Lua: JSON encoding / decoding support for the Lua language. +-- json Module. +-- Author: Craig Mason-Jones +-- Homepage: http://json.luaforge.net/ +-- Version: 0.9.40 +-- This module is released under the MIT License (MIT). +-- Please see LICENCE.txt for details. +-- +-- USAGE: +-- This module exposes two functions: +-- encode(o) +-- Returns the table / string / boolean / number / nil / json.null value as a JSON-encoded string. +-- decode(json_string) +-- Returns a Lua object populated with the data encoded in the JSON string json_string. +-- +-- REQUIREMENTS: +-- compat-5.1 if using Lua 5.0 +-- +-- CHANGELOG +-- 0.9.20 Introduction of local Lua functions for private functions (removed _ function prefix). +-- Fixed Lua 5.1 compatibility issues. +-- Introduced json.null to have null values in associative arrays. +-- encode() performance improvement (more than 50%) through table.concat rather than .. +-- Introduced decode ability to ignore /**/ comments in the JSON string. +-- 0.9.10 Fix to array encoding / decoding to correctly manage nil/null values in arrays. +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Imports and dependencies +----------------------------------------------------------------------------- +local math = require('math') +local string = require("string") +local table = require("table") + +local base = _G + +----------------------------------------------------------------------------- +-- Module declaration +----------------------------------------------------------------------------- +module("json") + +-- Public functions + +-- Private functions +local decode_scanArray +local decode_scanComment +local decode_scanConstant +local decode_scanNumber +local decode_scanObject +local decode_scanString +local decode_scanWhitespace +local encodeString +local isArray +local isEncodable + +----------------------------------------------------------------------------- +-- PUBLIC FUNCTIONS +----------------------------------------------------------------------------- +--- Encodes an arbitrary Lua object / variable. +-- @param v The Lua object / variable to be JSON encoded. +-- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode) +function encode (v) + -- Handle nil values + if v==nil then + return "null" + end + + local vtype = base.type(v) + + -- Handle strings + if vtype=='string' then + return '"' .. encodeString(v) .. '"' -- Need to handle encoding in string + end + + -- Handle booleans + if vtype=='number' or vtype=='boolean' then + return base.tostring(v) + end + + -- Handle tables + if vtype=='table' then + local rval = {} + -- Consider arrays separately + local bArray, maxCount = isArray(v) + if bArray then + for i = 1,maxCount do + table.insert(rval, encode(v[i])) + end + else -- An object, not an array + for i,j in base.pairs(v) do + if isEncodable(i) and isEncodable(j) then + table.insert(rval, '"' .. encodeString(i) .. '":' .. encode(j)) + end + end + end + if bArray then + return '[' .. table.concat(rval,',') ..']' + else + return '{' .. table.concat(rval,',') .. '}' + end + end + + -- Handle null values + if vtype=='function' and v==null then + return 'null' + end + + base.assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. base.tostring(v)) +end + + +--- Decodes a JSON string and returns the decoded value as a Lua data structure / value. +-- @param s The string to scan. +-- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1. +-- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil, +-- and the position of the first character after +-- the scanned JSON object. +function decode(s, startPos) + startPos = startPos and startPos or 1 + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']') + local curChar = string.sub(s,startPos,startPos) + -- Object + if curChar=='{' then + return decode_scanObject(s,startPos) + end + -- Array + if curChar=='[' then + return decode_scanArray(s,startPos) + end + -- Number + if string.find("+-0123456789.e", curChar, 1, true) then + return decode_scanNumber(s,startPos) + end + -- String + if curChar==[["]] or curChar==[[']] then + return decode_scanString(s,startPos) + end + if string.sub(s,startPos,startPos+1)=='/*' then + return decode(s, decode_scanComment(s,startPos)) + end + -- Otherwise, it must be a constant + return decode_scanConstant(s,startPos) +end + +--- The null function allows one to specify a null value in an associative array (which is otherwise +-- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null } +function null() + return null -- so json.null() will also return null ;-) +end +----------------------------------------------------------------------------- +-- Internal, PRIVATE functions. +-- Following a Python-like convention, I have prefixed all these 'PRIVATE' +-- functions with an underscore. +----------------------------------------------------------------------------- + +--- Scans an array from JSON into a Lua object +-- startPos begins at the start of the array. +-- Returns the array and the next starting position +-- @param s The string being scanned. +-- @param startPos The starting position for the scan. +-- @return table, int The scanned array as a table, and the position of the next character to scan. +function decode_scanArray(s,startPos) + local array = {} -- The return value + local stringLen = string.len(s) + base.assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s ) + startPos = startPos + 1 + -- Infinite loop for array elements + repeat + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.') + local curChar = string.sub(s,startPos,startPos) + if (curChar==']') then + return array, startPos+1 + end + if (curChar==',') then + startPos = decode_scanWhitespace(s,startPos+1) + end + base.assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.') + object, startPos = decode(s,startPos) + table.insert(array,object) + until false +end + +--- Scans a comment and discards the comment. +-- Returns the position of the next character following the comment. +-- @param string s The JSON string to scan. +-- @param int startPos The starting position of the comment +function decode_scanComment(s, startPos) + base.assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos) + local endPos = string.find(s,'*/',startPos+2) + base.assert(endPos~=nil, "Unterminated comment in string at " .. startPos) + return endPos+2 +end + +--- Scans for given constants: true, false or null +-- Returns the appropriate Lua type, and the position of the next character to read. +-- @param s The string being scanned. +-- @param startPos The position in the string at which to start scanning. +-- @return object, int The object (true, false or nil) and the position at which the next character should be +-- scanned. +function decode_scanConstant(s, startPos) + local consts = { ["true"] = true, ["false"] = false, ["null"] = nil } + local constNames = {"true","false","null"} + + for i,k in base.pairs(constNames) do + --print ("[" .. string.sub(s,startPos, startPos + string.len(k) -1) .."]", k) + if string.sub(s,startPos, startPos + string.len(k) -1 )==k then + return consts[k], startPos + string.len(k) + end + end + base.assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos) +end + +--- Scans a number from the JSON encoded string. +-- (in fact, also is able to scan numeric +- eqns, which is not +-- in the JSON spec.) +-- Returns the number, and the position of the next character +-- after the number. +-- @param s The string being scanned. +-- @param startPos The position at which to start scanning. +-- @return number, int The extracted number and the position of the next character to scan. +function decode_scanNumber(s,startPos) + local endPos = startPos+1 + local stringLen = string.len(s) + local acceptableChars = "+-0123456789.e" + while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true) + and endPos<=stringLen + ) do + endPos = endPos + 1 + end + local stringValue = 'return ' .. string.sub(s,startPos, endPos-1) + local stringEval = base.loadstring(stringValue) + base.assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos) + return stringEval(), endPos +end + +--- Scans a JSON object into a Lua object. +-- startPos begins at the start of the object. +-- Returns the object and the next starting position. +-- @param s The string being scanned. +-- @param startPos The starting position of the scan. +-- @return table, int The scanned object as a table and the position of the next character to scan. +function decode_scanObject(s,startPos) + local object = {} + local stringLen = string.len(s) + local key, value + base.assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s) + startPos = startPos + 1 + repeat + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.') + local curChar = string.sub(s,startPos,startPos) + if (curChar=='}') then + return object,startPos+1 + end + if (curChar==',') then + startPos = decode_scanWhitespace(s,startPos+1) + end + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.') + -- Scan the key + key, startPos = decode(s,startPos) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key) + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key) + base.assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos) + startPos = decode_scanWhitespace(s,startPos+1) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key) + value, startPos = decode(s,startPos) + object[key]=value + until false -- infinite loop while key-value pairs are found +end + +--- Scans a JSON string from the opening inverted comma or single quote to the +-- end of the string. +-- Returns the string extracted as a Lua string, +-- and the position of the next non-string character +-- (after the closing inverted comma or single quote). +-- @param s The string being scanned. +-- @param startPos The starting position of the scan. +-- @return string, int The extracted string as a Lua string, and the next character to parse. +function decode_scanString(s,startPos) + base.assert(startPos, 'decode_scanString(..) called without start position') + local startChar = string.sub(s,startPos,startPos) + base.assert(startChar==[[']] or startChar==[["]],'decode_scanString called for a non-string') + local escaped = false + local endPos = startPos + 1 + local bEnded = false + local stringLen = string.len(s) + repeat + local curChar = string.sub(s,endPos,endPos) + if not escaped then + if curChar==[[\]] then + escaped = true + else + bEnded = curChar==startChar + end + else + -- If we're escaped, we accept the current character come what may + escaped = false + end + endPos = endPos + 1 + base.assert(endPos <= stringLen+1, "String decoding failed: unterminated string at position " .. endPos) + until bEnded + local stringValue = 'return ' .. string.sub(s, startPos, endPos-1) + local stringEval = base.loadstring(stringValue) + base.assert(stringEval, 'Failed to load string [ ' .. stringValue .. '] in JSON4Lua.decode_scanString at position ' .. startPos .. ' : ' .. endPos) + return stringEval(), endPos +end + +--- Scans a JSON string skipping all whitespace from the current start position. +-- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached. +-- @param s The string being scanned +-- @param startPos The starting position where we should begin removing whitespace. +-- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string +-- was reached. +function decode_scanWhitespace(s,startPos) + local whitespace=" \n\r\t" + local stringLen = string.len(s) + while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true) and startPos <= stringLen) do + startPos = startPos + 1 + end + return startPos +end + +--- Encodes a string to be JSON-compatible. +-- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-) +-- @param s The string to return as a JSON encoded (i.e. backquoted string) +-- @return The string appropriately escaped. +function encodeString(s) + s = string.gsub(s,'\\','\\\\') + s = string.gsub(s,'"','\\"') + s = string.gsub(s,"'","\\'") + s = string.gsub(s,'\n','\\n') + s = string.gsub(s,'\t','\\t') + return s +end + +-- Determines whether the given Lua type is an array or a table / dictionary. +-- We consider any table an array if it has indexes 1..n for its n items, and no +-- other data in the table. +-- I think this method is currently a little 'flaky', but can't think of a good way around it yet... +-- @param t The table to evaluate as an array +-- @return boolean, number True if the table can be represented as an array, false otherwise. If true, +-- the second returned value is the maximum +-- number of indexed elements in the array. +function isArray(t) + -- Next we count all the elements, ensuring that any non-indexed elements are not-encodable + -- (with the possible exception of 'n') + local maxIndex = 0 + for k,v in base.pairs(t) do + if (base.type(k)=='number' and math.floor(k)==k and 1<=k) then -- k,v is an indexed pair + if (not isEncodable(v)) then return false end -- All array elements must be encodable + maxIndex = math.max(maxIndex,k) + else + if (k=='n') then + if v ~= table.getn(t) then return false end -- False if n does not hold the number of elements + else -- Else of (k=='n') + if isEncodable(v) then return false end + end -- End of (k~='n') + end -- End of k,v not an indexed pair + end -- End of loop across all pairs + return true, maxIndex +end + +--- Determines whether the given Lua object / table / variable can be JSON encoded. The only +-- types that are JSON encodable are: string, boolean, number, nil, table and json.null. +-- In this implementation, all other types are ignored. +-- @param o The object to examine. +-- @return boolean True if the object should be JSON encoded, false if it should be ignored. +function isEncodable(o) + local t = base.type(o) + return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or (t=='function' and o==null) +end + diff --git a/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua new file mode 100644 index 0000000000..2456d5d092 --- /dev/null +++ b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua @@ -0,0 +1,147 @@ +require("json") + +local function XMLHttpRequestLayer() + local layer = cc.Layer:create() + local winSize = cc.Director:getInstance():getWinSize() + local margin = 40 + local space = 35 + + local function init() + local label = cc.LabelTTF:create("XML Http Request Test", "Arial", 28) + label:setPosition(cc.p(winSize.width / 2, winSize.height - margin)) + layer:addChild(label, 0) + + --Response Code Label + local labelStatusCode = cc.LabelTTF:create("HTTP Status Code", "Marker Felt", 20) + labelStatusCode:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 6 * space)) + layer:addChild(labelStatusCode) + + local menuRequest = cc.Menu:create() + menuRequest:setPosition(cc.p(0,0)) + layer:addChild(menuRequest) + + --Get + local function onMenuGetClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 0 + xhr:open("GET", "http://httpbin.org/get") + + local function onReadyStateChange() + local statusString = "Http Status Code:"..xhr.statusText + labelStatusCode:setString(statusString) + print(xhr.response) + end + + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelGet = cc.LabelTTF:create("Test Get", "Arial", 22) + local itemGet = cc.MenuItemLabel:create(labelGet) + itemGet:registerScriptTapHandler(onMenuGetClicked) + itemGet:setPosition(cc.p(winSize.width / 2, winSize.height - margin - space)) + menuRequest:addChild(itemGet) + + --Post + local function onMenuPostClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 0 + xhr:open("POST", "http://httpbin.org/post") + local function onReadyStateChange() + labelStatusCode:setString("Http Status Code:"..xhr.statusText) + print(xhr.response) + end + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelPost = cc.LabelTTF:create("Test Post", "Arial", 22) + local itemPost = cc.MenuItemLabel:create(labelPost) + itemPost:registerScriptTapHandler(onMenuPostClicked) + itemPost:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 2 * space)) + menuRequest:addChild(itemPost) + + --Post Binary + local function onMenuPostBinaryClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 1 + xhr:open("POST", "http://httpbin.org/post") + + local function onReadyStateChange() + local response = xhr.response + local size = table.getn(response) + local strInfo = "" + + for i = 1,size do + if 0 == response[i] then + strInfo = strInfo.."\'\\0\'" + else + strInfo = strInfo..string.char(response[i]) + end + end + labelStatusCode:setString("Http Status Code:"..xhr.statusText) + print(strInfo) + end + + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelPostBinary = cc.LabelTTF:create("Test Post Binary", "Arial", 22) + local itemPostBinary = cc.MenuItemLabel:create(labelPostBinary) + itemPostBinary:registerScriptTapHandler(onMenuPostBinaryClicked) + itemPostBinary:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 3 * space)) + menuRequest:addChild(itemPostBinary) + + --Post Json + + local function onMenuPostJsonClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 4 + xhr:open("POST", "http://httpbin.org/post") + + local function onReadyStateChange() + labelStatusCode:setString("Http Status Code:"..xhr.statusText) + local response = xhr.response + local output = json.decode(response,1) + table.foreach(output,function(i, v) print (i, v) end) + print("headers are") + table.foreach(output.headers,print) + end + + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelPostJson = cc.LabelTTF:create("Test Post Json", "Arial", 22) + local itemPostJson = cc.MenuItemLabel:create(labelPostJson) + itemPostJson:registerScriptTapHandler(onMenuPostJsonClicked) + itemPostJson:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 4 * space)) + menuRequest:addChild(itemPostJson) + end + + local function onNodeEvent(eventName) + if "enter" == eventName then + init() + end + end + + layer:registerScriptHandler(onNodeEvent) + + return layer +end + +function XMLHttpRequestTestMain() + local scene = cc.Scene:create() + scene:addChild(XMLHttpRequestLayer()) + scene:addChild(CreateBackMenuItem()) + return scene +end diff --git a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua index 73d79855d6..3129caf5cb 100644 --- a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua +++ b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua @@ -44,6 +44,7 @@ require "luaScript/TransitionsTest/TransitionsTest" require "luaScript/UserDefaultTest/UserDefaultTest" require "luaScript/ZwoptexTest/ZwoptexTest" require "luaScript/LuaBridgeTest/LuaBridgeTest" +require "luaScript/XMLHttpRequestTest/XMLHttpRequestTest" local LINE_SPACE = 40 @@ -97,7 +98,8 @@ local _allTests = { { isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest }, { isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain }, { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain }, - { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest } + { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest }, + { isSupported = true, name = "XMLHttpRequestTest" , create_func = XMLHttpRequestTestMain} } local TESTS_COUNT = table.getn(_allTests) From 296978a9bee8ac85e8d2e8512c3d9781bedfe53c Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 14:57:16 +0800 Subject: [PATCH 062/144] issue #3069: Separate 'EventDispatcher::removeEventListeners' to 'removeEventListeners' and 'removeCustomEventListeners'. --- cocos/2d/CCEventDispatcher.cpp | 16 ++++++++++++++-- cocos/2d/CCEventDispatcher.h | 25 ++++++++++++++++--------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 1ebadf9b74..8d590c033d 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -993,7 +993,7 @@ EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListene return nullptr; } -void EventDispatcher::removeEventListeners(EventListener::ListenerID listenerID) +void EventDispatcher::removeEventListenersForListenerID(EventListener::ListenerID listenerID) { auto listenerItemIter = _listeners.find(listenerID); if (listenerItemIter != _listeners.end()) @@ -1040,6 +1040,18 @@ void EventDispatcher::removeEventListeners(EventListener::ListenerID listenerID) } } +void EventDispatcher::removeEventListeners(EventListener::Type listenerType) +{ + CCASSERT(listenerType != EventListener::Type::CUSTOM, "Not support custom event listener type, please use EventDispatcher::removeCustomEventListeners instead."); + + removeEventListenersForListenerID(static_cast(listenerType)); +} + +void EventDispatcher::removeCustomEventListeners(const std::string& customEventName) +{ + removeEventListenersForListenerID(std::hash()(customEventName)); +} + void EventDispatcher::removeAllEventListeners() { std::vector types(_listeners.size()); @@ -1051,7 +1063,7 @@ void EventDispatcher::removeAllEventListeners() for (auto& type : types) { - removeEventListeners(type); + removeEventListenersForListenerID(type); } if (!_inDispatch) diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index 3609c7a591..b8b1aa8efb 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -74,8 +74,11 @@ public: */ void removeEventListener(EventListener* listener); - /** Removes all listeners with the same event listener ID */ - void removeEventListeners(EventListener::ListenerID listenerID); + /** Removes all listeners with the same event listener type */ + void removeEventListeners(EventListener::Type listenerType); + + /** Removes all custom listeners with the same event name */ + void removeCustomEventListeners(const std::string& customEventName); /** Removes all listeners */ void removeAllEventListeners(); @@ -95,6 +98,14 @@ public: */ void dispatchEvent(Event* event); + /** Constructor of EventDispatcher */ + EventDispatcher(); + /** Destructor of EventDispatcher */ + ~EventDispatcher(); + +private: + friend class Node; + /** Sets the dirty flag for a node. */ void setDirtyForNode(Node* node); @@ -107,13 +118,6 @@ public: /** Notifys event dispatcher that the node has been deleted. */ void cleanTarget(Node* node); - /** Constructor of EventDispatcher */ - EventDispatcher(); - /** Destructor of EventDispatcher */ - ~EventDispatcher(); - -private: - /** * The vector to store event listeners with scene graph based priority and fixed priority. */ @@ -149,6 +153,9 @@ private: /** Update dirty flag */ void updateDirtyFlagForSceneGraph(); + /** Removes all listeners with the same event listener ID */ + void removeEventListenersForListenerID(EventListener::ListenerID listenerID); + /** Sort event listener */ void sortEventListeners(EventListener::ListenerID listenerID); From 5698dcd0e18788a00b9fb6510224f310cbfb856e Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 14:58:47 +0800 Subject: [PATCH 063/144] issue #3069: Protecting some methods in EventListener, make EventDispatcher as its friend class. --- cocos/2d/CCEventListener.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cocos/2d/CCEventListener.h b/cocos/2d/CCEventListener.h index bbf5121149..ea4734f7a3 100644 --- a/cocos/2d/CCEventListener.h +++ b/cocos/2d/CCEventListener.h @@ -74,6 +74,7 @@ public: /** Clones the listener, its subclasses have to override this method. */ virtual EventListener* clone() = 0; +protected: inline void setPaused(bool paused) { _paused = paused; }; inline bool isPaused() const { return _paused; }; @@ -91,16 +92,16 @@ public: std::function _onEvent; /// Event callback function -protected: - Type _type; /// Event listener type ListenerID _listenerID; /// Event listener ID bool _isRegistered; /// Whether the listener has been added to dispatcher. // The priority of event listener int _fixedPriority; // The higher the number, the higher the priority, 0 is for scene graph base priority. - Node* _node; // scene graph based priority - bool _paused; + Node* _node; // scene graph based priority + bool _paused; // Whether the listener is paused + + friend class EventDispatcher; }; NS_CC_END From cb7a762584dd9fcc800ad31ee616bd6b3eff5f06 Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 14:59:05 +0800 Subject: [PATCH 064/144] issue #3069: Updating EventDispatcherTest. --- .../Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 8aa31bb82f..bbc041c70b 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -187,7 +187,7 @@ void TouchableSpriteTest::onEnter() auto senderItem = static_cast(sender); senderItem->setString("Only Next item could be clicked"); - _eventDispatcher->removeEventListeners(EventListenerTouchOneByOne::ID); + _eventDispatcher->removeEventListeners(EventListener::Type::TOUCH_ONE_BY_ONE); auto nextItem = MenuItemFont::create("Next", [=](Object* sender){ nextCallback(nullptr); From 01579e12b0e87a9ae4affa12a376eb60bfed7e0e Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 15:01:39 +0800 Subject: [PATCH 065/144] issue #3069: Remove unused ID. --- cocos/2d/CCEventListenerAcceleration.h | 2 -- cocos/2d/CCEventListenerKeyboard.h | 2 -- cocos/2d/CCEventListenerTouch.h | 2 -- 3 files changed, 6 deletions(-) diff --git a/cocos/2d/CCEventListenerAcceleration.h b/cocos/2d/CCEventListenerAcceleration.h index 213bac646e..59ce3d8439 100644 --- a/cocos/2d/CCEventListenerAcceleration.h +++ b/cocos/2d/CCEventListenerAcceleration.h @@ -33,8 +33,6 @@ NS_CC_BEGIN class EventListenerAcceleration : public EventListener { public: - static const ListenerID ID = static_cast(Type::ACCELERATION); - static EventListenerAcceleration* create(std::function callback); virtual ~EventListenerAcceleration(); diff --git a/cocos/2d/CCEventListenerKeyboard.h b/cocos/2d/CCEventListenerKeyboard.h index 6c59f69121..c34d2add0d 100644 --- a/cocos/2d/CCEventListenerKeyboard.h +++ b/cocos/2d/CCEventListenerKeyboard.h @@ -36,8 +36,6 @@ class Event; class EventListenerKeyboard : public EventListener { public: - static const ListenerID ID = static_cast(Type::KEYBOARD); - static EventListenerKeyboard* create(); /// Overrides diff --git a/cocos/2d/CCEventListenerTouch.h b/cocos/2d/CCEventListenerTouch.h index 94b0bd65b7..80ff176263 100644 --- a/cocos/2d/CCEventListenerTouch.h +++ b/cocos/2d/CCEventListenerTouch.h @@ -36,8 +36,6 @@ NS_CC_BEGIN class EventListenerTouchOneByOne : public EventListener { public: - static const ListenerID ID = static_cast(Type::TOUCH_ONE_BY_ONE); - static EventListenerTouchOneByOne* create(); virtual ~EventListenerTouchOneByOne(); From fbd04a476ab9e151e13627d6da6f906e5f89d469 Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 15:02:26 +0800 Subject: [PATCH 066/144] issue #3069: Updating comments in CCEventListenerCustom.h. --- cocos/2d/CCEventListenerCustom.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cocos/2d/CCEventListenerCustom.h b/cocos/2d/CCEventListenerCustom.h index eb7e875165..e2e750ce56 100644 --- a/cocos/2d/CCEventListenerCustom.h +++ b/cocos/2d/CCEventListenerCustom.h @@ -33,21 +33,21 @@ class EventCustom; /** * Usage: - * auto dispatcher = EventDispatcher::getInstance(); + * auto dispatcher = Director::getInstance()->getEventDispatcher(); * Adds a listener: * - * auto callback = [](CustomEvent* event){ do_some_thing(); }; - * auto listener = CustomEventListener::create(callback); + * auto callback = [](EventCustom* event){ do_some_thing(); }; + * auto listener = EventListenerCustom::create(callback); * dispatcher->addEventListenerWithSceneGraphPriority(listener, one_node); * * Dispatchs a custom event: * - * Event event("your_event_type"); + * EventCustom event("your_event_type"); * dispatcher->dispatchEvent(&event); * * Removes a listener * - * dispatcher->removeListener(listener); + * dispatcher->removeEventListener(listener); */ class EventListenerCustom : public EventListener { From bb568e84e83d9c3b6cae993db4a8dfe827547417 Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 15:09:13 +0800 Subject: [PATCH 067/144] Updating auto generated binding codes. --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index 2f3c531665..4fd4e14912 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit 2f3c5316657e64ec38b8ed3ea6826eb48c46f32c +Subproject commit 4fd4e14912165a2c8a5a6faacda2626035af6f36 From 91932ea9063b56c295edfac9c486d55aed726a4b Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 15:36:43 +0800 Subject: [PATCH 068/144] issue #3069: Fixing compilation errors. --- cocos/2d/platform/android/nativeactivity.cpp | 14 ++++++++------ cocos/2d/platform/linux/CCEGLView.cpp | 3 ++- cocos/2d/platform/win32/CCEGLView.cpp | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cocos/2d/platform/android/nativeactivity.cpp b/cocos/2d/platform/android/nativeactivity.cpp index fa4fb434d4..5ac17a5ee5 100644 --- a/cocos/2d/platform/android/nativeactivity.cpp +++ b/cocos/2d/platform/android/nativeactivity.cpp @@ -422,18 +422,20 @@ static int32_t handle_key_input(AInputEvent *event) { if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) { + auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher(); + switch (AKeyEvent_getKeyCode(event)) { case AKEYCODE_BACK: { cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE, false); - cocos2d::EventDispatcher::getInstance()->dispatchEvent(&event); + dispatcher->dispatchEvent(&event); } return 1; case AKEYCODE_MENU: { cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_MENU, false); - cocos2d::EventDispatcher::getInstance()->dispatchEvent(&event); + dispatcher->dispatchEvent(&event); } return 1; default: @@ -629,8 +631,8 @@ void android_main(struct android_app* state) { acc.z = event.acceleration.z/10; acc.timestamp = 0; cocos2d::EventAcceleration accEvent(acc); - - cocos2d::EventDispatcher::getInstance()->dispatchEvent(&accEvent); + auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&accEvent); } else { // ACONFIGURATION_ORIENTATION_LAND // swap x and y parameters @@ -640,8 +642,8 @@ void android_main(struct android_app* state) { acc.z = event.acceleration.z/10; acc.timestamp = 0; cocos2d::EventAcceleration accEvent(acc); - - cocos2d::EventDispatcher::getInstance()->dispatchEvent(&accEvent); + auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&accEvent); } } } diff --git a/cocos/2d/platform/linux/CCEGLView.cpp b/cocos/2d/platform/linux/CCEGLView.cpp index 561fedcca8..172c9d796a 100644 --- a/cocos/2d/platform/linux/CCEGLView.cpp +++ b/cocos/2d/platform/linux/CCEGLView.cpp @@ -223,7 +223,8 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); - EventDispatcher::getInstance()->dispatchEvent(&event); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWCharCallback(GLFWwindow *window, unsigned int character) diff --git a/cocos/2d/platform/win32/CCEGLView.cpp b/cocos/2d/platform/win32/CCEGLView.cpp index d5b2ba0202..92bfbe5cf1 100644 --- a/cocos/2d/platform/win32/CCEGLView.cpp +++ b/cocos/2d/platform/win32/CCEGLView.cpp @@ -341,7 +341,8 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); - EventDispatcher::getInstance()->dispatchEvent(&event); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&event); } void EGLViewEventHandler::OnGLFWCharCallback(GLFWwindow *window, unsigned int character) From e2ce7144636ca0b7430dfa01fca302f2bd04a8a2 Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 16:20:42 +0800 Subject: [PATCH 069/144] issue #3069: Update device.mm for iOS. --- cocos/2d/platform/ios/CCDevice.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cocos/2d/platform/ios/CCDevice.mm b/cocos/2d/platform/ios/CCDevice.mm index fdc9448849..efc42c8788 100644 --- a/cocos/2d/platform/ios/CCDevice.mm +++ b/cocos/2d/platform/ios/CCDevice.mm @@ -100,7 +100,8 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher; } cocos2d::EventAcceleration event(*_acceleration); - cocos2d::_eventDispatcherdispatchEvent(&event); + auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher(); + dispatcher->dispatchEvent(&event); } @end From 5c8424423e3f55f28ce5ee5b34e0ba00abfc208f Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 29 Oct 2013 16:29:29 +0800 Subject: [PATCH 070/144] issue #3069: Update ios/CCDevice.mm. --- cocos/2d/platform/ios/CCDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/platform/ios/CCDevice.mm b/cocos/2d/platform/ios/CCDevice.mm index efc42c8788..4555b14df2 100644 --- a/cocos/2d/platform/ios/CCDevice.mm +++ b/cocos/2d/platform/ios/CCDevice.mm @@ -2,7 +2,7 @@ #include "ccTypes.h" #include "CCEventDispatcher.h" #include "CCEventAcceleration.h" - +#include "CCDirector.h" #import // Accelerometer From 70082ddc297d69beb33333c130dfbaaa784759c3 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 17:54:35 +0800 Subject: [PATCH 071/144] issue #3409:Add XMLHttpRequest lua binding and corresponding test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/network/HttpRequest.h | 5 +- cocos/scripting/lua/bindings/Android.mk | 1 + cocos/scripting/lua/bindings/Makefile | 3 +- cocos/scripting/lua/bindings/liblua.vcxproj | 2 + .../lua/bindings/liblua.vcxproj.filters | 6 +++ samples/Lua/TestLua/proj.android/.project | 52 ++----------------- .../TestLua/proj.android/project.properties | 2 +- .../TestLua/proj.win32/TestLua.win32.vcxproj | 2 +- 9 files changed, 22 insertions(+), 53 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 17e0cee1da..e5e294b55f 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b695026fc3d856d540590ff09112696f66379c22 \ No newline at end of file +51e880f9a11e50fd1bd14a92c4bcf1004dfbc12b \ No newline at end of file diff --git a/cocos/network/HttpRequest.h b/cocos/network/HttpRequest.h index 81715d7991..141b55df29 100644 --- a/cocos/network/HttpRequest.h +++ b/cocos/network/HttpRequest.h @@ -123,7 +123,10 @@ public: /** Get the request data pointer back */ inline char* getRequestData() { - return &(_requestData.front()); + if(_requestData.size() != 0) + return &(_requestData.front()); + + return nullptr; } /** Get the size of request data back */ inline int getRequestDataSize() diff --git a/cocos/scripting/lua/bindings/Android.mk b/cocos/scripting/lua/bindings/Android.mk index a5293f66a2..b39ee5f6a5 100644 --- a/cocos/scripting/lua/bindings/Android.mk +++ b/cocos/scripting/lua/bindings/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES := CCLuaBridge.cpp \ lua_cocos2dx_manual.cpp \ lua_cocos2dx_extension_manual.cpp \ lua_cocos2dx_deprecated.cpp \ + lua_xml_http_request.cpp \ platform/android/CCLuaJavaBridge.cpp \ platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge.cpp \ ../../../../external/lua/tolua/tolua_event.c \ diff --git a/cocos/scripting/lua/bindings/Makefile b/cocos/scripting/lua/bindings/Makefile index 95145d5fbc..c797ce3b9e 100644 --- a/cocos/scripting/lua/bindings/Makefile +++ b/cocos/scripting/lua/bindings/Makefile @@ -60,7 +60,8 @@ SOURCES = ../../../../external/lua/lua/lapi.c \ LuaBasicConversions.cpp \ lua_cocos2dx_manual.cpp \ lua_cocos2dx_extension_manual.cpp \ - lua_cocos2dx_deprecated.cpp + lua_cocos2dx_deprecated.cpp \ + lua_xml_http_request.cpp include ../../../2d/cocos2dx.mk diff --git a/cocos/scripting/lua/bindings/liblua.vcxproj b/cocos/scripting/lua/bindings/liblua.vcxproj index ed1ef534ed..1f6f39d5c8 100644 --- a/cocos/scripting/lua/bindings/liblua.vcxproj +++ b/cocos/scripting/lua/bindings/liblua.vcxproj @@ -144,6 +144,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\lua\luajit\prebuilt\win32\*.*" "$ + @@ -168,6 +169,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\lua\luajit\prebuilt\win32\*.*" "$ + diff --git a/cocos/scripting/lua/bindings/liblua.vcxproj.filters b/cocos/scripting/lua/bindings/liblua.vcxproj.filters index 56f49872c4..d323cdf804 100644 --- a/cocos/scripting/lua/bindings/liblua.vcxproj.filters +++ b/cocos/scripting/lua/bindings/liblua.vcxproj.filters @@ -81,6 +81,9 @@ cocos2dx_support + + cocos2dx_support + @@ -149,6 +152,9 @@ cocos2dx_support + + cocos2dx_support + diff --git a/samples/Lua/TestLua/proj.android/.project b/samples/Lua/TestLua/proj.android/.project index 3c1261c623..8703060095 100644 --- a/samples/Lua/TestLua/proj.android/.project +++ b/samples/Lua/TestLua/proj.android/.project @@ -6,56 +6,12 @@ - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, - ?name? - - - - org.eclipse.cdt.make.core.append_environment - true - - - org.eclipse.cdt.make.core.buildArguments - ${ProjDirPath}/build_native.sh - - - org.eclipse.cdt.make.core.buildCommand - bash - - - org.eclipse.cdt.make.core.buildLocation - ${ProjDirPath} - - - org.eclipse.cdt.make.core.cleanBuildTarget - clean - - - org.eclipse.cdt.make.core.contents - org.eclipse.cdt.make.core.activeConfigSettings - - - org.eclipse.cdt.make.core.enableAutoBuild - false - - - org.eclipse.cdt.make.core.enableCleanBuild - true - - - org.eclipse.cdt.make.core.enableFullBuild - true - - - org.eclipse.cdt.make.core.stopOnError - true - - - org.eclipse.cdt.make.core.useDefaultBuildCmd - false + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch diff --git a/samples/Lua/TestLua/proj.android/project.properties b/samples/Lua/TestLua/proj.android/project.properties index 0a6dc6664d..94dd07f59d 100644 --- a/samples/Lua/TestLua/proj.android/project.properties +++ b/samples/Lua/TestLua/proj.android/project.properties @@ -8,6 +8,6 @@ # project structure. # Project target. -target=android-10 +target=android-15 android.library.reference.1=../../../../cocos/2d/platform/android/java diff --git a/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj b/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj index 0a4ea9edbd..f70904ac2f 100644 --- a/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj +++ b/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj @@ -84,7 +84,7 @@ MachineX86 true $(OutDir);%(AdditionalLibraryDirectories) - lua51.lib;websockets.lib;%(AdditionalDependencies) + libcurl_imp.lib;lua51.lib;websockets.lib;%(AdditionalDependencies) 0x0409 From 663b27d1e76afc89a92ef0b04991430f22c40618 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 18:06:02 +0800 Subject: [PATCH 072/144] #3049:Add XMLHttpRequest lua binding and corresponding test sample --- cocos/network/HttpRequest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/network/HttpRequest.h b/cocos/network/HttpRequest.h index 141b55df29..4282193043 100644 --- a/cocos/network/HttpRequest.h +++ b/cocos/network/HttpRequest.h @@ -123,8 +123,8 @@ public: /** Get the request data pointer back */ inline char* getRequestData() { - if(_requestData.size() != 0) - return &(_requestData.front()); + if(_requestData.size() != 0) + return &(_requestData.front()); return nullptr; } From 471bbb8af95e7a2879bcd8dc1f41892927572984 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 18:21:15 +0800 Subject: [PATCH 073/144] issue #3049:Add XMLHttpRequest lua binding and corresponding test sample --- cocos/scripting/lua/bindings/lua_xml_http_request.cpp | 4 ---- samples/Lua/TestLua/proj.android/project.properties | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp index f63e55c0b1..945b36a16a 100644 --- a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp @@ -209,10 +209,6 @@ void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, n /** get the response data **/ std::vector *buffer = response->getResponseData(); -// for (unsigned int i = 0; i < buffer->size(); i++) -// { -// printf("%c", (*buffer)[i]); -// } char* concatenated = (char*) malloc(buffer->size() + 1); std::string s2(buffer->begin(), buffer->end()); strcpy(concatenated, s2.c_str()); diff --git a/samples/Lua/TestLua/proj.android/project.properties b/samples/Lua/TestLua/proj.android/project.properties index 94dd07f59d..0a6dc6664d 100644 --- a/samples/Lua/TestLua/proj.android/project.properties +++ b/samples/Lua/TestLua/proj.android/project.properties @@ -8,6 +8,6 @@ # project structure. # Project target. -target=android-15 +target=android-10 android.library.reference.1=../../../../cocos/2d/platform/android/java From c08a09a7e088eaec7b5dbca85e2ca0349a0f45a8 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Wed, 30 Oct 2013 10:52:04 +0800 Subject: [PATCH 074/144] #3049:Add LICENSE_JSON4LUA and some constant values. --- .gitignore | 2 ++ .../scripting/lua/script/Cocos2dConstants.lua | 8 +++++++ licenses/LICENSE_JSON4Lua.txt | 21 +++++++++++++++++++ .../XMLHttpRequestTest/XMLHttpRequestTest.lua | 8 +++---- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 licenses/LICENSE_JSON4Lua.txt diff --git a/.gitignore b/.gitignore index d6bae12eb7..91ab9c7356 100644 --- a/.gitignore +++ b/.gitignore @@ -22,10 +22,12 @@ Thumbs.db *.log [Bb]in [Dd]ebug/ +[Dd]ebug.win32/ *.sbr *.sdf obj/ [Rr]elease/ +[Rr]elease.win32/ _ReSharper*/ [Tt]est[Rr]esult* ipch/ diff --git a/cocos/scripting/lua/script/Cocos2dConstants.lua b/cocos/scripting/lua/script/Cocos2dConstants.lua index 5a8ae27e94..cc43ce5ee3 100644 --- a/cocos/scripting/lua/script/Cocos2dConstants.lua +++ b/cocos/scripting/lua/script/Cocos2dConstants.lua @@ -272,3 +272,11 @@ cc.WEBSOCKET_STATE_CONNECTING = 0 cc.WEBSOCKET_STATE_OPEN = 1 cc.WEBSOCKET_STATE_CLOSING = 2 cc.WEBSOCKET_STATE_CLOSED = 3 + + +cc.XMLHTTPREQUEST_RESPONSE_STRING = 0 +cc.XMLHTTPREQUEST_RESPONSE_ARRAY_BUFFER = 1 +cc.XMLHTTPREQUEST_RESPONSE_BLOB = 2 +cc.XMLHTTPREQUEST_RESPONSE_DOCUMENT = 3 +cc.XMLHTTPREQUEST_RESPONSE_JSON = 4 + \ No newline at end of file diff --git a/licenses/LICENSE_JSON4Lua.txt b/licenses/LICENSE_JSON4Lua.txt new file mode 100644 index 0000000000..7e0d778e8c --- /dev/null +++ b/licenses/LICENSE_JSON4Lua.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2009 Craig Mason-Jones + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE diff --git a/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua index 2456d5d092..1cdffa035a 100644 --- a/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua +++ b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua @@ -23,7 +23,7 @@ local function XMLHttpRequestLayer() --Get local function onMenuGetClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 0 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_STRING xhr:open("GET", "http://httpbin.org/get") local function onReadyStateChange() @@ -47,7 +47,7 @@ local function XMLHttpRequestLayer() --Post local function onMenuPostClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 0 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_STRING xhr:open("POST", "http://httpbin.org/post") local function onReadyStateChange() labelStatusCode:setString("Http Status Code:"..xhr.statusText) @@ -68,7 +68,7 @@ local function XMLHttpRequestLayer() --Post Binary local function onMenuPostBinaryClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 1 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_ARRAY_BUFFER xhr:open("POST", "http://httpbin.org/post") local function onReadyStateChange() @@ -103,7 +103,7 @@ local function XMLHttpRequestLayer() local function onMenuPostJsonClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 4 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_JSON xhr:open("POST", "http://httpbin.org/post") local function onReadyStateChange() From 4d9b05a67d643088bdddd35132f1a5c006e5b506 Mon Sep 17 00:00:00 2001 From: minggo Date: Wed, 30 Oct 2013 14:19:07 +0800 Subject: [PATCH 075/144] add script to build android samples --- build/android-build.py | 153 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 build/android-build.py diff --git a/build/android-build.py b/build/android-build.py new file mode 100755 index 0000000000..d5f8144ffe --- /dev/null +++ b/build/android-build.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +# android-build.py +# Build android samples + +# You can use + + +# begin +import sys +import os, os.path +from optparse import OptionParser + +CPP_SAMPLES = ['hellocpp', 'testcpp', 'simplegame', 'assetsmanager'] +LUA_SAMPLES = ['hellolua', 'testlua'] +JSB_SAMPLES = ['cocosdragon', 'crystalcraze', 'moonwarriors', 'testjavascript', 'watermelonwithme'] +ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JSB_SAMPLES + + +def usage(): + + print "%prog [-n ndk-build-parameter] target\n\ + valid target are [hellocpp|testcpp|simplegame|assetsmanager|hellolua|testlua|cocosdragon\ +|crystalcraze|moonwarriors|testjavascript|watermelonwithme], of course you can use 'cpp'\ +to build all cpp samples, 'lua' to build all lua samples, 'jsb' to build all javascript samples,\ + and 'all' for all samples" + +def check_environment_variables(): + ''' Checking the environment NDK_ROOT, which will be used for building + ''' + + try: + NDK_ROOT = os.environ['NDK_ROOT'] + except Exception: + print "NDK_ROOT not defined. Please define NDK_ROOT in your environment" + sys.exit(1) + + return NDK_ROOT + +def select_toolchain_version(): + '''Because ndk-r8e uses gcc4.6 as default. gcc4.6 doesn't support c++11. So we should select gcc4.7 when + using ndk-r8e. But gcc4.7 is removed in ndk-r9, so we should determine whether gcc4.7 exist. + Conclution: + ndk-r8e -> use gcc4.7 + ndk-r9 -> use gcc4.8 + ''' + + ndk_root = check_environment_variables() + if os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.8")): + os.environ['NDK_TOOLCHAIN_VERSION'] = '4.8' + print "The Selected NDK toolchain version was 4.8 !" + elif os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.7")): + os.environ['NDK_TOOLCHAIN_VERSION'] = '4.7' + print "The Selected NDK toolchain version was 4.7 !" + else: + print "Couldn't find the gcc toolchain." + exit(1) + +def caculate_built_samples(args): + ''' Compute the sampels to be built + 'cpp' for short of all cpp samples + 'lua' for short of all lua smpleas + 'jsb' for short of all javascript samples + ''' + + if 'all' == args: + return ALL_SAMPLES + + targets = [] + if 'cpp' in args: + targets += CPP_SAMPLES + args.remove('cpp') + if 'lua' in args: + targets += LUA_SAMPLES + args.remove('lua') + if 'jsb' in args: + targets += JSB_SAMPLES + args.remove('jsb') + + targets += args + + # remove duplicate elements, for example + # python android-build.py cpp hellocpp + targets = set(targets) + return list(targets) + +def do_build(cocos_root, ndk_root, app_android_root, ndk_build_param): + + ndk_path = os.path.join(ndk_root, "ndk-build") + + # windows should use ";" to seperate module paths + platform = sys.platform + if platform == 'win32': + ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos' % (cocos_root, cocos_root, cocos_root) + else: + ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root) + + if ndk_build_param == None: + command = '%s -C %s %s' % (ndk_path, app_android_root, ndk_module_path) + else: + command = '%s -C %s %s %s' % (ndk_path, app_android_root, ndk_build_param, ndk_module_path) + os.system(command) + +def build_samples(target,ndk_build_param): + + ndk_root = check_environment_variables() + select_toolchain_version() + build_targets = caculate_built_samples(target) + + current_dir = os.getcwd() + cocos_root = os.path.join(current_dir, "..") + + app_android_root = '' + for target in build_targets: + if target == 'hellocpp': + app_android_root = os.path.join(cocos_root, 'samples/Cpp/HelloCpp/proj.android') + elif target == 'testcpp': + app_android_root = os.path.join(cocos_root, 'samples/Cpp/TestCpp/proj.android') + elif target == 'simplegame': + app_android_root = os.path.join(cocos_root, 'samples/Cpp/SimpleGame/proj.android') + elif target == 'assetsmanager': + app_android_root = os.path.join(cocos_root, 'samples/Cpp/AssetsManager/proj.android') + elif target == 'hellolua': + app_android_root = os.path.join(cocos_root, 'samples/Lua/HelloLua/proj.android') + elif target == 'testlua': + app_android_root = os.path.join(cocos_root, 'samples/Lua/TestLua/proj.android') + elif target == 'cocosdragon': + app_android_root = os.path.join(cocos_root, 'samples/JavaScript/CocosDragonJS/proj.android') + elif target == 'crystalcraze': + app_android_root = os.path.join(cocos_root, 'samples/JavaScript/CrystalCraze/proj.android') + elif target == 'moonwarriors': + app_android_root = os.path.join(cocos_root, 'samples/JavaScript/MoonWarriors/proj.android') + elif target == 'testjavascript': + app_android_root = os.path.join(cocos_root, 'samples/JavaScript/TestJavascript/proj.android') + elif target == 'watermelonwithme': + app_android_root = os.path.join(cocos_root, 'samples/JavaScript/WatermelonWithMe/proj.android') + else: + print 'unknown target %s, pass it', target + continue + + do_build(cocos_root, ndk_root, app_android_root, ndk_build_param) + +# -------------- main -------------- +if __name__ == '__main__': + + #parse the params + parser = OptionParser() + parser.add_option("-n", "--ndk", dest="ndk_build_param", help='parameter for ndk-build') + (opts, args) = parser.parse_args() + + if len(args) == 0: + usage() + else: + build_samples(args, opts.ndk_build_param) From da9f7c912b561f4783f557e063239d885689d4e5 Mon Sep 17 00:00:00 2001 From: minggo Date: Wed, 30 Oct 2013 18:27:56 +0800 Subject: [PATCH 076/144] use build/android-build to build android samples, and update readme --- README.md | 22 ++- build/android-build.py | 61 +++++++- .../proj.android/build_native.cmd | 87 ----------- .../proj.android/build_native.sh | 123 --------------- .../HelloCpp/proj.android/build_native.cmd | 83 ---------- .../Cpp/HelloCpp/proj.android/build_native.sh | 107 ------------- .../SimpleGame/proj.android/build_native.cmd | 83 ---------- .../SimpleGame/proj.android/build_native.sh | 107 ------------- .../Cpp/TestCpp/proj.android/build_native.cmd | 90 ----------- .../Cpp/TestCpp/proj.android/build_native.sh | 98 ------------ .../proj.android/build_native.cmd | 90 ----------- .../proj.android/build_native.sh | 114 -------------- .../proj.android/build_native.cmd | 90 ----------- .../CrystalCraze/proj.android/build_native.sh | 115 -------------- .../proj.android/build_native.cmd | 96 ------------ .../MoonWarriors/proj.android/build_native.sh | 117 -------------- .../proj.android/build_native.cmd | 90 ----------- .../proj.android/build_native.sh | 114 -------------- .../proj.android/build_native.cmd | 90 ----------- .../proj.android/build_native.sh | 113 -------------- .../HelloLua/proj.android/build_native.cmd | 86 ----------- .../Lua/HelloLua/proj.android/build_native.sh | 116 -------------- .../Lua/TestLua/proj.android/build_native.cmd | 93 ------------ .../Lua/TestLua/proj.android/build_native.sh | 143 ------------------ 24 files changed, 69 insertions(+), 2259 deletions(-) delete mode 100644 samples/Cpp/AssetsManagerTest/proj.android/build_native.cmd delete mode 100755 samples/Cpp/AssetsManagerTest/proj.android/build_native.sh delete mode 100644 samples/Cpp/HelloCpp/proj.android/build_native.cmd delete mode 100755 samples/Cpp/HelloCpp/proj.android/build_native.sh delete mode 100644 samples/Cpp/SimpleGame/proj.android/build_native.cmd delete mode 100755 samples/Cpp/SimpleGame/proj.android/build_native.sh delete mode 100644 samples/Cpp/TestCpp/proj.android/build_native.cmd delete mode 100755 samples/Cpp/TestCpp/proj.android/build_native.sh delete mode 100644 samples/Javascript/CocosDragonJS/proj.android/build_native.cmd delete mode 100755 samples/Javascript/CocosDragonJS/proj.android/build_native.sh delete mode 100644 samples/Javascript/CrystalCraze/proj.android/build_native.cmd delete mode 100755 samples/Javascript/CrystalCraze/proj.android/build_native.sh delete mode 100644 samples/Javascript/MoonWarriors/proj.android/build_native.cmd delete mode 100755 samples/Javascript/MoonWarriors/proj.android/build_native.sh delete mode 100644 samples/Javascript/TestJavascript/proj.android/build_native.cmd delete mode 100755 samples/Javascript/TestJavascript/proj.android/build_native.sh delete mode 100644 samples/Javascript/WatermelonWithMe/proj.android/build_native.cmd delete mode 100755 samples/Javascript/WatermelonWithMe/proj.android/build_native.sh delete mode 100644 samples/Lua/HelloLua/proj.android/build_native.cmd delete mode 100755 samples/Lua/HelloLua/proj.android/build_native.sh delete mode 100644 samples/Lua/TestLua/proj.android/build_native.cmd delete mode 100755 samples/Lua/TestLua/proj.android/build_native.sh diff --git a/README.md b/README.md index 39e47ca9ad..217779827f 100644 --- a/README.md +++ b/README.md @@ -23,14 +23,15 @@ How to start a new game ----------------------- 1. Download the code from [cocos2d download site][4] +2. Enter `tools/project-creator` -2. Run the `create-multi-platform-projects.py` script +2. Run the `create-projects.py` script Example: - $ cd cocos2d-x + $ cd cocos2d-x/tools/project-creator $ ./create-multi-platform-projects.py -p mygame -k com.your_company.mygame -l cpp - $ cd projects/mygame + $ cd ../../projects/mygame Main features @@ -79,9 +80,6 @@ Runtime Requirements * Android 2.3+ for Android games * OS X v10.6+ for Mac games * Windows 7+ for Win games - * Tizen 2.2+ - * Emscripten - * Google Native Client Running Tests @@ -92,28 +90,26 @@ Select the test you want from Xcode Scheme chooser. * For OS X / iOS ``` -$ cd cocos2d-x/samples +$ cd cocos2d-x/build $ open samples.xcodeproj ``` * For Linux ``` -$ cd cocos2d-x +$ cd cocos2d-x/build $ ./make-all-linux-projects.sh ``` -or open the `cocos2d-x/cocos2dx-qt5.pro` file using QT Creator 5. - * For Windows -Open the `cocos2d-x/cocos2d-win32.vc2012.sln` +Open the `cocos2d-x/build/cocos2d-win32.vc2012.sln` * For Android ``` -$ cd cocos2d-x/samples/Cpp/HelloCpp/proj.android -$ ./build_native.sh +$ cd cocos2d-x/build +$ python ./android-build.py hellocpp ``` Import HelloCpp Android project using Eclipse(released with Android SDK). The path to be imported is `cocos2d-x/samples/Cpp/HelloCpp/proj.android`. diff --git a/build/android-build.py b/build/android-build.py index d5f8144ffe..62bc226e77 100755 --- a/build/android-build.py +++ b/build/android-build.py @@ -8,6 +8,7 @@ # begin import sys import os, os.path +import shutil from optparse import OptionParser CPP_SAMPLES = ['hellocpp', 'testcpp', 'simplegame', 'assetsmanager'] @@ -62,7 +63,7 @@ def caculate_built_samples(args): 'jsb' for short of all javascript samples ''' - if 'all' == args: + if 'all' in args: return ALL_SAMPLES targets = [] @@ -100,6 +101,63 @@ def do_build(cocos_root, ndk_root, app_android_root, ndk_build_param): command = '%s -C %s %s %s' % (ndk_path, app_android_root, ndk_build_param, ndk_module_path) os.system(command) +def copy_files(src, dst): + + for item in os.listdir(src): + path = os.path.join(src, item) + # Android can not package the file that ends with ".gz" + if not item.startswith('.') and not item.endswith('.gz') and os.path.isfile(path): + shutil.copy(path, dst) + if os.path.isdir(path): + new_dst = os.path.join(dst, item) + os.mkdir(new_dst) + copy_files(path, new_dst) + +def copy_resources(target, app_android_root): + + # remove app_android_root/assets if it exists + assets_dir = os.path.join(app_android_root, "assets") + if os.path.isdir(assets_dir): + shutil.rmtree(assets_dir) + + # copy resources(cpp samples and lua samples) + os.mkdir(assets_dir) + resources_dir = os.path.join(app_android_root, "../Resources") + if os.path.isdir(resources_dir): + copy_files(resources_dir, assets_dir) + + # jsb samples should copy javascript files and resources(shared with cocos2d-html5) + if target in JSB_SAMPLES or target == "assetsmanager": + resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/javascript/script") + copy_files(resources_dir, assets_dir) + + if target == "cocosdragon": + resources_dir = os.path.join(app_android_root, "../../Shared/games/CocosDragonJS/Published files Android") + if target == "crystalcraze": + resources_dir = os.path.join(app_android_root, "../../Shared/games/CrystalCraze/Published-Android") + if target == "moonwarriors": + resources_dir = os.path.join(app_android_root, "../../Shared/games/MoonWarriors/res") + if target == "testjavascript": + resources_dir = os.path.join(app_android_root, "../../Shared/tests/") + if target == "watermelonwithme": + resources_dir = os.path.join(app_android_root, "../../Shared/games/WatermelonWithMe") + copy_files(resources_dir, assets_dir) + + # AssetsManager test should also copy javascript files + if target == "assetsmanager": + resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/javascript/script") + copy_files(resources_dir, assets_dir) + + # lua samples should copy lua script + if target in LUA_SAMPLES: + resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/lua/script") + copy_files(resources_dir, assets_dir) + + # TestLua shared resources with TestCpp + if target == "testlua": + resources_dir = os.path.join(app_android_root, "../../../Cpp/TestCpp/Resources") + copy_files(resources_dir, assets_dir) + def build_samples(target,ndk_build_param): ndk_root = check_environment_variables() @@ -137,6 +195,7 @@ def build_samples(target,ndk_build_param): print 'unknown target %s, pass it', target continue + copy_resources(target, app_android_root) do_build(cocos_root, ndk_root, app_android_root, ndk_build_param) # -------------- main -------------- diff --git a/samples/Cpp/AssetsManagerTest/proj.android/build_native.cmd b/samples/Cpp/AssetsManagerTest/proj.android/build_native.cmd deleted file mode 100644 index d397bbc901..0000000000 --- a/samples/Cpp/AssetsManagerTest/proj.android/build_native.cmd +++ /dev/null @@ -1,87 +0,0 @@ -@echo off - -set APPNAME="AssetsManager" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 -set BINDINGS_JS_ROOT=%COCOS2DX_ROOT%\cocos\scripting\javascript\script - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\Resources\* %APP_ANDROID_ROOT%\assets - -rem copy bindings/*.js into assets' root -xcopy /e /q /r /y %BINDINGS_JS_ROOT%\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Cpp/AssetsManagerTest/proj.android/build_native.sh b/samples/Cpp/AssetsManagerTest/proj.android/build_native.sh deleted file mode 100755 index 30549e8869..0000000000 --- a/samples/Cpp/AssetsManagerTest/proj.android/build_native.sh +++ /dev/null @@ -1,123 +0,0 @@ -APPNAME="AssetsManager" - -# options - -buildexternalsfromsource= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --h this help -EOF -} - -while getopts "sh" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -h) -usage -exit 0 -;; -esac -done - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" -BINDINGS_JS_ROOT="$APP_ROOT/../../../cocos/scripting/javascript/script" - -echo "NDK_ROOT = $NDK_ROOT" -echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo "APP_ROOT = $APP_ROOT" -echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy resources -for file in "$APP_ROOT"/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -# copy bindings/*.js into assets' root -cp -rf "$BINDINGS_JS_ROOT"/* "$APP_ANDROID_ROOT"/assets - -# copy icons (if they exist) -file="$APP_ANDROID_ROOT"/assets/Icon-72.png -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/res/drawable-hdpi/icon.png -fi -file="$APP_ANDROID_ROOT"/assets/Icon-48.png -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/res/drawable-mdpi/icon.png -fi -file="$APP_ANDROID_ROOT"/assets/Icon-32.png -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/res/drawable-ldpi/icon.png -fi - - -if [[ "$buildexternalsfromsource" ]]; then - echo "Building external dependencies from source" - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source" -else - echo "Using prebuilt externals" - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" -fi diff --git a/samples/Cpp/HelloCpp/proj.android/build_native.cmd b/samples/Cpp/HelloCpp/proj.android/build_native.cmd deleted file mode 100644 index f18ac5f170..0000000000 --- a/samples/Cpp/HelloCpp/proj.android/build_native.cmd +++ /dev/null @@ -1,83 +0,0 @@ -@echo off - -set APPNAME="HelloCpp" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%\external;%COCOS2DX_ROOT%\cocos - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\Resources\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Cpp/HelloCpp/proj.android/build_native.sh b/samples/Cpp/HelloCpp/proj.android/build_native.sh deleted file mode 100755 index cfd49f5d79..0000000000 --- a/samples/Cpp/HelloCpp/proj.android/build_native.sh +++ /dev/null @@ -1,107 +0,0 @@ -APPNAME="HelloCpp" - -# options - -buildexternalsfromsource= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --h this help -EOF -} - -while getopts "sh" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -h) -usage -exit 0 -;; -esac -done - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" - -echo "NDK_ROOT = $NDK_ROOT" -echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo "APP_ROOT = $APP_ROOT" -echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy resources -for file in "$APP_ROOT"/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -if [[ "$buildexternalsfromsource" ]]; then - echo "Building external dependencies from source" - set -x - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos" -else - echo "Using prebuilt externals" - set -x - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos" - -fi diff --git a/samples/Cpp/SimpleGame/proj.android/build_native.cmd b/samples/Cpp/SimpleGame/proj.android/build_native.cmd deleted file mode 100644 index 437e55298f..0000000000 --- a/samples/Cpp/SimpleGame/proj.android/build_native.cmd +++ /dev/null @@ -1,83 +0,0 @@ -@echo off - -set APPNAME="SimpleGame" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\Resources\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Cpp/SimpleGame/proj.android/build_native.sh b/samples/Cpp/SimpleGame/proj.android/build_native.sh deleted file mode 100755 index 8f09b2bb6b..0000000000 --- a/samples/Cpp/SimpleGame/proj.android/build_native.sh +++ /dev/null @@ -1,107 +0,0 @@ -APPNAME="SimpleGame" - -# options - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --h this help -EOF -} - -while getopts "h" OPTION; do -case "$OPTION" in -h) -usage -exit 0 -;; -esac -done - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=$(sed '/\./d' "$_LOCALPROPERTIES_FILE") - for line in $_PROPERTIES; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" - -echo "NDK_ROOT = $NDK_ROOT" -echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo "APP_ROOT = $APP_ROOT" -echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy resources -for file in "$APP_ROOT"/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -# copy icons (if they exist) -file="$APP_ANDROID_ROOT"/assets/Icon-72.png -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/res/drawable-hdpi/icon.png -fi -file="$APP_ANDROID_ROOT"/assets/Icon-48.png -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/res/drawable-mdpi/icon.png -fi -file="$APP_ANDROID_ROOT"/assets/Icon-32.png -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/res/drawable-ldpi/icon.png -fi - -echo "Building in debug" - -"$NDK_ROOT"/ndk-build NDK_DEBUG=1 -C "$APP_ANDROID_ROOT" \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" diff --git a/samples/Cpp/TestCpp/proj.android/build_native.cmd b/samples/Cpp/TestCpp/proj.android/build_native.cmd deleted file mode 100644 index d8eaaea7c7..0000000000 --- a/samples/Cpp/TestCpp/proj.android/build_native.cmd +++ /dev/null @@ -1,90 +0,0 @@ -@echo off - -set APPNAME="TestCpp" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\external;%COCOS2DX_ROOT%\cocos - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\Resources\* %APP_ANDROID_ROOT%\assets - -rem remove test_image_rgba4444.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_image_rgba4444.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_rgba8888.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_rgb888.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_rgba4444.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_a8.pvr.gz - -call %NDK_ROOT%\ndk-build.cmd NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Cpp/TestCpp/proj.android/build_native.sh b/samples/Cpp/TestCpp/proj.android/build_native.sh deleted file mode 100755 index 69464cc437..0000000000 --- a/samples/Cpp/TestCpp/proj.android/build_native.sh +++ /dev/null @@ -1,98 +0,0 @@ -APPNAME="TestCpp" - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --h this help -EOF -} - -while getopts "h" OPTION; do -case "$OPTION" in -h) -usage -exit 0 -;; -esac -done - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=$(sed '/\./d' "$_LOCALPROPERTIES_FILE") - for line in $_PROPERTIES; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" - -echo "NDK_ROOT = $NDK_ROOT" -echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo "APP_ROOT = $APP_ROOT" -echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy resources -for file in "$APP_ROOT"/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -# remove test_image_rgba4444.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_image_rgba4444.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_rgba8888.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_rgb888.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_rgba4444.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_a8.pvr.gz - -echo "Using prebuilt externals" -"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos" diff --git a/samples/Javascript/CocosDragonJS/proj.android/build_native.cmd b/samples/Javascript/CocosDragonJS/proj.android/build_native.cmd deleted file mode 100644 index 76a9a7138f..0000000000 --- a/samples/Javascript/CocosDragonJS/proj.android/build_native.cmd +++ /dev/null @@ -1,90 +0,0 @@ -@echo off - -set APPNAME="CocosDragonJS" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -p Run make with -j8 option to take advantage of multiple processors - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-p" set PARALLEL_BUILD_FLAG=\-j8 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 -set RESROUCE_ROOT="%APP_ROOT%\..\Shared\games\CocosDragonJS\Published files Android" -set BINDINGS_JS_ROOT=%COCOS2DX_ROOT%\cocos\scripting\javascript\script - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %RESROUCE_ROOT%\* %APP_ANDROID_ROOT%\assets - -rem copy bindings/*.js into assets' root -xcopy /e /q /r /y %BINDINGS_JS_ROOT%\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd %PARALLEL_BUILD_FLAG% NDK_LOG=0 V=0 %* -pause diff --git a/samples/Javascript/CocosDragonJS/proj.android/build_native.sh b/samples/Javascript/CocosDragonJS/proj.android/build_native.sh deleted file mode 100755 index 768c2caf04..0000000000 --- a/samples/Javascript/CocosDragonJS/proj.android/build_native.sh +++ /dev/null @@ -1,114 +0,0 @@ -#NDK_ROOT="/opt/android/android-ndk" -APPNAME="CocosDragonJS" - -# options - -buildexternalsfromsource= -PARALLEL_BUILD_FLAG= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --p Run make with -j8 option to take advantage of multiple processors --h this help -EOF -} - -while getopts "sph" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -p) -PARALLEL_BUILD_FLAG=\-j8 -;; -h) -usage -exit 0 -;; -esac -done - -# exit this script if any commmand fails -set -e - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" -RESROUCE_ROOT="$APP_ROOT/../Shared/games/CocosDragonJS/Published files Android" -BINDINGS_JS_ROOT="$APP_ROOT/../../../cocos/scripting/javascript/script" - -echo -echo "Paths" -echo " NDK_ROOT = $NDK_ROOT" -echo " COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo " APP_ROOT = $APP_ROOT" -echo " APP_ANDROID_ROOT = $APP_ANDROID_ROOT" -echo - -# Debug -set -x - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy "Resources" into "assets" -cp -rf "$RESROUCE_ROOT"/* "$APP_ANDROID_ROOT"/assets - -# copy bindings/*.js into assets' root -cp -rf "$BINDINGS_JS_ROOT"/* "$APP_ANDROID_ROOT"/assets - -echo "Using prebuilt externals" -echo - -set -x - -"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" \ - NDK_LOG=0 V=0 diff --git a/samples/Javascript/CrystalCraze/proj.android/build_native.cmd b/samples/Javascript/CrystalCraze/proj.android/build_native.cmd deleted file mode 100644 index 22f5ad4442..0000000000 --- a/samples/Javascript/CrystalCraze/proj.android/build_native.cmd +++ /dev/null @@ -1,90 +0,0 @@ -@echo off - -set APPNAME="CrystalCraze" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -p Run make with -j8 option to take advantage of multiple processors - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-p" set PARALLEL_BUILD_FLAG=\-j8 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 -set RESROUCE_ROOT="%APP_ROOT%\..\Shared\games\CrystalCraze\Published-Android" -set BINDINGS_JS_ROOT=%COCOS2DX_ROOT%\cocos\scripting\javascript\script - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %RESROUCE_ROOT%\* %APP_ANDROID_ROOT%\assets - -rem copy bindings/*.js into assets' root -xcopy /e /q /r /y %BINDINGS_JS_ROOT%\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd %PARALLEL_BUILD_FLAG% NDK_LOG=0 V=0 %* -pause diff --git a/samples/Javascript/CrystalCraze/proj.android/build_native.sh b/samples/Javascript/CrystalCraze/proj.android/build_native.sh deleted file mode 100755 index 102eefa80f..0000000000 --- a/samples/Javascript/CrystalCraze/proj.android/build_native.sh +++ /dev/null @@ -1,115 +0,0 @@ -#NDK_ROOT="/opt/android/android-ndk" -APPNAME="CrystalCraze" - -# options - -buildexternalsfromsource= -PARALLEL_BUILD_FLAG= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --p Run make with -j8 option to take advantage of multiple processors --h this help -EOF -} - -while getopts "sph" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -p) -PARALLEL_BUILD_FLAG=\-j8 -;; -h) -usage -exit 0 -;; -esac -done - -# exit this script if any commmand fails -set -e - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" -RESROUCE_ROOT="$APP_ROOT/../Shared/games/CrystalCraze/Published-Android" -BINDINGS_JS_ROOT="$APP_ROOT/../../../cocos/scripting/javascript/script" - -echo -echo "Paths" -echo " NDK_ROOT = $NDK_ROOT" -echo " COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo " APP_ROOT = $APP_ROOT" -echo " APP_ANDROID_ROOT = $APP_ANDROID_ROOT" -echo - -# Debug -set -x - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy "Resources" into "assets" -cp -rf "$RESROUCE_ROOT"/* "$APP_ANDROID_ROOT"/assets - -# copy bindings/*.js into assets' root -cp -rf "$BINDINGS_JS_ROOT"/* "$APP_ANDROID_ROOT"/assets - - -echo "Using prebuilt externals" -echo - -set -x - -"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" \ - NDK_LOG=0 V=0 diff --git a/samples/Javascript/MoonWarriors/proj.android/build_native.cmd b/samples/Javascript/MoonWarriors/proj.android/build_native.cmd deleted file mode 100644 index e2c1c82c7e..0000000000 --- a/samples/Javascript/MoonWarriors/proj.android/build_native.cmd +++ /dev/null @@ -1,96 +0,0 @@ -@echo off - -set APPNAME="MoonWarriors" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -p Run make with -j8 option to take advantage of multiple processors - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-p" set PARALLEL_BUILD_FLAG=\-j8 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 -set RESROUCE_ROOT="%APP_ROOT%\..\Shared\games\MoonWarriors\res" -set BINDINGS_JS_ROOT=%COCOS2DX_ROOT%\cocos\scripting\javascript\script - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %RESROUCE_ROOT%\* %APP_ANDROID_ROOT%\assets - -rem copy MoonWarriors js -xcopy /e /q /r /y %RESROUCE_ROOT%\..\src %APP_ANDROID_ROOT%\assets - -rem copy MoonWarriors-native.js -xcopy /e /q /r /y %RESROUCE_ROOT%\..\* %APP_ANDROID_ROOT%\assets - -rem copy bindings/*.js into assets' root -xcopy /e /q /r /y %BINDINGS_JS_ROOT%\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd %PARALLEL_BUILD_FLAG% NDK_LOG=0 V=0 %* -pause diff --git a/samples/Javascript/MoonWarriors/proj.android/build_native.sh b/samples/Javascript/MoonWarriors/proj.android/build_native.sh deleted file mode 100755 index e97488b40c..0000000000 --- a/samples/Javascript/MoonWarriors/proj.android/build_native.sh +++ /dev/null @@ -1,117 +0,0 @@ -APPNAME="MoonWarriors" - -# options - -buildexternalsfromsource= -PARALLEL_BUILD_FLAG= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --p Run make with -j8 option to take advantage of multiple processors --h this help -EOF -} - -while getopts "sph" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -p) -PARALLEL_BUILD_FLAG=\-j8 -;; -h) -usage -exit 0 -;; -esac -done - -# exit this script if any commmand fails -set -e - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" -RESROUCE_ROOT="$APP_ROOT/../Shared/games/MoonWarriors/res" -BINDINGS_JS_ROOT="$APP_ROOT/../../../cocos/scripting/javascript/script" - -echo -echo "Paths" -echo " NDK_ROOT = $NDK_ROOT" -echo " COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo " APP_ROOT = $APP_ROOT" -echo " APP_ANDROID_ROOT = $APP_ANDROID_ROOT" -echo - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - - -# copy "Resources" into "assets" -cp -rf "$RESROUCE_ROOT" "$APP_ANDROID_ROOT"/assets - -# copy MoonWarriors js -cp -rf "$RESROUCE_ROOT"/../src "$APP_ANDROID_ROOT"/assets -# copy MoonWarriors-native.js -cp "$RESROUCE_ROOT"/../*.js "$APP_ANDROID_ROOT"/assets - -# copy bindings/*.js into assets' root -cp -rf "$BINDINGS_JS_ROOT"/* "$APP_ANDROID_ROOT"/assets - - -echo "Using prebuilt externals" -echo - -set -x - -"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" \ - NDK_LOG=1 V=1 diff --git a/samples/Javascript/TestJavascript/proj.android/build_native.cmd b/samples/Javascript/TestJavascript/proj.android/build_native.cmd deleted file mode 100644 index a0a5ec0785..0000000000 --- a/samples/Javascript/TestJavascript/proj.android/build_native.cmd +++ /dev/null @@ -1,90 +0,0 @@ -@echo off - -set APPNAME="TestJavascript" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -p Run make with -j8 option to take advantage of multiple processors - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-p" set PARALLEL_BUILD_FLAG=\-j8 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 -set BINDINGS_JS_ROOT=%COCOS2DX_ROOT%\cocos\scripting\javascript\script - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets -mkdir %APP_ANDROID_ROOT%\assets\res - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\..\Shared\tests\* %APP_ANDROID_ROOT%\assets - -rem copy bindings/*.js into assets' root -xcopy /e /q /r /y %BINDINGS_JS_ROOT%\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd %PARALLEL_BUILD_FLAG% NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Javascript/TestJavascript/proj.android/build_native.sh b/samples/Javascript/TestJavascript/proj.android/build_native.sh deleted file mode 100755 index 3378f4006a..0000000000 --- a/samples/Javascript/TestJavascript/proj.android/build_native.sh +++ /dev/null @@ -1,114 +0,0 @@ -APPNAME="TestJavascript" - -# options - -buildexternalsfromsource= -PARALLEL_BUILD_FLAG= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --p Run make with -j8 option to take advantage of multiple processors --h this help -EOF -} - -while getopts "sph" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -p) -PARALLEL_BUILD_FLAG=\-j8 -;; -h) -usage -exit 0 -;; -esac -done - -# exit this script if any commmand fails -set -e - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" -BINDINGS_JS_ROOT="$APP_ROOT/../../../cocos/scripting/javascript/script" - -echo -echo "Paths" -echo " NDK_ROOT = $NDK_ROOT" -echo " COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo " APP_ROOT = $APP_ROOT" -echo " APP_ANDROID_ROOT = $APP_ANDROID_ROOT" -echo - -# Debug -set -x - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets -mkdir "$APP_ANDROID_ROOT"/assets/res - -# copy src/**/*.js from cocos2d-js-tests into assets' root -cp -rf "$APP_ROOT"/../Shared/tests/* "$APP_ANDROID_ROOT"/assets - - -# copy bindings/*.js into assets' root -cp -rf "$BINDINGS_JS_ROOT"/* "$APP_ANDROID_ROOT"/assets - -echo "Using prebuilt externals" -echo - -set -x - -"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" \ - NDK_LOG=0 V=0 diff --git a/samples/Javascript/WatermelonWithMe/proj.android/build_native.cmd b/samples/Javascript/WatermelonWithMe/proj.android/build_native.cmd deleted file mode 100644 index a592025ff0..0000000000 --- a/samples/Javascript/WatermelonWithMe/proj.android/build_native.cmd +++ /dev/null @@ -1,90 +0,0 @@ -@echo off - -set APPNAME="WatermelonWithMe" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -p Run make with -j8 option to take advantage of multiple processors - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-p" set PARALLEL_BUILD_FLAG=\-j8 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 -set RESROUCE_ROOT="%APP_ROOT%\..\Shared\games\WatermelonWithMe" -set BINDINGS_JS_ROOT=%COCOS2DX_ROOT%\cocos\scripting\javascript\script - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %RESROUCE_ROOT%\* %APP_ANDROID_ROOT%\assets - -rem copy bindings/*.js into assets' root -xcopy /e /q /r /y %BINDINGS_JS_ROOT%\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd %PARALLEL_BUILD_FLAG% NDK_LOG=0 V=0 %* -pause diff --git a/samples/Javascript/WatermelonWithMe/proj.android/build_native.sh b/samples/Javascript/WatermelonWithMe/proj.android/build_native.sh deleted file mode 100755 index e976f1c2b2..0000000000 --- a/samples/Javascript/WatermelonWithMe/proj.android/build_native.sh +++ /dev/null @@ -1,113 +0,0 @@ -APPNAME="TestJavascript" - -# options - -buildexternalsfromsource= -PARALLEL_BUILD_FLAG= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --p Run make with -j8 option to take advantage of multiple processors --h this help -EOF -} - -while getopts "sph" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -p) -PARALLEL_BUILD_FLAG=\-j8 -;; -h) -usage -exit 0 -;; -esac -done - -# exit this script if any commmand fails -set -e - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" -RESROUCE_ROOT="$APP_ROOT/../Shared/games/WatermelonWithMe" -BINDINGS_JS_ROOT="$APP_ROOT/../../../cocos/scripting/javascript/script" - -echo -echo "Paths" -echo " NDK_ROOT = $NDK_ROOT" -echo " COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo " APP_ROOT = $APP_ROOT" -echo " APP_ANDROID_ROOT = $APP_ANDROID_ROOT" -echo - -# Debug -set -x - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy "Resources" into "assets" -cp -rf "$RESROUCE_ROOT"/* "$APP_ANDROID_ROOT"/assets - -# copy bindings/*.js into assets' root -cp -rf "$BINDINGS_JS_ROOT"/* "$APP_ANDROID_ROOT"/assets - -echo "Using prebuilt externals" -echo - -set -x - -"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" \ - NDK_LOG=0 V=0 diff --git a/samples/Lua/HelloLua/proj.android/build_native.cmd b/samples/Lua/HelloLua/proj.android/build_native.cmd deleted file mode 100644 index 4116608669..0000000000 --- a/samples/Lua/HelloLua/proj.android/build_native.cmd +++ /dev/null @@ -1,86 +0,0 @@ -@echo off - -set APPNAME="HelloLua" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\Resources\* %APP_ANDROID_ROOT%\assets - -rem copy common luaScript -xcopy /e /q /r /y %COCOS2DX_ROOT%\cocos\scripting\lua\script\* %APP_ANDROID_ROOT%\assets - -call %NDK_ROOT%\ndk-build.cmd NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Lua/HelloLua/proj.android/build_native.sh b/samples/Lua/HelloLua/proj.android/build_native.sh deleted file mode 100755 index 0e0f3662f5..0000000000 --- a/samples/Lua/HelloLua/proj.android/build_native.sh +++ /dev/null @@ -1,116 +0,0 @@ -APPNAME="HelloLua" - -# options - -buildexternalsfromsource= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --h this help -EOF -} - -while getopts "sh" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -h) -usage -exit 0 -;; -esac -done - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory -COCOS2DX_ROOT="$DIR/../../../.." -APP_ROOT="$DIR/.." -APP_ANDROID_ROOT="$DIR" - -echo "NDK_ROOT = $NDK_ROOT" -echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo "APP_ROOT = $APP_ROOT" -echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy resources -for file in "$APP_ROOT"/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -#copy comment script -for file in "$APP_ROOT"/../../../cocos/scripting/lua/script/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -if [[ "$buildexternalsfromsource" ]]; then - echo "Building external dependencies from source" - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}" -else - echo "Using prebuilt externals" - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}/external:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}" -fi diff --git a/samples/Lua/TestLua/proj.android/build_native.cmd b/samples/Lua/TestLua/proj.android/build_native.cmd deleted file mode 100644 index fa1fc0ad75..0000000000 --- a/samples/Lua/TestLua/proj.android/build_native.cmd +++ /dev/null @@ -1,93 +0,0 @@ -@echo off - -set APPNAME="TestLua" - -set buildexternalsfromsource= -set PARALLEL_BUILD_FLAG= - -goto :getopts - -:usage - echo Build C/C++ code for %APPNAME% using Android NDK - echo OPTIONS: - echo -s Build externals from source - echo -h this help - pause - exit /b 1 - -:def - echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment." - pause - exit /b 1 - -:getopts - set "par=%~1" - if "%par%"=="" (goto :L) - if "%~1"=="-s" set /a buildexternalsfromsource=1 - if "%~1"=="-h" goto :usage - shift - goto :getopts - -:L -set NDK_ROOT=%NDK_ROOT% -if "%NDK_ROOT%"=="" goto:def - -rem check toolchains -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.8 (goto :toolchains48) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.7 (goto :toolchains47) -if exist %NDK_ROOT%\toolchains\arm-linux-androideabi-4.6 (goto :toolchains46) -echo "Couldn't find the gcc toolchain." -pause -exit /b 1 - -:toolchains48 - set NDK_TOOLCHAIN_VERSION=4.8 - goto :InitPath -:toolchains47 - set NDK_TOOLCHAIN_VERSION=4.7 - goto :InitPath -:toolchains46 - set NDK_TOOLCHAIN_VERSION=4.6 - -:InitPath - -set COCOS2DX_ROOT=%~dp0..\..\..\.. -set APP_ROOT=%~dp0.. -set APP_ANDROID_ROOT=%~dp0 - -if "%buildexternalsfromsource%"=="1" (goto :MODULE1) else (goto :MODULE2) -:MODULE1 - echo "Building external dependencies from source" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos2dx\platform\third_party\android\source - goto :COPY_RES -:MODULE2 - echo "Using prebuilt externals" - set NDK_MODULE_PATH=%COCOS2DX_ROOT%;%COCOS2DX_ROOT%\cocos;%COCOS2DX_ROOT%\external - -:COPY_RES -echo NDK_ROOT = %NDK_ROOT% -echo COCOS2DX_ROOT=%COCOS2DX_ROOT% -echo APP_ROOT=%APP_ROOT% -echo APP_ANDROID_ROOT=%APP_ANDROID_ROOT% -echo NDK_TOOLCHAIN_VERSION=%NDK_TOOLCHAIN_VERSION% - -rem make sure assets is exist -if exist %APP_ANDROID_ROOT%\assets rd /q /s %APP_ANDROID_ROOT%\assets - -mkdir %APP_ANDROID_ROOT%\assets - -rem copy Resources/* into assets' root -xcopy /e /q /r /y %APP_ROOT%\Resources\* %APP_ANDROID_ROOT%\assets - -rem copy common luaScript -xcopy /e /q /r /y %COCOS2DX_ROOT%\cocos\scripting\lua\script\* %APP_ANDROID_ROOT%\assets - -rem remove test_image_rgba4444.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_image_rgba4444.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_rgba8888.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_rgb888.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_rgba4444.pvr.gz -del /f /q %APP_ANDROID_ROOT%\assets\Images\test_1021x1024_a8.pvr.gz - -call %NDK_ROOT%\ndk-build.cmd NDK_LOG=0 V=0 %* -pause \ No newline at end of file diff --git a/samples/Lua/TestLua/proj.android/build_native.sh b/samples/Lua/TestLua/proj.android/build_native.sh deleted file mode 100755 index 1774c62c32..0000000000 --- a/samples/Lua/TestLua/proj.android/build_native.sh +++ /dev/null @@ -1,143 +0,0 @@ -APPNAME="TestLua" - -# options - -buildexternalsfromsource= - -usage(){ -cat << EOF -usage: $0 [options] - -Build C/C++ code for $APPNAME using Android NDK - -OPTIONS: --s Build externals from source --h this help -EOF -} - -while getopts "sh" OPTION; do -case "$OPTION" in -s) -buildexternalsfromsource=1 -;; -h) -usage -exit 0 -;; -esac -done - -# read local.properties - -_LOCALPROPERTIES_FILE=$(dirname "$0")"/local.properties" -if [ -f "$_LOCALPROPERTIES_FILE" ] -then - [ -r "$_LOCALPROPERTIES_FILE" ] || die "Fatal Error: $_LOCALPROPERTIES_FILE exists but is unreadable" - - # strip out entries with a "." because Bash cannot process variables with a "." - _PROPERTIES=`sed '/\./d' "$_LOCALPROPERTIES_FILE"` - for line in "$_PROPERTIES"; do - declare "$line"; - done -fi - -# paths - -if [ -z "${NDK_ROOT+aaa}" ];then -echo "NDK_ROOT not defined. Please define NDK_ROOT in your environment or in local.properties" -exit 1 -fi - -# For compatibility of android-ndk-r9, 4.7 was removed from r9 -if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.7" ]; then - export NDK_TOOLCHAIN_VERSION=4.7 - echo "The Selected NDK toolchain version was 4.7 !" -else - if [ -d "${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8" ]; then - export NDK_TOOLCHAIN_VERSION=4.8 - echo "The Selected NDK toolchain version was 4.8 !" - else - echo "Couldn't find the gcc toolchain." - exit 1 - fi -fi - - -if [ -z "${COCOS2DX_ROOT+aaa}" ]; then -# ... if COCOS2DX_ROOT is not set -# ... find current working directory - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# ... use paths relative to current directory - COCOS2DX_ROOT="$DIR/../../../.." - APP_ROOT="$DIR/.." - APP_ANDROID_ROOT="$DIR" -else - APP_ROOT="$COCOS2DX_ROOT"/samples/Lua/"$APPNAME" - APP_ANDROID_ROOT="$COCOS2DX_ROOT"/samples/Lua/"$APPNAME"/proj.android -fi - -echo "NDK_ROOT = $NDK_ROOT" -echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" -echo "APP_ROOT = $APP_ROOT" -echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" - -# make sure assets is exist -if [ -d "$APP_ANDROID_ROOT"/assets ]; then - rm -rf "$APP_ANDROID_ROOT"/assets -fi - -mkdir "$APP_ANDROID_ROOT"/assets - -# copy resources -for file in "$APP_ROOT"/../../Cpp/TestCpp/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -# copy luaScript -for file in "$APP_ROOT"/Resources/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -# copy common luaScript -for file in "$APP_ROOT"/../../../cocos/scripting/lua/script/* -do -if [ -d "$file" ]; then - cp -rf "$file" "$APP_ANDROID_ROOT"/assets -fi - -if [ -f "$file" ]; then - cp "$file" "$APP_ANDROID_ROOT"/assets -fi -done - -# remove test_image_rgba4444.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_image_rgba4444.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_rgba8888.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_rgb888.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_rgba4444.pvr.gz -rm -f "$APP_ANDROID_ROOT"/assets/Images/test_1021x1024_a8.pvr.gz - -if [[ "$buildexternalsfromsource" ]]; then - echo "Building external dependencies from source" - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" -else - echo "Using prebuilt externals" - "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \ - "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos:${COCOS2DX_ROOT}/external" -fi From 5d931dab644a8c8e882d7af854adb814e17edf10 Mon Sep 17 00:00:00 2001 From: minggo Date: Wed, 30 Oct 2013 18:31:59 +0800 Subject: [PATCH 077/144] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 8fc9c367ee..158e288955 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] Fixed application will crash when pause and resume. [FIX] Clear NoSuchMethodError Exception when JniHelper fails to find method id [NEW] Added xlargeScreens="true" to supports-screens + [NEW] Added build/android-build.py to build all Android samples [Mac] [FIX] Removed unused CCLOG() from GL initialization [iOS] From 1f07a659a6dda6add0c590bf992f1e521fe67315 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 09:49:04 +0800 Subject: [PATCH 078/144] issue #3069:Modify layer lua register and add some compatible lua binding functions --- .../cocos2d_specifics.cpp.REMOVED.git-id | 2 +- .../lua/bindings/lua_cocos2dx_manual.cpp | 793 +++++++++++++++++- .../PerformanceTest/PerformanceSpriteTest.cpp | 17 +- tools/tolua/cocos2dx_extension.ini | 2 +- 4 files changed, 797 insertions(+), 17 deletions(-) diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index c661a05129..3237461ed0 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -1475f1478d176a00cc8d0f9b3302881dee7a8437 \ No newline at end of file +d88cc721a9477ddfd6f690121991a620cbd260e6 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/lua_cocos2dx_manual.cpp b/cocos/scripting/lua/bindings/lua_cocos2dx_manual.cpp index cb3ab58888..7e5a38abb1 100644 --- a/cocos/scripting/lua/bindings/lua_cocos2dx_manual.cpp +++ b/cocos/scripting/lua/bindings/lua_cocos2dx_manual.cpp @@ -514,6 +514,709 @@ tolua_lerror: #endif } + +static int executeScriptTouchHandler(Layer* layer, EventTouch::EventCode eventType, Touch* touch) +{ + TouchScriptData data(eventType, layer, touch); + ScriptEvent event(kTouchEvent, &data); + return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); +} + +static int executeScriptTouchesHandler(Layer* layer, EventTouch::EventCode eventType, const std::vector& touches) +{ + TouchesScriptData data(eventType, layer, touches); + ScriptEvent event(kTouchesEvent, &data); + return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); +} + +static void setTouchEnabledForLayer(Layer* layer, bool enabled) +{ + if (nullptr == layer) + return; + + auto dict = static_cast(layer->getUserObject()); + if (dict == nullptr) + { + dict = Dictionary::create(); + layer->setUserObject(dict); + } + + dict->setObject(Bool::create(enabled), "touchEnabled"); + + auto touchListenerAllAtOnce = static_cast(dict->objectForKey("touchListenerAllAtOnce")); + auto touchListenerOneByOne = static_cast(dict->objectForKey("touchListenerOneByOne")); + auto touchMode = static_cast(dict->objectForKey("touchMode")); + auto swallowTouches = static_cast(dict->objectForKey("swallowTouches")); + + auto dispatcher = layer->getEventDispatcher(); + if (nullptr != dispatcher) + { + dispatcher->removeEventListener(touchListenerAllAtOnce); + dispatcher->removeEventListener(touchListenerOneByOne); + } + + if (enabled) + { + if (touchMode == nullptr || touchMode->getValue() == (int)Touch::DispatchMode::ALL_AT_ONCE) + { + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = [layer](const std::vector& touches, Event* event){ + executeScriptTouchesHandler(layer, EventTouch::EventCode::BEGAN, touches); + }; + listener->onTouchesMoved = [layer](const std::vector& touches, Event* event){ + executeScriptTouchesHandler(layer, EventTouch::EventCode::MOVED, touches); + }; + listener->onTouchesEnded = [layer](const std::vector& touches, Event* event){ + executeScriptTouchesHandler(layer, EventTouch::EventCode::ENDED, touches); + }; + listener->onTouchesCancelled = [layer](const std::vector& touches, Event* event){ + executeScriptTouchesHandler(layer, EventTouch::EventCode::CANCELLED, touches); + }; + + dispatcher->addEventListenerWithSceneGraphPriority(listener, layer); + + dict->setObject(listener, "touchListenerAllAtOnce"); + } + else + { + auto listener = EventListenerTouchOneByOne::create(); + listener->setSwallowTouches(swallowTouches ? swallowTouches->getValue() : false); + listener->onTouchBegan = [layer](Touch* touch, Event* event) -> bool{ + return executeScriptTouchHandler(layer, EventTouch::EventCode::BEGAN, touch) == 0 ? false : true; + }; + listener->onTouchMoved = [layer](Touch* touch, Event* event){ + executeScriptTouchHandler(layer, EventTouch::EventCode::MOVED, touch); + }; + listener->onTouchEnded = [layer](Touch* touch, Event* event){ + executeScriptTouchHandler(layer, EventTouch::EventCode::ENDED, touch); + }; + listener->onTouchCancelled = [layer](Touch* touch, Event* event){ + executeScriptTouchHandler(layer, EventTouch::EventCode::CANCELLED, touch); + }; + + dispatcher->addEventListenerWithSceneGraphPriority(listener, layer); + + dict->setObject(listener, "touchListenerOneByOne"); + } + } + +} + +//Only for v2.x lua compatibility +static int lua_cocos2dx_Layer_setTouchPriority(lua_State* L) +{ + return 0; +} + +static int lua_cocos2dx_Layer_setTouchEnabled(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setTouchEnabled'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 2, 0, &tolua_err)) + { + goto tolua_lerror; + } +#endif + bool enabled = tolua_toboolean(L, 2, 0); + setTouchEnabledForLayer(self, enabled); + return 0; + } + + CCLOG("'setTouchEnabled' has wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setTouchEnabled'.",&tolua_err); + return 0; +#endif + +} + +static int lua_cocos2dx_Layer_isTouchEnabled(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_isTouchEnabled'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (0 == argc) + { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + Bool* enabled = static_cast(dict->objectForKey("touchEnabled")); + bool ret = enabled ? enabled->getValue() : false; + tolua_pushboolean(L, ret); + return 1; + } + + return 0; + } + + CCLOG("'isTouchEnabled' has wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'isTouchEnabled'.",&tolua_err); + return 0; +#endif + + +} + +static int lua_cocos2dx_Layer_setTouchMode(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setTouchMode'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isnumber(L, 2, 0, &tolua_err)) + { + goto tolua_lerror; + } +#endif + int32_t mode = (int32_t)tolua_tonumber(L, 2, 0); + + auto dict = static_cast(self->getUserObject()); + if ( nullptr == dict) + { + dict = Dictionary::create(); + self->setUserObject(dict); + } + + Integer* touchModeObj = static_cast(dict->objectForKey("touchMode")); + int32_t touchMode = touchModeObj ? touchModeObj->getValue() : 0; + if (touchMode != mode) + { + dict->setObject(Integer::create(mode), "touchMode"); + Bool* enabled = static_cast(dict->objectForKey("touchEnabled")); + if (enabled && enabled->getValue()) + { + setTouchEnabledForLayer(self, false); + setTouchEnabledForLayer(self, true); + } + } + return 0; + } + + CCLOG("'setTouchMode' has wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setTouchMode'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_getTouchMode(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_getTouchMode'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (0 == argc) + { + int32_t ret = 0; + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + Integer* mode = static_cast(dict->objectForKey("touchMode")); + ret = mode ? mode->getValue() : 0; + tolua_pushnumber(L, (lua_Number)ret); + return 1; + } + + return 0; + } + + CCLOG("'getTouchMode' has wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'getTouchMode'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_setSwallowsTouches(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setSwallowsTouches'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + + bool swallowsTouches = tolua_toboolean(L, 2, 0); + Bool* swallowsTouchesObj = nullptr; + + auto dict = static_cast(self->getUserObject()); + if (dict == nullptr) + { + dict = Dictionary::create(); + self->setUserObject(dict); + } + + swallowsTouchesObj = static_cast(dict->objectForKey("swallowTouches")); + bool oldSwallowsTouches = swallowsTouchesObj ? swallowsTouchesObj->getValue() : false; + + if (oldSwallowsTouches != swallowsTouches) + { + dict->setObject(Integer::create(swallowsTouches), "swallowTouches"); + Bool* enabled = static_cast(dict->objectForKey("touchEnabled")); + if (enabled && enabled->getValue()) + { + setTouchEnabledForLayer(self, false); + setTouchEnabledForLayer(self, true); + } + } + + return 0; + } + + CCLOG("'setSwallowsTouches' has wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setSwallowsTouches'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_isSwallowsTouches(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_isSwallowsTouches'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (0 == argc) + { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + Bool* swallowTouches = static_cast(dict->objectForKey("swallowTouches")); + bool ret = swallowTouches ? swallowTouches->getValue() : false; + lua_pushboolean(L, ret); + return 1; + } + return 0; + } + + CCLOG("'isSwallowsTouches' has wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'isSwallowsTouches'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_setKeyboardEnabled(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setKeyboardEnabled'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + bool enabled = tolua_toboolean(L, 2, 0); + auto dict = static_cast(self->getUserObject()); + if (dict == nullptr) + { + dict = Dictionary::create(); + self->setUserObject(dict); + } + + dict->setObject(Bool::create(enabled), "keyboardEnabled"); + + auto keyboardListener = static_cast(dict->objectForKey("keyboardListener")); + + auto dispatcher = self->getEventDispatcher(); + dispatcher->removeEventListener(keyboardListener); + if (enabled) + { + auto listener = EventListenerKeyboard::create(); + listener->onKeyPressed = [self](EventKeyboard::KeyCode keyCode, Event* event){ + + }; + listener->onKeyReleased = [self](EventKeyboard::KeyCode keyCode, Event* event){ + KeypadScriptData data(keyCode, self); + ScriptEvent scriptEvent(kKeypadEvent,&data); + ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); + }; + CCLOG("come in the keyboardEnable"); + dispatcher->addEventListenerWithSceneGraphPriority(listener, self); + + dict->setObject(listener, "keyboardListener"); + } + return 0; + } + + CCLOG("'setKeyboardEnabled' has wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setKeyboardEnabled'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_isKeyboardEnabled(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_isKeyboardEnabled'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (0 == argc) + { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + Bool* enabled = static_cast(dict->objectForKey("keyboardEnabled")); + bool ret = enabled ? enabled->getValue() : false; + tolua_pushboolean(L, ret); + return 1; + } + return 0; + } + + CCLOG("'isKeyboardEnabled' has wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'isKeyboardEnabled'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_setAccelerometerEnabled(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setAccelerometerEnabled'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + bool enabled = tolua_toboolean(L, 2, 0); + auto dict = static_cast(self->getUserObject()); + if (dict == nullptr) + { + dict = Dictionary::create(); + self->setUserObject(dict); + } + + dict->setObject(Bool::create(enabled), "accelerometerEnabled"); + + auto accListener = static_cast(dict->objectForKey("accListener")); + + auto dispatcher = self->getEventDispatcher(); + dispatcher->removeEventListener(accListener); + + Device::setAccelerometerEnabled(enabled); + + if (enabled) + { + auto listener = EventListenerAcceleration::create([self](Acceleration* acc, Event* event){ + BasicScriptData data(self,(void*)acc); + ScriptEvent accEvent(kAccelerometerEvent,&data); + ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&accEvent); + }); + + dispatcher->addEventListenerWithSceneGraphPriority(listener, self); + + dict->setObject(listener, "accListener"); + } + + return 0; + } + + CCLOG("'setAccelerometerEnabled' has wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setAccelerometerEnabled'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_isAccelerometerEnabled(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_isAccelerometerEnabled'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (0 == argc) + { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + Bool* enabled = static_cast(dict->objectForKey("accelerometerEnabled")); + bool ret = enabled ? enabled->getValue() : false; + tolua_pushboolean(L, ret); + return 1; + } + + return 0; + } + + + CCLOG("'isAccelerometerEnabled' has wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'isAccelerometerEnabled'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_Layer_setAccelerometerInterval(lua_State* L) +{ + if (nullptr == L) + return 0; + + int argc = 0; + Layer* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"Layer",0,&tolua_err)) goto tolua_lerror; +#endif + + self = static_cast(tolua_tousertype(L,1,0)); + +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_Layer_setAccelerometerInterval'\n", NULL); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isnumber(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + double interval = tolua_tonumber(L, 2, 0); + Device::setAccelerometerEnabled(interval); + return 0; + } + + CCLOG("'setAccelerometerInterval' has wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'setAccelerometerInterval'.",&tolua_err); + return 0; +#endif +} + + static int tolua_cocos2d_Layer_registerScriptTouchHandler(lua_State* tolua_S) { if (NULL == tolua_S) @@ -546,6 +1249,7 @@ static int tolua_cocos2d_Layer_registerScriptTouchHandler(lua_State* tolua_S) #endif LUA_FUNCTION handler = ( toluafix_ref_function(tolua_S,2,0)); bool isMultiTouches = false; + //Note:priority is useless int priority = 0; bool swallowTouches = true; @@ -579,9 +1283,43 @@ static int tolua_cocos2d_Layer_registerScriptTouchHandler(lua_State* tolua_S) Touch::DispatchMode touchesMode = Touch::DispatchMode::ALL_AT_ONCE; if (!isMultiTouches) touchesMode = Touch::DispatchMode::ONE_BY_ONE; - self->setTouchMode(touchesMode); -// self->setTouchPriority(priority); - self->setSwallowsTouches(swallowTouches); + + auto dict = static_cast(self->getUserObject()); + if (dict == nullptr) + { + dict = Dictionary::create(); + self->setUserObject(dict); + } + + auto touchModeobj = static_cast(dict->objectForKey("touchMode")); + auto swallowTouchesValue = static_cast(dict->objectForKey("swallowTouches")); + + //touch model + int32_t mode = touchModeobj?touchModeobj->getValue() : 0; + if (mode != (int)touchesMode) + { + dict->setObject(Integer::create((int)touchesMode), "touchMode"); + Bool* enabled = static_cast(dict->objectForKey("touchEnabled")); + if (enabled && enabled->getValue()) + { + setTouchEnabledForLayer(self, false); + setTouchEnabledForLayer(self, true); + } + } + + //swallowsTouches Obj + bool oldSwallowTouchesValue = swallowTouchesValue?swallowTouchesValue->getValue():false; + if (oldSwallowTouchesValue != swallowTouches) + { + dict->setObject(Integer::create(swallowTouches), "swallowTouches"); + Bool* enabled = static_cast(dict->objectForKey("touchEnabled")); + if (enabled && enabled->getValue()) + { + setTouchEnabledForLayer(self, false); + setTouchEnabledForLayer(self, true); + } + } + ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, ScriptHandlerMgr::HandlerType::TOUCHES); return 0; } @@ -622,6 +1360,19 @@ static int tolua_cocos2d_Layer_unregisterScriptTouchHandler(lua_State* tolua_S) if (0 == argc) { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + auto touchListenerAllAtOnce = static_cast(dict->objectForKey("touchListenerAllAtOnce")); + auto touchListenerOneByOne = static_cast(dict->objectForKey("touchListenerOneByOne")); + auto dispatcher = self->getEventDispatcher(); + if (nullptr != dispatcher) + { + dispatcher->removeEventListener(touchListenerAllAtOnce); + dispatcher->removeEventListener(touchListenerOneByOne); + } + } + ScriptHandlerMgr::getInstance()->removeObjectHandler((void*)self, ScriptHandlerMgr::HandlerType::TOUCHES); return 0; } @@ -710,6 +1461,18 @@ static int tolua_cocos2d_Layer_unregisterScriptKeypadHandler(lua_State* tolua_S) if (0 == argc) { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + auto keyboardListener = static_cast(dict->objectForKey("keyboardListener")); + + auto dispatcher = self->getEventDispatcher(); + if (dispatcher != nullptr) + { + dispatcher->removeEventListener(keyboardListener); + } + } + ScriptHandlerMgr::getInstance()->removeObjectHandler(self, ScriptHandlerMgr::HandlerType::KEYPAD); return 0; } @@ -795,6 +1558,18 @@ static int tolua_cocos2d_Layer_unregisterScriptAccelerateHandler(lua_State* tolu if (0 == argc) { + auto dict = static_cast(self->getUserObject()); + if (dict != nullptr) + { + auto accListener = static_cast(dict->objectForKey("accListener")); + + auto dispatcher = self->getEventDispatcher(); + if (dispatcher != nullptr) + { + dispatcher->removeEventListener(accListener); + } + } + ScriptHandlerMgr::getInstance()->removeObjectHandler((void*)self, ScriptHandlerMgr::HandlerType::ACCELEROMETER); return 0; } @@ -2503,6 +3278,18 @@ static void extendLayer(lua_State* tolua_S) lua_pushstring(tolua_S, "unregisterScriptAccelerateHandler"); lua_pushcfunction(tolua_S, tolua_cocos2d_Layer_unregisterScriptAccelerateHandler); lua_rawset(tolua_S, -3); + + tolua_function(tolua_S, "setTouchEnabled", lua_cocos2dx_Layer_setTouchEnabled); + tolua_function(tolua_S, "isTouchEnabled", lua_cocos2dx_Layer_isTouchEnabled); + tolua_function(tolua_S, "setTouchMode", lua_cocos2dx_Layer_setTouchMode); + tolua_function(tolua_S, "getTouchMode", lua_cocos2dx_Layer_getTouchMode); + tolua_function(tolua_S, "setSwallowsTouches", lua_cocos2dx_Layer_setSwallowsTouches); + tolua_function(tolua_S, "isSwallowsTouches", lua_cocos2dx_Layer_isSwallowsTouches); + tolua_function(tolua_S, "setKeyboardEnabled", lua_cocos2dx_Layer_setKeyboardEnabled); + tolua_function(tolua_S, "isKeyboardEnabled", lua_cocos2dx_Layer_isKeyboardEnabled); + tolua_function(tolua_S, "setAccelerometerEnabled", lua_cocos2dx_Layer_setAccelerometerEnabled); + tolua_function(tolua_S, "isAccelerometerEnabled", lua_cocos2dx_Layer_isAccelerometerEnabled); + tolua_function(tolua_S, "setAccelerometerInterval", lua_cocos2dx_Layer_setAccelerometerInterval); } } diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceSpriteTest.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceSpriteTest.cpp index b00cef317c..7e290e5e5b 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceSpriteTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceSpriteTest.cpp @@ -480,19 +480,12 @@ void SpriteMainScene::dumpProfilerFPS() float maxFPS = *iter; float totalFPS = 0.0f; float averagerFPS = 0.0f; - for (; iter != _vecFPS.end(); ++iter) + for (auto fps : _vecFPS) { - if (minFPS > *iter) - { - minFPS = *iter; - } - - if (maxFPS < *iter) - { - maxFPS = *iter; - } - - totalFPS += *iter; + CCLOG("fps is :%f\n",fps); + minFPS = std::min(minFPS, fps); + maxFPS = std::max(maxFPS, fps); + totalFPS += fps; } averagerFPS = totalFPS / _vecFPS.size(); diff --git a/tools/tolua/cocos2dx_extension.ini b/tools/tolua/cocos2dx_extension.ini index 67d87c51d6..40cac55aac 100644 --- a/tools/tolua/cocos2dx_extension.ini +++ b/tools/tolua/cocos2dx_extension.ini @@ -13,7 +13,7 @@ android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include clang_flags = -nostdinc -x c++ -std=c++11 -cocos_headers = -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/gui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath/include -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s +cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/gui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath/include -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT cxxgenerator_headers = From 12db6a32ab7f4e651ae4baa166db7747d9d62cb9 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Tue, 29 Oct 2013 20:25:03 +0800 Subject: [PATCH 079/144] issues #2893: 1.Texture atlas are create on demand, based on the characters used in the label. 2.Create Quads (and not sprites) for each letter. --- cocos/2d/CCDirector.cpp | 3 + cocos/2d/CCFont.cpp | 16 +- cocos/2d/CCFontAtlas.cpp | 164 ++++++- cocos/2d/CCFontAtlas.h | 13 +- cocos/2d/CCFontAtlasFactory.cpp | 11 +- cocos/2d/CCFontFNT.cpp | 7 +- cocos/2d/CCFontFreeType.cpp | 132 +++--- cocos/2d/CCFontFreeType.h | 13 +- cocos/2d/CCLabel.cpp | 400 +++++++++--------- cocos/2d/CCLabel.h | 35 +- cocos/2d/CCLabelTextFormatProtocol.h | 24 +- cocos/2d/CCLabelTextFormatter.cpp | 78 ++-- .../Classes/LabelTest/LabelTestNew.cpp | 8 +- 13 files changed, 550 insertions(+), 354 deletions(-) diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index ef8b38f423..7255659d07 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -60,6 +60,7 @@ THE SOFTWARE. #include "CCEGLView.h" #include "CCConfiguration.h" #include "CCEventDispatcher.h" +#include "CCFontFreeType.h" /** Position of the FPS @@ -686,6 +687,8 @@ void Director::purgeDirector() // purge bitmap cache LabelBMFont::purgeCachedData(); + FontFreeType::shutdownFreeType(); + // purge all managed caches DrawPrimitives::free(); AnimationCache::destroyInstance(); diff --git a/cocos/2d/CCFont.cpp b/cocos/2d/CCFont.cpp index 63fe7af7d1..cad004a906 100644 --- a/cocos/2d/CCFont.cpp +++ b/cocos/2d/CCFont.cpp @@ -73,13 +73,15 @@ void Font::setCurrentGlyphCollection(GlyphCollection glyphs, const char *customG break; default: - - int lenght = strlen(customGlyphs); - _customGlyphs = new char [lenght + 2]; - memcpy(_customGlyphs, customGlyphs, lenght); - - _customGlyphs[lenght] = 0; - _customGlyphs[lenght+1] = 0; + if (customGlyphs) + { + int lenght = strlen(customGlyphs); + _customGlyphs = new char [lenght + 2]; + memcpy(_customGlyphs, customGlyphs, lenght); + + _customGlyphs[lenght] = 0; + _customGlyphs[lenght+1] = 0; + } break; } diff --git a/cocos/2d/CCFontAtlas.cpp b/cocos/2d/CCFontAtlas.cpp index 6f8adeaa43..2879ac72de 100644 --- a/cocos/2d/CCFontAtlas.cpp +++ b/cocos/2d/CCFontAtlas.cpp @@ -9,18 +9,41 @@ #include "cocos2d.h" #include "CCFontAtlas.h" #include "CCFont.h" +#include "CCFontFreeType.h" NS_CC_BEGIN -FontAtlas::FontAtlas(Font &theFont) : _font(theFont) +FontAtlas::FontAtlas(Font &theFont) : +_font(theFont), +_currentPageData(nullptr) { _font.retain(); + + FontFreeType* fontTTf = dynamic_cast(&_font); + if (fontTTf && fontTTf->isDynamicGlyphCollection()) + { + _currentPageLineHeight = _font.getFontMaxHeight(); + _commonLineHeight = _currentPageLineHeight * 0.8f; + Texture2D * tex = new Texture2D; + _currentPage = 0; + _currentPageOrigX = 0; + _currentPageOrigY = 0; + _letterPadding = 5; + _currentPageDataSize = (1024 * 1024 * 4); + + _currentPageData = new unsigned char[_currentPageDataSize]; + memset(_currentPageData, 0, _currentPageDataSize); + addTexture(*tex,0); + } } FontAtlas::~FontAtlas() { _font.release(); relaseTextures(); + + if(_currentPageData) + delete []_currentPageData; } void FontAtlas::relaseTextures() @@ -51,6 +74,145 @@ bool FontAtlas::getLetterDefinitionForChar(unsigned short letteCharUTF16, FontL } } +bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) +{ + if(_currentPageData == nullptr) + return false; + + FontFreeType* fontTTf = (FontFreeType*)&_font; + + std::vector fontDefs; + int length = cc_wcslen(utf16String); + + //find out new letter + for (int i = 0; i < length; ++i) + { + auto outIterator = _fontLetterDefinitions.find(utf16String[i]); + + if (outIterator == _fontLetterDefinitions.end()) + { + Rect tempRect; + + FontLetterDefinition tempDef; + tempDef.offsetX = 0; + tempDef.anchorX = 0.0f; + tempDef.anchorY = 1.0f; + + if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect)) + { + //log("Warning: Cannot find definition for glyph: %c in font:%s", utf16String[i], _fontName.c_str()); + tempDef.validDefinition = false; + tempDef.letteCharUTF16 = utf16String[i]; + tempDef.commonLineHeight = 0; + tempDef.width = 0; + tempDef.height = 0; + tempDef.U = 0; + tempDef.V = 0; + tempDef.offsetY = 0; + tempDef.textureID = 0; + } + else + { + tempDef.validDefinition = true; + tempDef.letteCharUTF16 = utf16String[i]; + tempDef.width = tempRect.size.width + _letterPadding; + tempDef.height = _currentPageLineHeight - 1; + tempDef.offsetY = tempRect.origin.y; + tempDef.commonLineHeight = _currentPageLineHeight; + + } + fontDefs.push_back(tempDef); + } + } + + float scaleFactor = CC_CONTENT_SCALE_FACTOR(); + int newLetterCount = fontDefs.size(); + float glyphWidth; + for (int i = 0; i < newLetterCount; ++i) + { + if (fontDefs[i].validDefinition) + { + _currentPageOrigX += _letterPadding; + glyphWidth = fontDefs[i].width - _letterPadding; + + if (_currentPageOrigX + glyphWidth > 1024) + { + _currentPageOrigY += _currentPageLineHeight; + if(_currentPageOrigY >= 1024) + { + _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, Texture2D::PixelFormat::RGBA8888, 1024, 1024, Size(1024, 1024) ); + _currentPageOrigX = 0; + _currentPageOrigY = 0; + + delete []_currentPageData; + _currentPageData = new unsigned char[_currentPageDataSize]; + if(_currentPageData == nullptr) + return false; + memset(_currentPageData, 0, _currentPageDataSize); + _currentPage++; + addTexture(*(new Texture2D),_currentPage); + } + } + renderCharAt(fontDefs[i].letteCharUTF16,_currentPageOrigX,_currentPageOrigY,_currentPageData,1024); + + fontDefs[i].U = _currentPageOrigX - 1; + fontDefs[i].V = _currentPageOrigY; + fontDefs[i].textureID = _currentPage; + // take from pixels to points + fontDefs[i].width = fontDefs[i].width / scaleFactor; + fontDefs[i].height = fontDefs[i].height / scaleFactor; + fontDefs[i].U = fontDefs[i].U / scaleFactor; + fontDefs[i].V = fontDefs[i].V / scaleFactor; + } + else + glyphWidth = 0; + + this->addLetterDefinition(fontDefs[i]); + _currentPageOrigX += glyphWidth; + } + if(newLetterCount > 0) + _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, Texture2D::PixelFormat::RGBA8888, 1024, 1024, Size(1024, 1024) ); + return true; +} + +bool FontAtlas::renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize) +{ + unsigned char *sourceBitmap = 0; + int sourceWidth = 0; + int sourceHeight = 0; + + // get the glyph's bitmap + sourceBitmap = _font.getGlyphBitmap(charToRender, sourceWidth, sourceHeight); + + if (!sourceBitmap) + return false; + + int iX = posX; + int iY = posY; + + for (int y = 0; y < sourceHeight; ++y) + { + int bitmap_y = y * sourceWidth; + + for (int x = 0; x < sourceWidth; ++x) + { + unsigned char cTemp = sourceBitmap[bitmap_y + x]; + + // the final pixel + int iTemp = cTemp << 24 | cTemp << 16 | cTemp << 8 | cTemp; + *(int*) &destMemory[(iX + ( iY * destSize ) ) * 4] = iTemp; + + iX += 1; + } + + iX = posX; + iY += 1; + } + + //everything good + return true; +} + void FontAtlas::addTexture(Texture2D &texture, int slot) { texture.retain(); diff --git a/cocos/2d/CCFontAtlas.h b/cocos/2d/CCFontAtlas.h index 376da41fa9..b1b6eaa9b4 100644 --- a/cocos/2d/CCFontAtlas.h +++ b/cocos/2d/CCFontAtlas.h @@ -63,6 +63,8 @@ public: void addLetterDefinition(const FontLetterDefinition &letterDefinition); bool getLetterDefinitionForChar(unsigned short letteCharUTF16, FontLetterDefinition &outDefinition); + bool prepareLetterDefinitions(unsigned short *utf16String); + void addTexture(Texture2D &texture, int slot); float getCommonLineHeight() const; void setCommonLineHeight(float newHeight); @@ -71,13 +73,22 @@ public: Font & getFont() const; private: - + bool renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize); + void relaseTextures(); std::map _atlasTextures; std::map _fontLetterDefinitions; float _commonLineHeight; Font & _font; + // Dynamic GlyphCollection related stuff + int _currentPage; + unsigned char *_currentPageData; + int _currentPageDataSize; + float _currentPageOrigX; + float _currentPageOrigY; + float _currentPageLineHeight; + float _letterPadding; }; diff --git a/cocos/2d/CCFontAtlasFactory.cpp b/cocos/2d/CCFontAtlasFactory.cpp index d80c050def..2b8e0b4ca4 100644 --- a/cocos/2d/CCFontAtlasFactory.cpp +++ b/cocos/2d/CCFontAtlasFactory.cpp @@ -16,11 +16,6 @@ NS_CC_BEGIN FontAtlas * FontAtlasFactory::createAtlasFromTTF(const char* fntFilePath, int fontSize, GlyphCollection glyphs, const char *customGlyphs) { - if( glyphs == GlyphCollection::DYNAMIC ) - { - log("ERROR: GlyphCollection::DYNAMIC is not supported yet!"); - return nullptr; - } Font *font = Font::createWithTTF(fntFilePath, fontSize, glyphs, customGlyphs); if (font) @@ -34,7 +29,11 @@ FontAtlas * FontAtlasFactory::createAtlasFromFNT(const char* fntFilePath) Font *font = Font::createWithFNT(fntFilePath); if(font) - return font->createFontAtlas(); + { + FontAtlas * atlas = font->createFontAtlas(); + font->release(); + return atlas; + } else return nullptr; } diff --git a/cocos/2d/CCFontFNT.cpp b/cocos/2d/CCFontFNT.cpp index ebf7c876d7..cd1e586e62 100644 --- a/cocos/2d/CCFontFNT.cpp +++ b/cocos/2d/CCFontFNT.cpp @@ -38,8 +38,11 @@ FontFNT * FontFNT::create(const char* fntFilePath) FontFNT::~FontFNT() { - if (_configuration) + //_configuration release when execute LabelBMFont::purgeCachedData(); + /*if (_configuration) + { _configuration->release(); + }*/ } Size * FontFNT::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const @@ -176,7 +179,7 @@ FontAtlas * FontFNT::createFontAtlas() tempDefinition.anchorX = 0.5f; tempDefinition.anchorY = 0.5f; - + tempDefinition.validDefinition = true; // add the new definition tempAtlas->addLetterDefinition(tempDefinition); } diff --git a/cocos/2d/CCFontFreeType.cpp b/cocos/2d/CCFontFreeType.cpp index c0522f522b..3fbac58b5b 100644 --- a/cocos/2d/CCFontFreeType.cpp +++ b/cocos/2d/CCFontFreeType.cpp @@ -1,28 +1,29 @@ /**************************************************************************** - Copyright (c) 2013 Zynga Inc. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ +Copyright (c) 2013 Zynga Inc. + +http://www.cocos2d-x.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ #include +#include #include "ccUTF8.h" #include "CCFontFreeType.h" @@ -38,14 +39,12 @@ bool FontFreeType::_FTInitialized = false; FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs) { - if( glyphs == GlyphCollection::DYNAMIC ) - { - log("ERROR: GlyphCollection::DYNAMIC is not supported yet!"); - return nullptr; - } - - FontFreeType *tempFont = new FontFreeType(); + bool dynamicGlyphCollection = false; + if(glyphs == GlyphCollection::DYNAMIC) + dynamicGlyphCollection = true; + FontFreeType *tempFont = new FontFreeType(dynamicGlyphCollection); + if (!tempFont) return nullptr; @@ -56,7 +55,6 @@ FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, G delete tempFont; return nullptr; } - return tempFont; } @@ -79,6 +77,7 @@ void FontFreeType::shutdownFreeType() if (_FTInitialized == true) { FT_Done_FreeType(_FTlibrary); + _FTInitialized = false; } } @@ -88,34 +87,35 @@ FT_Library FontFreeType::getFTLibrary() return _FTlibrary; } -FontFreeType::FontFreeType() : _letterPadding(5) +FontFreeType::FontFreeType(bool dynamicGlyphCollection) + : _letterPadding(5) + ,_ttfData(nullptr), + _dynamicGlyphCollection(dynamicGlyphCollection), + _fontRef(nullptr) { } bool FontFreeType::createFontObject(const std::string &fontName, int fontSize) { - int dpi = 72; - - int len = 0; - unsigned char* data = FileUtils::getInstance()->getFileData(fontName.c_str(), "rb", (unsigned long *)(&len)); - - if (!data) - return false; - - // create the new face FT_Face face; - - // create the face from the data - if (FT_New_Memory_Face(getFTLibrary(), data, len, 0, &face )) + + int len = 0; + _ttfData = FileUtils::getInstance()->getFileData(fontName.c_str(), "rb", (unsigned long *)(&len)); + if (!_ttfData) return false; - + + // create the face from the data + if (FT_New_Memory_Face(getFTLibrary(), _ttfData, len, 0, &face )) + return false; + //we want to use unicode if (FT_Select_Charmap(face, FT_ENCODING_UNICODE)) return false; - + // set the requested font size - int fontSizePoints = (int)(64.f * fontSize); - if (FT_Set_Char_Size(face, fontSizePoints, fontSizePoints, dpi, dpi)) + int dpi = 72; + int fontSizePoints = (int)(64.f * fontSize); + if (FT_Set_Char_Size(face, fontSizePoints, fontSizePoints, dpi, dpi)) return false; // store the face globally @@ -132,20 +132,38 @@ FontFreeType::~FontFreeType() { // release the font // TO DO + if (_fontRef) + { + FT_Done_Face(_fontRef); + } + if (_ttfData) + { + delete _ttfData; + _ttfData = nullptr; + } } FontAtlas * FontFreeType::createFontAtlas() { - FontDefinitionTTF *def = FontDefinitionTTF::create(this); - - if (!def) - return nullptr; - - FontAtlas *atlas = def->createFontAtlas(); - - // release the font definition, we don't need it anymore - def->release(); - return atlas; + if (_dynamicGlyphCollection) + { + FontAtlas *atlas = new FontAtlas(*this); + this->release(); + return atlas; + } + else + { + FontDefinitionTTF *def = FontDefinitionTTF::create(this); + + if (!def) + return nullptr; + + FontAtlas *atlas = def->createFontAtlas(); + + // release the font definition, we don't need it anymore + def->release(); + return atlas; + } } bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect) const diff --git a/cocos/2d/CCFontFreeType.h b/cocos/2d/CCFontFreeType.h index 83455d801a..cdf3d1a1ac 100644 --- a/cocos/2d/CCFontFreeType.h +++ b/cocos/2d/CCFontFreeType.h @@ -47,20 +47,22 @@ public: virtual int getFontMaxHeight() const override; virtual int getLetterPadding() const override; - + bool getBBOXFotChar(unsigned short theChar, Rect &outRect) const; + + inline bool isDynamicGlyphCollection() { return _dynamicGlyphCollection;} + static void shutdownFreeType(); + protected: - FontFreeType(); + FontFreeType(bool dynamicGlyphCollection = false); virtual ~FontFreeType(); bool createFontObject(const std::string &fontName, int fontSize); private: bool initFreeType(); - void shutdownFreeType(); FT_Library getFTLibrary(); - bool getBBOXFotChar(unsigned short theChar, Rect &outRect) const; int getAdvanceForChar(unsigned short theChar) const; int getBearingXForChar(unsigned short theChar) const; int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const; @@ -70,7 +72,8 @@ private: FT_Face _fontRef; const int _letterPadding; std::string _fontName; - + unsigned char* _ttfData; + bool _dynamicGlyphCollection; }; NS_CC_END diff --git a/cocos/2d/CCLabel.cpp b/cocos/2d/CCLabel.cpp index 6164811045..a7ed8e2978 100644 --- a/cocos/2d/CCLabel.cpp +++ b/cocos/2d/CCLabel.cpp @@ -46,8 +46,6 @@ Label* Label::createWithTTF( const char* label, const char* fontFilePath, int fo } return nullptr; - - return 0; } Label* Label::createWithBMFont( const char* label, const char* bmfontFilePath, TextHAlignment alignment, int lineSize) @@ -95,8 +93,8 @@ Label* Label::createWithAtlas(FontAtlas *atlas, TextHAlignment alignment, int li } Label::Label(FontAtlas *atlas, TextHAlignment alignment) -: _currentUTF8String(0) -, _originalUTF8String(0) +: _currentUTF16String(0) +, _originalUTF16String(0) , _fontAtlas(atlas) , _alignment(alignment) , _lineBreakWithoutSpaces(false) @@ -107,32 +105,35 @@ Label::Label(FontAtlas *atlas, TextHAlignment alignment) , _cascadeOpacityEnabled(true) , _displayedOpacity(255) , _realOpacity(255) -, _isOpacityModifyRGB(false) +, _isOpacityModifyRGB(true) +,_reusedLetter(nullptr) { } Label::~Label() -{ - CC_SAFE_RELEASE(_spriteArray); - CC_SAFE_RELEASE(_spriteArrayCache); - - if (_currentUTF8String) - delete [] _currentUTF8String; - +{ + if (_currentUTF16String) + delete [] _currentUTF16String; + if (_originalUTF16String) + delete [] _originalUTF16String; if (_advances) delete [] _advances; if (_fontAtlas) FontAtlasCache::releaseFontAtlas(_fontAtlas); + + delete _reusedLetter; } bool Label::init() -{ - _spriteArray = Array::createWithCapacity(30); - _spriteArrayCache = Array::createWithCapacity(30); - - _spriteArray->retain(); - _spriteArrayCache->retain(); +{ + if(_fontAtlas) + { + _reusedLetter = new Sprite; + _reusedLetter->initWithTexture(&_fontAtlas->getTexture(0)); + _reusedLetter->setOpacityModifyRGB(_isOpacityModifyRGB); + return SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), 30); + } return true; } @@ -151,14 +152,10 @@ bool Label::setText(const char *stringToRender, float lineWidth, TextHAlignment // reset the string resetCurrentString(); - _width = lineWidth; _alignment = alignment; _lineBreakWithoutSpaces = lineBreakWithoutSpaces; - // release all the sprites - moveAllSpritesToCache(); - // store locally common line height _commonLineHeight = _fontAtlas->getCommonLineHeight(); if (_commonLineHeight <= 0) @@ -169,11 +166,8 @@ bool Label::setText(const char *stringToRender, float lineWidth, TextHAlignment if(!utf16String) return false; - numLetter = cc_wcslen(utf16String); - SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), numLetter); _cascadeColorEnabled = true; - // setCurrentString(utf16String); setOriginalString(utf16String); @@ -247,30 +241,56 @@ void Label::setScaleY(float scaleY) } void Label::alignText() -{ - hideAllLetters(); - LabelTextFormatter::createStringSprites(this); - - if( LabelTextFormatter::multilineText(this) ) - { - hideAllLetters(); +{ + if(_textureAtlas) + _textureAtlas->removeAllQuads(); + _fontAtlas->prepareLetterDefinitions(_currentUTF16String); + LabelTextFormatter::createStringSprites(this); + if( LabelTextFormatter::multilineText(this) ) LabelTextFormatter::createStringSprites(this); - } LabelTextFormatter::alignText(this); -} - -void Label::hideAllLetters() -{ - Object* Obj = NULL; - CCARRAY_FOREACH(_spriteArray, Obj) + + int strLen = cc_wcslen(_currentUTF16String); + if (_children && _children->count() != 0) { - ((Sprite *)Obj)->setVisible(false); + Object* child; + CCARRAY_FOREACH(_children, child) + { + Node* pNode = static_cast( child ); + if (pNode) + { + int tag = pNode->getTag(); + if(tag < 0 || tag >= strLen) + SpriteBatchNode::removeChild(pNode, true); + } + } } - - CCARRAY_FOREACH(_spriteArrayCache, Obj) - { - ((Sprite *)Obj)->setVisible(false); + _reusedLetter->setBatchNode(nullptr); + + int vaildIndex = 0; + Sprite* child = nullptr; + Rect uvRect; + for (int ctr = 0; ctr < strLen; ++ctr) + { + if (_lettersInfo[ctr].def.validDefinition) + { + child = (Sprite*)this->getChildByTag(ctr); + if (child) + { + uvRect.size.height = _lettersInfo[ctr].def.height; + uvRect.size.width = _lettersInfo[ctr].def.width; + uvRect.origin.x = _lettersInfo[ctr].def.U; + uvRect.origin.y = _lettersInfo[ctr].def.V; + + child->setTexture(&_fontAtlas->getTexture(_lettersInfo[ctr].def.textureID)); + child->setTextureRect(uvRect); + } + + updateSpriteWithLetterDefinition(_reusedLetter,_lettersInfo[ctr].def,&_fontAtlas->getTexture(_lettersInfo[ctr].def.textureID)); + _reusedLetter->setPosition(_lettersInfo[ctr].position); + insertQuadFromSprite(_reusedLetter,vaildIndex++); + } } } @@ -295,17 +315,17 @@ bool Label::computeAdvancesForString(unsigned short int *stringToRender) bool Label::setOriginalString(unsigned short *stringToSet) { - if (_originalUTF8String) + if (_originalUTF16String) { - delete [] _originalUTF8String; - _originalUTF8String = 0; + delete [] _originalUTF16String; + _originalUTF16String = 0; } int newStringLenght = cc_wcslen(stringToSet); - _originalUTF8String = new unsigned short int [newStringLenght + 1]; - memset(_originalUTF8String, 0, (newStringLenght + 1) * 2); - memcpy(_originalUTF8String, stringToSet, (newStringLenght * 2)); - _originalUTF8String[newStringLenght] = 0; + _originalUTF16String = new unsigned short int [newStringLenght + 1]; + memset(_originalUTF16String, 0, (newStringLenght + 1) * 2); + memcpy(_originalUTF16String, stringToSet, (newStringLenght * 2)); + _originalUTF16String[newStringLenght] = 0; return true; } @@ -313,65 +333,36 @@ bool Label::setOriginalString(unsigned short *stringToSet) bool Label::setCurrentString(unsigned short *stringToSet) { // set the new string - if (_currentUTF8String) + if (_currentUTF16String) { - delete [] _currentUTF8String; - _currentUTF8String = 0; + delete [] _currentUTF16String; + _currentUTF16String = 0; } // - _currentUTF8String = stringToSet; + _currentUTF16String = stringToSet; // compute the advances return computeAdvancesForString(stringToSet); } void Label::resetCurrentString() { - if ((!_currentUTF8String) && (!_originalUTF8String)) + if ((!_currentUTF16String) && (!_originalUTF16String)) return; // set the new string - if (_currentUTF8String) + if (_currentUTF16String) { - delete [] _currentUTF8String; - _currentUTF8String = 0; + delete [] _currentUTF16String; + _currentUTF16String = 0; } - int stringLenght = cc_wcslen(_originalUTF8String); - _currentUTF8String = new unsigned short int [stringLenght + 1]; - memcpy(_currentUTF8String, _originalUTF8String, stringLenght * 2); - _currentUTF8String[stringLenght] = 0; + int stringLenght = cc_wcslen(_originalUTF16String); + _currentUTF16String = new unsigned short int [stringLenght + 1]; + memcpy(_currentUTF16String, _originalUTF16String, stringLenght * 2); + _currentUTF16String[stringLenght] = 0; } -Sprite * Label::createNewSpriteFromLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture) -{ - Rect uvRect; - uvRect.size.height = theDefinition.height; - uvRect.size.width = theDefinition.width; - uvRect.origin.x = theDefinition.U; - uvRect.origin.y = theDefinition.V; - - SpriteFrame *pFrame = SpriteFrame::createWithTexture(theTexture, uvRect); - Sprite *tempSprite = getSprite(); - - if (!tempSprite) - return 0; - - tempSprite->initWithSpriteFrame(pFrame); - tempSprite->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY)); - tempSprite->setBatchNode(this); - - // Apply label properties - tempSprite->setOpacityModifyRGB(_isOpacityModifyRGB); - - // Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on - tempSprite->updateDisplayedColor(_displayedColor); - tempSprite->updateDisplayedOpacity(_displayedOpacity); - - - return tempSprite; -} - Sprite * Label::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const FontLetterDefinition &theDefinition, Texture2D *theTexture) { if (!spriteToUpdate) @@ -389,143 +380,93 @@ Sprite * Label::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const F SpriteFrame *frame = SpriteFrame::createWithTexture(theTexture, uvRect); if (frame) { + spriteToUpdate->setBatchNode(this); spriteToUpdate->setTexture(theTexture); spriteToUpdate->setDisplayFrame(frame); - spriteToUpdate->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY)); - spriteToUpdate->setBatchNode(this); - } + spriteToUpdate->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY)); + } return spriteToUpdate; } } -Sprite * Label::getSpriteForLetter(unsigned short int newLetter) +bool Label::recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex) { - if (!_fontAtlas) - return 0; + if (spriteIndex >= _lettersInfo.size()) + { + LetterInfo tmpInfo; + _lettersInfo.push_back(tmpInfo); + } + + _fontAtlas->getLetterDefinitionForChar(theChar, _lettersInfo[spriteIndex].def); + _lettersInfo[spriteIndex].position = point; + _lettersInfo[spriteIndex].contentSize.width = _lettersInfo[spriteIndex].def.width; + _lettersInfo[spriteIndex].contentSize.height = _lettersInfo[spriteIndex].def.height; + + return _lettersInfo[spriteIndex].def.validDefinition; +} + +bool Label::recordPlaceholderInfo(int spriteIndex) +{ + if (spriteIndex >= _lettersInfo.size()) + { + LetterInfo tmpInfo; + _lettersInfo.push_back(tmpInfo); + } + + _lettersInfo[spriteIndex].def.validDefinition = false; - FontLetterDefinition tempDefinition; - bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition); - if (validDefinition) - { - Sprite *newSprite = createNewSpriteFromLetterDefinition(tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) ); - this->addChild(newSprite); - return newSprite; - } - else - { - return 0; - } + return false; } -Sprite * Label::updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter) +void Label::addChild(Node * child, int zOrder/* =0 */, int tag/* =0 */) { - if (!spriteToUpdate || !_fontAtlas) - return 0; - else - { - FontLetterDefinition tempDefinition; - bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition); - if (validDefinition) - { - Sprite *pNewSprite = updateSpriteWithLetterDefinition(spriteToUpdate, tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) ); - return pNewSprite; - } - else - { - return 0; - } - } -} - -void Label::moveAllSpritesToCache() -{ - Object* pObj = NULL; - CCARRAY_FOREACH(_spriteArray, pObj) - { - ((Sprite *)pObj)->removeFromParent(); - _spriteArrayCache->addObject(pObj); - } - - _spriteArray->removeAllObjects(); -} - -Sprite * Label::getSprite() -{ - if (_spriteArrayCache->count()) - { - Sprite *retSprite = static_cast(_spriteArrayCache->getLastObject()); - _spriteArrayCache->removeLastObject(); - return retSprite; - } - else - { - Sprite *retSprite = new Sprite; - return retSprite; - } + CCASSERT(0, "addChild: is not supported on Label."); } ///// PROTOCOL STUFF -Sprite * Label::getSpriteChild(int ID) const +Sprite * Label::getLetterAt(int ID) { - Object* pObj = NULL; - CCARRAY_FOREACH(_spriteArray, pObj) - { - Sprite *pSprite = (Sprite *)pObj; - if ( pSprite->getTag() == ID) + if (ID < getStringLenght()) + { + if(_lettersInfo[ID].def.validDefinition == false) + return nullptr; + + Sprite* sp = static_cast(this->getChildByTag(ID)); + + if (!sp) { - return pSprite; + Rect uvRect; + uvRect.size.height = _lettersInfo[ID].def.height; + uvRect.size.width = _lettersInfo[ID].def.width; + uvRect.origin.x = _lettersInfo[ID].def.U; + uvRect.origin.y = _lettersInfo[ID].def.V; + + sp = new Sprite(); + sp->initWithTexture(&_fontAtlas->getTexture(_lettersInfo[ID].def.textureID),uvRect); + sp->setBatchNode(this); + sp->setAnchorPoint(Point(_lettersInfo[ID].def.anchorX, _lettersInfo[ID].def.anchorY)); + sp->setPosition(_lettersInfo[ID].position); + sp->setOpacity(_realOpacity); + + this->addSpriteWithoutQuad(sp, ID, ID); + sp->release(); } - } - return 0; -} - -Array* Label::getChildrenLetters() const -{ - return _spriteArray; -} - -Sprite * Label::getSpriteForChar(unsigned short int theChar, int spriteIndexHint) -{ - // ret sprite - Sprite *retSprite = 0; - - // look for already existing sprites - retSprite = getSpriteChild(spriteIndexHint); - - if (!retSprite) - { - retSprite = getSpriteForLetter(theChar); - if (!retSprite) - return 0; - - if (retSprite) - retSprite->setTag(spriteIndexHint); - - _spriteArray->addObject(retSprite); + return sp; } - // the sprite is now visible - retSprite->setVisible(true); - - // set the right texture letter to the sprite - updateSpriteForLetter(retSprite, theChar); - - // we are done here - return retSprite; + return nullptr; } -float Label::getLetterPosXLeft( Sprite* sp ) const +float Label::getLetterPosXLeft( int index ) const { - float scaleX = _scaleX; - return sp->getPosition().x * scaleX - (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x); + return _lettersInfo[index].position.x * _scaleX - (_lettersInfo[index].contentSize.width * _scaleX * _lettersInfo[index].def.anchorX); } -float Label::getLetterPosXRight( Sprite* sp ) const +float Label::getLetterPosXRight( int index ) const { - float scaleX = _scaleX; - return sp->getPosition().x * scaleX + (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x); + return _lettersInfo[index].position.x * _scaleX + (_lettersInfo[index].contentSize.width * _scaleX * _lettersInfo[index].def.anchorX); } int Label::getCommonLineHeight() const @@ -586,14 +527,14 @@ int Label::getStringNumLines() const { int quantityOfLines = 1; - unsigned int stringLen = _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0; + unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : 0; if (stringLen == 0) return (-1); // count number of lines for (unsigned int i = 0; i < stringLen - 1; ++i) { - unsigned short c = _currentUTF8String[i]; + unsigned short c = _currentUTF16String[i]; if (c == '\n') { quantityOfLines++; @@ -605,17 +546,17 @@ int Label::getStringNumLines() const int Label::getStringLenght() const { - return _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0; + return _currentUTF16String ? cc_wcslen(_currentUTF16String) : 0; } unsigned short Label::getCharAtStringPosition(int position) const { - return _currentUTF8String[position]; + return _currentUTF16String[position]; } unsigned short * Label::getUTF8String() const { - return _currentUTF8String; + return _currentUTF16String; } void Label::assignNewUTF8String(unsigned short *newString) @@ -677,6 +618,7 @@ void Label::setOpacityModifyRGB(bool isOpacityModifyRGB) } } } + _reusedLetter->setOpacityModifyRGB(true); } unsigned char Label::getOpacity() const @@ -692,7 +634,7 @@ unsigned char Label::getDisplayedOpacity() const void Label::setOpacity(GLubyte opacity) { _displayedOpacity = _realOpacity = opacity; - + _reusedLetter->setOpacity(opacity); if( _cascadeOpacityEnabled ) { GLubyte parentOpacity = 255; RGBAProtocol* pParent = dynamic_cast(_parent); @@ -713,6 +655,26 @@ void Label::updateDisplayedOpacity(GLubyte parentOpacity) Sprite *item = static_cast( pObj ); item->updateDisplayedOpacity(_displayedOpacity); } + //if (_cascadeOpacityEnabled) + { + V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads(); + int count = _textureAtlas->getTotalQuads(); + Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); + if (_isOpacityModifyRGB) + { + color4.r *= _displayedOpacity/255.0f; + color4.g *= _displayedOpacity/255.0f; + color4.b *= _displayedOpacity/255.0f; + } + for (int index=0; indexupdateQuad(&quads[index], index); + } + } } bool Label::isCascadeOpacityEnabled() const @@ -738,7 +700,7 @@ const Color3B& Label::getDisplayedColor() const void Label::setColor(const Color3B& color) { _displayedColor = _realColor = color; - + _reusedLetter->setColor(color); if( _cascadeColorEnabled ) { Color3B parentColor = Color3B::WHITE; @@ -763,6 +725,26 @@ void Label::updateDisplayedColor(const Color3B& parentColor) Sprite *item = static_cast( pObj ); item->updateDisplayedColor(_displayedColor); } + + V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads(); + int count = _textureAtlas->getTotalQuads(); + Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); + + // special opacity for premultiplied textures + if (_isOpacityModifyRGB) + { + color4.r *= _displayedOpacity/255.0f; + color4.g *= _displayedOpacity/255.0f; + color4.b *= _displayedOpacity/255.0f; + } + for (int index=0; indexupdateQuad(&quads[index], index); + } } bool Label::isCascadeColorEnabled() const diff --git a/cocos/2d/CCLabel.h b/cocos/2d/CCLabel.h index e65c27eb7b..e9e56e31ca 100644 --- a/cocos/2d/CCLabel.h +++ b/cocos/2d/CCLabel.h @@ -82,12 +82,13 @@ public: virtual unsigned char getDisplayedOpacity() const override; // CCLabelTextFormat protocol implementation - virtual Sprite * getSpriteChild(int ID) const override; - virtual Array * getChildrenLetters() const override; - virtual Sprite * getSpriteForChar(unsigned short int theChar, int spriteIndexHint) override; - virtual float getLetterPosXLeft( Sprite* sp ) const override; - virtual float getLetterPosXRight( Sprite* sp ) const override; + virtual std::vector *getLettersInfo(){ return &_lettersInfo; }; + virtual bool recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex); + virtual bool recordPlaceholderInfo(int spriteIndex); + virtual float getLetterPosXLeft( int index ) const override; + virtual float getLetterPosXRight( int index ) const override; + virtual Sprite * getLetterAt(int ID) override; // font related stuff virtual int getCommonLineHeight() const override; @@ -113,7 +114,8 @@ public: // carloX const char * getString() const { return "not implemented"; } - + void addChild(Node * child, int zOrder=0, int tag=0); + private: /** * @js NA @@ -129,29 +131,26 @@ private: bool init(); - void alignText(); - void hideAllLetters(); - void moveAllSpritesToCache(); + void alignText(); bool computeAdvancesForString(unsigned short int *stringToRender); bool setCurrentString(unsigned short *stringToSet); bool setOriginalString(unsigned short *stringToSet); void resetCurrentString(); + + Sprite * updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const FontLetterDefinition &theDefinition, Texture2D *theTexture); - Sprite * getSprite(); - Sprite * createNewSpriteFromLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture); - Sprite * updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const FontLetterDefinition &theDefinition, Texture2D *theTexture); - Sprite * getSpriteForLetter(unsigned short int newLetter); - Sprite * updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter); - Array * _spriteArray; - Array * _spriteArrayCache; + //! used for optimization + Sprite *_reusedLetter; + std::vector _lettersInfo; + float _commonLineHeight; bool _lineBreakWithoutSpaces; float _width; TextHAlignment _alignment; - unsigned short int * _currentUTF8String; - unsigned short int * _originalUTF8String; + unsigned short int * _currentUTF16String; + unsigned short int * _originalUTF16String; Size * _advances; FontAtlas * _fontAtlas; Color3B _displayedColor; diff --git a/cocos/2d/CCLabelTextFormatProtocol.h b/cocos/2d/CCLabelTextFormatProtocol.h index 6208cfc493..c2027350fc 100644 --- a/cocos/2d/CCLabelTextFormatProtocol.h +++ b/cocos/2d/CCLabelTextFormatProtocol.h @@ -24,19 +24,31 @@ #ifndef _CCLabelTextFormatProtocol_h_ #define _CCLabelTextFormatProtocol_h_ +#include "CCFontAtlas.h" +#include NS_CC_BEGIN + +struct LetterInfo +{ + FontLetterDefinition def; + + Point position; + Size contentSize; + bool visible; +}; + class CC_DLL LabelTextFormatProtocol { public: - + virtual bool recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex) = 0; + virtual bool recordPlaceholderInfo(int spriteIndex) = 0; + virtual std::vector *getLettersInfo() = 0; + virtual float getLetterPosXLeft(int index) const = 0; + virtual float getLetterPosXRight(int index) const = 0; // sprite related stuff - virtual cocos2d::Sprite *getSpriteChild(int ID) const = 0; - virtual cocos2d::Array *getChildrenLetters() const = 0; - virtual cocos2d::Sprite *getSpriteForChar(unsigned short int theChar, int spriteIndexHint) = 0; - virtual float getLetterPosXLeft(cocos2d::Sprite* sp) const = 0; - virtual float getLetterPosXRight(cocos2d::Sprite* sp) const = 0; + virtual cocos2d::Sprite *getLetterAt(int ID) = 0; // font related stuff virtual int getCommonLineHeight() const = 0; diff --git a/cocos/2d/CCLabelTextFormatter.cpp b/cocos/2d/CCLabelTextFormatter.cpp index 0c674a5345..dc3bc82020 100644 --- a/cocos/2d/CCLabelTextFormatter.cpp +++ b/cocos/2d/CCLabelTextFormatter.cpp @@ -53,23 +53,26 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel) float startOfLine = -1, startOfWord = -1; int skip = 0; - - Array* children = theLabel->getChildrenLetters(); - - for (int j = 0; j < children->count(); j++) - { - Sprite* characterSprite; - unsigned int justSkipped = 0; + + int strLen = theLabel->getStringLenght(); + std::vector *leterInfo = theLabel->getLettersInfo(); + int tIndex = 0; + + for (int j = 0; j < strLen; j++) + { + LetterInfo* info = &leterInfo->at(j+skip); + + unsigned int justSkipped = 0; - while (!(characterSprite = theLabel->getSpriteChild(j + skip + justSkipped))) + while (info->def.validDefinition == false) { justSkipped++; + info = &leterInfo->at( j+skip+justSkipped ); } - skip += justSkipped; - - if (!characterSprite->isVisible()) - continue; + tIndex = j + skip; + //if (!info->visible) + // continue; if (i >= stringLength) break; @@ -78,7 +81,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel) if (!isStartOfWord) { - startOfWord = theLabel->getLetterPosXLeft( characterSprite ); + startOfWord = theLabel->getLetterPosXLeft( tIndex ); isStartOfWord = true; } @@ -110,7 +113,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel) if (!startOfWord) { - startOfWord = theLabel->getLetterPosXLeft( characterSprite ); + startOfWord = theLabel->getLetterPosXLeft( tIndex ); isStartOfWord = true; } if (!startOfLine) @@ -133,7 +136,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel) } // Out of bounds. - if (theLabel->getLetterPosXRight( characterSprite ) - startOfLine > theLabel->getMaxLineWidth()) + if (theLabel->getLetterPosXRight( tIndex ) - startOfLine > theLabel->getMaxLineWidth()) { if (!theLabel->breakLineWithoutSpace()) { @@ -171,7 +174,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel) if (!startOfWord) { - startOfWord = theLabel->getLetterPosXLeft( characterSprite ); + startOfWord = theLabel->getLetterPosXLeft( tIndex ); isStartOfWord = true; } if (!startOfLine) @@ -222,9 +225,10 @@ bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel) int lineNumber = 0; int strLen = cc_wcslen(theLabel->getUTF8String()); vector lastLine; + std::vector *leterInfo = theLabel->getLettersInfo(); for (int ctr = 0; ctr <= strLen; ++ctr) { - unsigned short int currentChar = theLabel->getCharAtStringPosition(ctr); + unsigned short int currentChar = theLabel->getCharAtStringPosition(ctr); if (currentChar == '\n' || currentChar == 0) { @@ -240,11 +244,12 @@ bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel) int index = i + lineLength - 1 + lineNumber; if (index < 0) continue; - Sprite* lastChar = theLabel->getSpriteChild(index); - if (lastChar == nullptr) + if(currentChar == 0) continue; - - lineWidth = lastChar->getPosition().x + lastChar->getContentSize().width / 2.0f; + LetterInfo* info = &leterInfo->at( index ); + if(info->def.validDefinition == false) + continue; + lineWidth = info->position.x + info->contentSize.width /2.0f; float shift = 0; switch (theLabel->getTextAlignment()) @@ -266,10 +271,11 @@ bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel) index = i + j + lineNumber; if (index < 0) continue; - Sprite* characterSprite = theLabel->getSpriteChild(index); - - if (characterSprite) - characterSprite->setPosition( characterSprite->getPosition() + Point(shift, 0.0f)); + info = &leterInfo->at( index ); + if(info) + { + info->position = info->position + Point(shift, 0.0f); + } } } @@ -336,15 +342,8 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel) { nextFontPositionX = 0; nextFontPositionY -= commonLineHeight; - continue; - } - - // get the sprite to this letter - Sprite *letterSprite = theLabel->getSpriteForChar(c, i); - - if (!letterSprite) - { - log("WARNING: can't find letter definition in font file for letter: %c", c); + + theLabel->recordPlaceholderInfo(i); continue; } @@ -354,10 +353,13 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel) Point fontPos = Point((float)nextFontPositionX + charXOffset + charRect.size.width * 0.5f + kerningAmount, (float)nextFontPositionY + yOffset - charRect.size.height * 0.5f); - - // set the sprite position - letterSprite->setPosition(CC_POINT_PIXELS_TO_POINTS(fontPos)); - + + if( theLabel->recordLetterInfo(CC_POINT_PIXELS_TO_POINTS(fontPos),c,i) == false) + { + log("WARNING: can't find letter definition in font file for letter: %c", c); + continue; + } + // update kerning nextFontPositionX += charAdvance + kerningAmount; prev = c; diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp index f22c5a7864..9aa5d20947 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp @@ -264,9 +264,9 @@ LabelFNTSpriteActions::LabelFNTSpriteActions() label->setAnchorPoint( Point(0.5f, 0.5f) ); - auto BChar = (Sprite*) label->getChildByTag(0); - auto FChar = (Sprite*) label->getChildByTag(7); - auto AChar = (Sprite*) label->getChildByTag(12); + auto BChar = (Sprite*) label->getLetterAt(0); + auto FChar = (Sprite*) label->getLetterAt(7); + auto AChar = (Sprite*) label->getLetterAt(12); auto rotate = RotateBy::create(2, 360); @@ -296,7 +296,7 @@ LabelFNTSpriteActions::LabelFNTSpriteActions() addChild(label2, 0, kTagBitmapAtlas2); label2->setPosition( Point(s.width/2.0f, 80) ); - auto lastChar = (Sprite*) label2->getChildByTag(1); + auto lastChar = (Sprite*) label2->getLetterAt(3); lastChar->runAction( rot_4ever->clone() ); schedule( schedule_selector(LabelFNTSpriteActions::step), 0.1f); From a68d92ff5a4f695e8d880230c011324aaba151fc Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Tue, 29 Oct 2013 20:30:24 +0800 Subject: [PATCH 080/144] perfect vs-project configuration --- .../cocosbuilder/proj.win32/libCocosBuilder.vcxproj | 8 ++++++-- .../cocostudio/proj.win32/libCocosStudio.vcxproj | 8 ++++++-- cocos/editor-support/spine/proj.win32/libSpine.vcxproj | 8 ++++++-- cocos/gui/proj.win32/libGUI.vcxproj | 8 ++++++-- .../local-storage/proj.win32/libLocalStorage.vcxproj | 8 ++++++-- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/cocos/editor-support/cocosbuilder/proj.win32/libCocosBuilder.vcxproj b/cocos/editor-support/cocosbuilder/proj.win32/libCocosBuilder.vcxproj index 2b44d72452..c6238489c7 100644 --- a/cocos/editor-support/cocosbuilder/proj.win32/libCocosBuilder.vcxproj +++ b/cocos/editor-support/cocosbuilder/proj.win32/libCocosBuilder.vcxproj @@ -18,13 +18,17 @@ StaticLibrary true - v110_xp + v100 + v110 + v110_xp Unicode StaticLibrary false - v110_xp + v100 + v110 + v110_xp true Unicode diff --git a/cocos/editor-support/cocostudio/proj.win32/libCocosStudio.vcxproj b/cocos/editor-support/cocostudio/proj.win32/libCocosStudio.vcxproj index d52ce8d931..77de7fdb61 100644 --- a/cocos/editor-support/cocostudio/proj.win32/libCocosStudio.vcxproj +++ b/cocos/editor-support/cocostudio/proj.win32/libCocosStudio.vcxproj @@ -106,13 +106,17 @@ StaticLibrary true - v110_xp + v100 + v110 + v110_xp Unicode StaticLibrary false - v110_xp + v100 + v110 + v110_xp true Unicode diff --git a/cocos/editor-support/spine/proj.win32/libSpine.vcxproj b/cocos/editor-support/spine/proj.win32/libSpine.vcxproj index b4fc436abf..b8bd4306b8 100644 --- a/cocos/editor-support/spine/proj.win32/libSpine.vcxproj +++ b/cocos/editor-support/spine/proj.win32/libSpine.vcxproj @@ -65,13 +65,17 @@ StaticLibrary true - v110_xp + v100 + v110 + v110_xp Unicode StaticLibrary false - v110_xp + v100 + v110 + v110_xp true Unicode diff --git a/cocos/gui/proj.win32/libGUI.vcxproj b/cocos/gui/proj.win32/libGUI.vcxproj index 1e483d4b85..b225eaa127 100644 --- a/cocos/gui/proj.win32/libGUI.vcxproj +++ b/cocos/gui/proj.win32/libGUI.vcxproj @@ -67,13 +67,17 @@ StaticLibrary true - v110_xp + v100 + v110 + v110_xp Unicode StaticLibrary false - v110_xp + v100 + v110 + v110_xp true Unicode diff --git a/cocos/storage/local-storage/proj.win32/libLocalStorage.vcxproj b/cocos/storage/local-storage/proj.win32/libLocalStorage.vcxproj index d79eb7ce1c..3413ec57b0 100644 --- a/cocos/storage/local-storage/proj.win32/libLocalStorage.vcxproj +++ b/cocos/storage/local-storage/proj.win32/libLocalStorage.vcxproj @@ -24,13 +24,17 @@ StaticLibrary true - v110_xp + v100 + v110 + v110_xp Unicode StaticLibrary false - v110_xp + v100 + v110 + v110_xp true Unicode From 379bcb194c43f1e410d6c5eb18893e9ad398f3a0 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 30 Oct 2013 21:55:19 +0800 Subject: [PATCH 081/144] [sp v25] Updating SpiderMonkey library to FFv25. --- .../spidermonkey/include/android/js-config.h | 6 +- external/spidermonkey/include/android/js.msg | 29 +- .../spidermonkey/include/android/js/Anchor.h | 6 +- .../include/android/js/CallArgs.h | 187 ++- .../include/android/js/CharacterEncoding.h | 48 +- .../spidermonkey/include/android/js/Date.h | 6 +- .../spidermonkey/include/android/js/GCAPI.h | 15 +- .../include/android/js/HashTable.h | 132 +- .../spidermonkey/include/android/js/HeapAPI.h | 29 +- .../include/android/js/LegacyIntTypes.h | 11 +- .../include/android/js/MemoryMetrics.h | 27 +- .../include/android/js/PropertyKey.h | 6 +- .../include/android/js/RequiredDefines.h | 6 +- .../include/android/js/RootingAPI.h | 493 +++++-- .../include/android/js/TemplateLib.h | 117 -- .../spidermonkey/include/android/js/Utility.h | 403 +----- .../spidermonkey/include/android/js/Value.h | 152 ++- .../spidermonkey/include/android/js/Vector.h | 1119 +--------------- .../spidermonkey/include/android/jsalloc.h | 37 +- .../include/android/jsapi.h.REMOVED.git-id | 2 +- .../spidermonkey/include/android/jsclass.h | 26 +- .../spidermonkey/include/android/jsclist.h | 6 +- .../spidermonkey/include/android/jscpucfg.h | 6 +- .../spidermonkey/include/android/jsdbgapi.h | 19 +- .../spidermonkey/include/android/jsdhash.h | 612 --------- .../include/android/jsfriendapi.h | 477 ++++++- .../spidermonkey/include/android/jslock.h | 13 +- external/spidermonkey/include/android/json.h | 48 - .../spidermonkey/include/android/jsperf.h | 6 +- external/spidermonkey/include/android/jsprf.h | 12 +- .../include/android/jsprototypes.h | 21 +- .../spidermonkey/include/android/jsproxy.h | 52 +- .../spidermonkey/include/android/jsprvtd.h | 38 +- .../spidermonkey/include/android/jspubtd.h | 66 +- .../spidermonkey/include/android/jstypes.h | 6 +- .../spidermonkey/include/android/jsutil.h | 21 +- .../spidermonkey/include/android/jsversion.h | 8 +- .../spidermonkey/include/android/jswrapper.h | 14 +- .../include/android/mozilla/AllocPolicy.h | 63 + .../include/android/mozilla/Array.h | 51 + .../include/android/mozilla/Assertions.h | 294 ++-- .../include/android/mozilla/Atomics.h | 1014 ++++++++++++++ .../include/android/mozilla/Attributes.h | 46 +- .../include/android/mozilla/BloomFilter.h | 17 +- .../include/android/mozilla/Casting.h | 58 +- .../include/android/mozilla/Char16.h | 15 +- .../include/android/mozilla/CheckedInt.h | 110 +- .../include/android/mozilla/Compiler.h | 9 +- .../include/android/mozilla/Constants.h | 9 +- .../include/android/mozilla/DebugOnly.h | 9 +- .../include/android/mozilla/Decimal.h | 2 +- .../include/android/mozilla/Endian.h | 11 +- .../include/android/mozilla/EnumSet.h | 8 +- .../include/android/mozilla/FloatingPoint.h | 135 +- .../include/android/mozilla/GuardObjects.h | 6 +- .../include/android/mozilla/HashFunctions.h | 23 +- .../include/android/mozilla/Likely.h | 13 +- .../include/android/mozilla/LinkedList.h | 61 +- .../include/android/mozilla/MSStdInt.h | 247 ---- .../include/android/mozilla/MathAlgorithms.h | 293 +++- .../include/android/mozilla/MemoryChecking.h | 9 +- .../include/android/mozilla/MemoryReporting.h | 30 + .../include/android/mozilla/Move.h | 166 +++ .../include/android/mozilla/NullPtr.h | 9 +- .../include/android/mozilla/PodOperations.h | 5 +- .../include/android/mozilla/Poison.h | 13 +- .../include/android/mozilla/Range.h | 18 +- .../include/android/mozilla/RangedPtr.h | 12 +- .../include/android/mozilla/ReentrancyGuard.h | 57 + .../include/android/mozilla/RefPtr.h | 55 +- .../include/android/mozilla/SHA1.h | 11 +- .../include/android/mozilla/Scoped.h | 17 +- .../include/android/mozilla/SplayTree.h | 13 +- .../include/android/mozilla/StandardInteger.h | 43 - .../include/android/mozilla/TemplateLib.h | 111 ++ .../include/android/mozilla/ThreadLocal.h | 22 +- .../include/android/mozilla/TypeTraits.h | 229 +++- .../include/android/mozilla/TypedEnum.h | 47 +- .../include/android/mozilla/Types.h | 28 +- .../include/android/mozilla/Util.h | 63 +- .../include/android/mozilla/Vector.h | 1190 +++++++++++++++++ .../include/android/mozilla/WeakPtr.h | 55 +- external/spidermonkey/include/ios/js-config.h | 6 +- external/spidermonkey/include/ios/js.msg | 29 +- external/spidermonkey/include/ios/js/Anchor.h | 6 +- .../spidermonkey/include/ios/js/CallArgs.h | 187 ++- .../include/ios/js/CharacterEncoding.h | 48 +- external/spidermonkey/include/ios/js/Date.h | 6 +- external/spidermonkey/include/ios/js/GCAPI.h | 15 +- .../spidermonkey/include/ios/js/HashTable.h | 132 +- .../spidermonkey/include/ios/js/HeapAPI.h | 29 +- .../include/ios/js/LegacyIntTypes.h | 11 +- .../include/ios/js/MemoryMetrics.h | 27 +- .../spidermonkey/include/ios/js/PropertyKey.h | 6 +- .../include/ios/js/RequiredDefines.h | 6 +- .../spidermonkey/include/ios/js/RootingAPI.h | 493 +++++-- .../spidermonkey/include/ios/js/TemplateLib.h | 117 -- .../spidermonkey/include/ios/js/Utility.h | 403 +----- external/spidermonkey/include/ios/js/Value.h | 152 ++- external/spidermonkey/include/ios/js/Vector.h | 1119 +--------------- external/spidermonkey/include/ios/jsalloc.h | 37 +- .../include/ios/jsapi.h.REMOVED.git-id | 2 +- external/spidermonkey/include/ios/jsclass.h | 26 +- external/spidermonkey/include/ios/jsclist.h | 6 +- external/spidermonkey/include/ios/jscpucfg.h | 6 +- external/spidermonkey/include/ios/jsdbgapi.h | 19 +- external/spidermonkey/include/ios/jsdhash.h | 612 --------- .../spidermonkey/include/ios/jsfriendapi.h | 477 ++++++- external/spidermonkey/include/ios/jslock.h | 13 +- external/spidermonkey/include/ios/json.h | 48 - external/spidermonkey/include/ios/jsperf.h | 6 +- external/spidermonkey/include/ios/jsprf.h | 12 +- .../spidermonkey/include/ios/jsprototypes.h | 21 +- external/spidermonkey/include/ios/jsproxy.h | 52 +- external/spidermonkey/include/ios/jsprvtd.h | 38 +- external/spidermonkey/include/ios/jspubtd.h | 66 +- external/spidermonkey/include/ios/jstypes.h | 6 +- external/spidermonkey/include/ios/jsutil.h | 21 +- external/spidermonkey/include/ios/jsversion.h | 8 +- external/spidermonkey/include/ios/jswrapper.h | 14 +- .../include/ios/mozilla/AllocPolicy.h | 63 + .../spidermonkey/include/ios/mozilla/Array.h | 51 + .../include/ios/mozilla/Assertions.h | 294 ++-- .../include/ios/mozilla/Atomics.h | 1014 ++++++++++++++ .../include/ios/mozilla/Attributes.h | 46 +- .../include/ios/mozilla/BloomFilter.h | 17 +- .../include/ios/mozilla/Casting.h | 58 +- .../spidermonkey/include/ios/mozilla/Char16.h | 15 +- .../include/ios/mozilla/CheckedInt.h | 110 +- .../include/ios/mozilla/Compiler.h | 9 +- .../include/ios/mozilla/Constants.h | 9 +- .../include/ios/mozilla/DebugOnly.h | 9 +- .../include/ios/mozilla/Decimal.h | 2 +- .../spidermonkey/include/ios/mozilla/Endian.h | 11 +- .../include/ios/mozilla/EnumSet.h | 8 +- .../include/ios/mozilla/FloatingPoint.h | 135 +- .../include/ios/mozilla/GuardObjects.h | 6 +- .../include/ios/mozilla/HashFunctions.h | 23 +- .../spidermonkey/include/ios/mozilla/Likely.h | 13 +- .../include/ios/mozilla/LinkedList.h | 61 +- .../include/ios/mozilla/MSStdInt.h | 247 ---- .../include/ios/mozilla/MathAlgorithms.h | 293 +++- .../include/ios/mozilla/MemoryChecking.h | 9 +- .../include/ios/mozilla/MemoryReporting.h | 30 + .../spidermonkey/include/ios/mozilla/Move.h | 166 +++ .../include/ios/mozilla/NullPtr.h | 9 +- .../include/ios/mozilla/PodOperations.h | 5 +- .../spidermonkey/include/ios/mozilla/Poison.h | 13 +- .../spidermonkey/include/ios/mozilla/Range.h | 18 +- .../include/ios/mozilla/RangedPtr.h | 12 +- .../include/ios/mozilla/ReentrancyGuard.h | 57 + .../spidermonkey/include/ios/mozilla/RefPtr.h | 55 +- .../spidermonkey/include/ios/mozilla/SHA1.h | 11 +- .../spidermonkey/include/ios/mozilla/Scoped.h | 17 +- .../include/ios/mozilla/SplayTree.h | 13 +- .../include/ios/mozilla/StandardInteger.h | 43 - .../include/ios/mozilla/TemplateLib.h | 111 ++ .../include/ios/mozilla/ThreadLocal.h | 22 +- .../include/ios/mozilla/TypeTraits.h | 229 +++- .../include/ios/mozilla/TypedEnum.h | 47 +- .../spidermonkey/include/ios/mozilla/Types.h | 28 +- .../spidermonkey/include/ios/mozilla/Util.h | 63 +- .../spidermonkey/include/ios/mozilla/Vector.h | 1190 +++++++++++++++++ .../include/ios/mozilla/WeakPtr.h | 55 +- external/spidermonkey/include/mac/js-config.h | 6 +- external/spidermonkey/include/mac/js.msg | 29 +- external/spidermonkey/include/mac/js/Anchor.h | 6 +- .../spidermonkey/include/mac/js/CallArgs.h | 187 ++- .../include/mac/js/CharacterEncoding.h | 48 +- external/spidermonkey/include/mac/js/Date.h | 6 +- external/spidermonkey/include/mac/js/GCAPI.h | 15 +- .../spidermonkey/include/mac/js/HashTable.h | 132 +- .../spidermonkey/include/mac/js/HeapAPI.h | 29 +- .../include/mac/js/LegacyIntTypes.h | 11 +- .../include/mac/js/MemoryMetrics.h | 27 +- .../spidermonkey/include/mac/js/PropertyKey.h | 6 +- .../include/mac/js/RequiredDefines.h | 6 +- .../spidermonkey/include/mac/js/RootingAPI.h | 493 +++++-- .../spidermonkey/include/mac/js/TemplateLib.h | 117 -- .../spidermonkey/include/mac/js/Utility.h | 403 +----- external/spidermonkey/include/mac/js/Value.h | 152 ++- external/spidermonkey/include/mac/js/Vector.h | 1119 +--------------- external/spidermonkey/include/mac/jsalloc.h | 37 +- .../include/mac/jsapi.h.REMOVED.git-id | 2 +- external/spidermonkey/include/mac/jsclass.h | 26 +- external/spidermonkey/include/mac/jsclist.h | 6 +- external/spidermonkey/include/mac/jscpucfg.h | 6 +- external/spidermonkey/include/mac/jsdbgapi.h | 19 +- external/spidermonkey/include/mac/jsdhash.h | 612 --------- .../spidermonkey/include/mac/jsfriendapi.h | 477 ++++++- external/spidermonkey/include/mac/jslock.h | 13 +- external/spidermonkey/include/mac/json.h | 48 - external/spidermonkey/include/mac/jsperf.h | 6 +- external/spidermonkey/include/mac/jsprf.h | 12 +- .../spidermonkey/include/mac/jsprototypes.h | 21 +- external/spidermonkey/include/mac/jsproxy.h | 52 +- external/spidermonkey/include/mac/jsprvtd.h | 38 +- external/spidermonkey/include/mac/jspubtd.h | 66 +- external/spidermonkey/include/mac/jstypes.h | 6 +- external/spidermonkey/include/mac/jsutil.h | 21 +- external/spidermonkey/include/mac/jsversion.h | 8 +- external/spidermonkey/include/mac/jswrapper.h | 14 +- .../include/mac/mozilla/AllocPolicy.h | 63 + .../spidermonkey/include/mac/mozilla/Array.h | 51 + .../include/mac/mozilla/Assertions.h | 294 ++-- .../include/mac/mozilla/Atomics.h | 1014 ++++++++++++++ .../include/mac/mozilla/Attributes.h | 46 +- .../include/mac/mozilla/BloomFilter.h | 17 +- .../include/mac/mozilla/Casting.h | 58 +- .../spidermonkey/include/mac/mozilla/Char16.h | 15 +- .../include/mac/mozilla/CheckedInt.h | 110 +- .../include/mac/mozilla/Compiler.h | 9 +- .../include/mac/mozilla/Constants.h | 9 +- .../include/mac/mozilla/DebugOnly.h | 9 +- .../include/mac/mozilla/Decimal.h | 2 +- .../spidermonkey/include/mac/mozilla/Endian.h | 11 +- .../include/mac/mozilla/EnumSet.h | 8 +- .../include/mac/mozilla/FloatingPoint.h | 135 +- .../include/mac/mozilla/GuardObjects.h | 6 +- .../include/mac/mozilla/HashFunctions.h | 23 +- .../spidermonkey/include/mac/mozilla/Likely.h | 13 +- .../include/mac/mozilla/LinkedList.h | 61 +- .../include/mac/mozilla/MSStdInt.h | 247 ---- .../include/mac/mozilla/MathAlgorithms.h | 293 +++- .../include/mac/mozilla/MemoryChecking.h | 9 +- .../include/mac/mozilla/MemoryReporting.h | 30 + .../spidermonkey/include/mac/mozilla/Move.h | 166 +++ .../include/mac/mozilla/NullPtr.h | 9 +- .../include/mac/mozilla/PodOperations.h | 5 +- .../spidermonkey/include/mac/mozilla/Poison.h | 13 +- .../spidermonkey/include/mac/mozilla/Range.h | 18 +- .../include/mac/mozilla/RangedPtr.h | 12 +- .../include/mac/mozilla/ReentrancyGuard.h | 57 + .../spidermonkey/include/mac/mozilla/RefPtr.h | 55 +- .../spidermonkey/include/mac/mozilla/SHA1.h | 11 +- .../spidermonkey/include/mac/mozilla/Scoped.h | 17 +- .../include/mac/mozilla/SplayTree.h | 13 +- .../include/mac/mozilla/StandardInteger.h | 43 - .../include/mac/mozilla/TemplateLib.h | 111 ++ .../include/mac/mozilla/ThreadLocal.h | 22 +- .../include/mac/mozilla/TypeTraits.h | 229 +++- .../include/mac/mozilla/TypedEnum.h | 47 +- .../spidermonkey/include/mac/mozilla/Types.h | 28 +- .../spidermonkey/include/mac/mozilla/Util.h | 63 +- .../spidermonkey/include/mac/mozilla/Vector.h | 1190 +++++++++++++++++ .../include/mac/mozilla/WeakPtr.h | 55 +- .../spidermonkey/include/win32/js-config.h | 6 +- external/spidermonkey/include/win32/js.msg | 29 +- .../spidermonkey/include/win32/js/Anchor.h | 6 +- .../spidermonkey/include/win32/js/CallArgs.h | 187 ++- .../include/win32/js/CharacterEncoding.h | 48 +- external/spidermonkey/include/win32/js/Date.h | 6 +- .../spidermonkey/include/win32/js/GCAPI.h | 15 +- .../spidermonkey/include/win32/js/HashTable.h | 132 +- .../spidermonkey/include/win32/js/HeapAPI.h | 29 +- .../include/win32/js/LegacyIntTypes.h | 11 +- .../include/win32/js/MemoryMetrics.h | 27 +- .../include/win32/js/PropertyKey.h | 6 +- .../include/win32/js/RequiredDefines.h | 6 +- .../include/win32/js/RootingAPI.h | 493 +++++-- .../include/win32/js/TemplateLib.h | 117 -- .../spidermonkey/include/win32/js/Utility.h | 403 +----- .../spidermonkey/include/win32/js/Value.h | 152 ++- .../spidermonkey/include/win32/js/Vector.h | 1119 +--------------- external/spidermonkey/include/win32/jsalloc.h | 37 +- .../include/win32/jsapi.h.REMOVED.git-id | 2 +- external/spidermonkey/include/win32/jsclass.h | 26 +- external/spidermonkey/include/win32/jsclist.h | 6 +- .../spidermonkey/include/win32/jscpucfg.h | 6 +- .../spidermonkey/include/win32/jsdbgapi.h | 19 +- external/spidermonkey/include/win32/jsdhash.h | 612 --------- .../spidermonkey/include/win32/jsfriendapi.h | 477 ++++++- external/spidermonkey/include/win32/jslock.h | 13 +- external/spidermonkey/include/win32/json.h | 48 - external/spidermonkey/include/win32/jsperf.h | 6 +- external/spidermonkey/include/win32/jsprf.h | 12 +- .../spidermonkey/include/win32/jsprototypes.h | 21 +- external/spidermonkey/include/win32/jsproxy.h | 52 +- external/spidermonkey/include/win32/jsprvtd.h | 38 +- external/spidermonkey/include/win32/jspubtd.h | 66 +- external/spidermonkey/include/win32/jstypes.h | 6 +- external/spidermonkey/include/win32/jsutil.h | 21 +- .../spidermonkey/include/win32/jsversion.h | 8 +- .../spidermonkey/include/win32/jswrapper.h | 14 +- .../include/win32/mozilla/AllocPolicy.h | 63 + .../include/win32/mozilla/Array.h | 51 + .../include/win32/mozilla/Assertions.h | 294 ++-- .../include/win32/mozilla/Atomics.h | 1014 ++++++++++++++ .../include/win32/mozilla/Attributes.h | 46 +- .../include/win32/mozilla/BloomFilter.h | 17 +- .../include/win32/mozilla/Casting.h | 58 +- .../include/win32/mozilla/Char16.h | 15 +- .../include/win32/mozilla/CheckedInt.h | 110 +- .../include/win32/mozilla/Compiler.h | 9 +- .../include/win32/mozilla/Constants.h | 9 +- .../include/win32/mozilla/DebugOnly.h | 9 +- .../include/win32/mozilla/Decimal.h | 2 +- .../include/win32/mozilla/Endian.h | 11 +- .../include/win32/mozilla/EnumSet.h | 8 +- .../include/win32/mozilla/FloatingPoint.h | 135 +- .../include/win32/mozilla/GuardObjects.h | 6 +- .../include/win32/mozilla/HashFunctions.h | 23 +- .../include/win32/mozilla/Likely.h | 13 +- .../include/win32/mozilla/LinkedList.h | 61 +- .../include/win32/mozilla/MSStdInt.h | 247 ---- .../include/win32/mozilla/MathAlgorithms.h | 293 +++- .../include/win32/mozilla/MemoryChecking.h | 9 +- .../include/win32/mozilla/MemoryReporting.h | 30 + .../spidermonkey/include/win32/mozilla/Move.h | 166 +++ .../include/win32/mozilla/NullPtr.h | 9 +- .../include/win32/mozilla/PodOperations.h | 5 +- .../include/win32/mozilla/Poison.h | 13 +- .../include/win32/mozilla/Range.h | 18 +- .../include/win32/mozilla/RangedPtr.h | 12 +- .../include/win32/mozilla/ReentrancyGuard.h | 57 + .../include/win32/mozilla/RefPtr.h | 55 +- .../spidermonkey/include/win32/mozilla/SHA1.h | 11 +- .../include/win32/mozilla/Scoped.h | 17 +- .../include/win32/mozilla/SplayTree.h | 13 +- .../include/win32/mozilla/StandardInteger.h | 43 - .../include/win32/mozilla/TemplateLib.h | 111 ++ .../include/win32/mozilla/ThreadLocal.h | 22 +- .../include/win32/mozilla/TypeTraits.h | 229 +++- .../include/win32/mozilla/TypedEnum.h | 47 +- .../include/win32/mozilla/Types.h | 28 +- .../spidermonkey/include/win32/mozilla/Util.h | 63 +- .../include/win32/mozilla/Vector.h | 1190 +++++++++++++++++ .../include/win32/mozilla/WeakPtr.h | 55 +- .../armeabi-v7a/libjs_static.a.REMOVED.git-id | 2 +- .../armeabi/libjs_static.a.REMOVED.git-id | 2 +- .../android/x86/libjs_static.a.REMOVED.git-id | 2 +- .../ios/libjs_static.a.REMOVED.git-id | 2 +- .../mac/libjs_static.a.REMOVED.git-id | 2 +- .../win32/mozjs-23.0.dll.REMOVED.git-id | 1 - .../win32/mozjs-23.0.lib.REMOVED.git-id | 1 - .../win32/mozjs-25.0.dll.REMOVED.git-id | 1 + .../win32/mozjs-25.0.lib.REMOVED.git-id | 1 + 337 files changed, 21639 insertions(+), 14291 deletions(-) delete mode 100644 external/spidermonkey/include/android/js/TemplateLib.h delete mode 100644 external/spidermonkey/include/android/jsdhash.h delete mode 100644 external/spidermonkey/include/android/json.h create mode 100644 external/spidermonkey/include/android/mozilla/AllocPolicy.h create mode 100644 external/spidermonkey/include/android/mozilla/Array.h create mode 100644 external/spidermonkey/include/android/mozilla/Atomics.h delete mode 100644 external/spidermonkey/include/android/mozilla/MSStdInt.h create mode 100644 external/spidermonkey/include/android/mozilla/MemoryReporting.h create mode 100644 external/spidermonkey/include/android/mozilla/Move.h create mode 100644 external/spidermonkey/include/android/mozilla/ReentrancyGuard.h delete mode 100644 external/spidermonkey/include/android/mozilla/StandardInteger.h create mode 100644 external/spidermonkey/include/android/mozilla/TemplateLib.h create mode 100644 external/spidermonkey/include/android/mozilla/Vector.h delete mode 100644 external/spidermonkey/include/ios/js/TemplateLib.h delete mode 100644 external/spidermonkey/include/ios/jsdhash.h delete mode 100644 external/spidermonkey/include/ios/json.h create mode 100644 external/spidermonkey/include/ios/mozilla/AllocPolicy.h create mode 100644 external/spidermonkey/include/ios/mozilla/Array.h create mode 100644 external/spidermonkey/include/ios/mozilla/Atomics.h delete mode 100644 external/spidermonkey/include/ios/mozilla/MSStdInt.h create mode 100644 external/spidermonkey/include/ios/mozilla/MemoryReporting.h create mode 100644 external/spidermonkey/include/ios/mozilla/Move.h create mode 100644 external/spidermonkey/include/ios/mozilla/ReentrancyGuard.h delete mode 100644 external/spidermonkey/include/ios/mozilla/StandardInteger.h create mode 100644 external/spidermonkey/include/ios/mozilla/TemplateLib.h create mode 100644 external/spidermonkey/include/ios/mozilla/Vector.h delete mode 100644 external/spidermonkey/include/mac/js/TemplateLib.h delete mode 100644 external/spidermonkey/include/mac/jsdhash.h delete mode 100644 external/spidermonkey/include/mac/json.h create mode 100644 external/spidermonkey/include/mac/mozilla/AllocPolicy.h create mode 100644 external/spidermonkey/include/mac/mozilla/Array.h create mode 100644 external/spidermonkey/include/mac/mozilla/Atomics.h delete mode 100644 external/spidermonkey/include/mac/mozilla/MSStdInt.h create mode 100644 external/spidermonkey/include/mac/mozilla/MemoryReporting.h create mode 100644 external/spidermonkey/include/mac/mozilla/Move.h create mode 100644 external/spidermonkey/include/mac/mozilla/ReentrancyGuard.h delete mode 100644 external/spidermonkey/include/mac/mozilla/StandardInteger.h create mode 100644 external/spidermonkey/include/mac/mozilla/TemplateLib.h create mode 100644 external/spidermonkey/include/mac/mozilla/Vector.h delete mode 100644 external/spidermonkey/include/win32/js/TemplateLib.h delete mode 100644 external/spidermonkey/include/win32/jsdhash.h delete mode 100644 external/spidermonkey/include/win32/json.h create mode 100644 external/spidermonkey/include/win32/mozilla/AllocPolicy.h create mode 100644 external/spidermonkey/include/win32/mozilla/Array.h create mode 100644 external/spidermonkey/include/win32/mozilla/Atomics.h delete mode 100644 external/spidermonkey/include/win32/mozilla/MSStdInt.h create mode 100644 external/spidermonkey/include/win32/mozilla/MemoryReporting.h create mode 100644 external/spidermonkey/include/win32/mozilla/Move.h create mode 100644 external/spidermonkey/include/win32/mozilla/ReentrancyGuard.h delete mode 100644 external/spidermonkey/include/win32/mozilla/StandardInteger.h create mode 100644 external/spidermonkey/include/win32/mozilla/TemplateLib.h create mode 100644 external/spidermonkey/include/win32/mozilla/Vector.h delete mode 100644 external/spidermonkey/prebuilt/win32/mozjs-23.0.dll.REMOVED.git-id delete mode 100644 external/spidermonkey/prebuilt/win32/mozjs-23.0.lib.REMOVED.git-id create mode 100644 external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id create mode 100644 external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id diff --git a/external/spidermonkey/include/android/js-config.h b/external/spidermonkey/include/android/js-config.h index 793bdb0a9f..4b893482f4 100644 --- a/external/spidermonkey/include/android/js-config.h +++ b/external/spidermonkey/include/android/js-config.h @@ -38,8 +38,8 @@ JS_HAVE_STDINT_H. */ #define JS_BYTES_PER_WORD 4 -/* Some mozilla code uses JS-friend APIs that depend on JS_METHODJIT being - correct. */ -#define JS_METHODJIT 1 +/* MOZILLA JSAPI version number components */ +#define MOZJS_MAJOR_VERSION 25 +#define MOZJS_MINOR_VERSION 0 #endif /* js_config_h___ */ diff --git a/external/spidermonkey/include/android/js.msg b/external/spidermonkey/include/android/js.msg index 3e57bdf174..3f665d8d54 100644 --- a/external/spidermonkey/include/android/js.msg +++ b/external/spidermonkey/include/android/js.msg @@ -184,7 +184,7 @@ MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} oper MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id") MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error") -MSG_DEF(JSMSG_UNUSED134, 134, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 134, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent") MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory") @@ -193,10 +193,10 @@ MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many paren MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment") MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_UNUSED143, 143, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 143, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_UNUSED146, 146, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 146, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses") @@ -220,7 +220,7 @@ MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot ind MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals") MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_UNUSED170, 170, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 170, 0, JSEXN_RANGEERR, "repeat count must be non-negative") MSG_DEF(JSMSG_UNUSED171, 171, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED172, 172, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED173, 173, 0, JSEXN_NONE, "") @@ -286,7 +286,7 @@ MSG_DEF(JSMSG_DEPRECATED_OCTAL, 232, 0, JSEXN_SYNTAXERR, "octal literals a MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated") +MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "can't assign to {0} in strict mode") MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 238, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 239, 1, JSEXN_TYPEERR, "{0} is not extensible") @@ -313,16 +313,16 @@ MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 259, 0, JSEXN_TYPEERR, "can't change ob MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 260, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 261, 0, JSEXN_TYPEERR, "unsupported type for structured data") MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive object") -MSG_DEF(JSMSG_UNUSED263, 263, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 263, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee") MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version") MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_UNUSED266, 266, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 266, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function") MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer") MSG_DEF(JSMSG_CLEARED_SCOPE, 269, 0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope") MSG_DEF(JSMSG_MALFORMED_ESCAPE, 270, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") MSG_DEF(JSMSG_BAD_GENEXP_BODY, 271, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_UNUSED272, 272, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_YIELD_WITHOUT_OPERAND, 272, 0, JSEXN_SYNTAXERR, "yield without a value is deprecated, and illegal in ES6 (use 'yield undefined' instead)") MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 273, 0, JSEXN_SYNTAXERR, "function statement requires a name") MSG_DEF(JSMSG_CCW_REQUIRED, 274, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 275, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") @@ -391,12 +391,21 @@ MSG_DEF(JSMSG_DATE_NOT_FINITE, 337, 0, JSEXN_RANGEERR, "date value is not MSG_DEF(JSMSG_MODULE_STATEMENT, 338, 0, JSEXN_SYNTAXERR, "module declarations may only appear at the top level of a program or module body") MSG_DEF(JSMSG_CURLY_BEFORE_MODULE, 339, 0, JSEXN_SYNTAXERR, "missing { before module body") MSG_DEF(JSMSG_CURLY_AFTER_MODULE, 340, 0, JSEXN_SYNTAXERR, "missing } after module body") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "'use asm' directive only works on function code") +MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 342, 1, JSEXN_TYPEERR, "asm.js type error: {0}") MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 343, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 0, JSEXN_ERR, "successfully compiled asm.js code") +MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 1, JSEXN_ERR, "successfully compiled asm.js code ({0})") MSG_DEF(JSMSG_BAD_ARROW_ARGS, 345, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") MSG_DEF(JSMSG_YIELD_IN_ARROW, 346, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") MSG_DEF(JSMSG_WRONG_VALUE, 347, 2, JSEXN_ERR, "expected {0} but found {1}") MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, 348, 1, JSEXN_ERR, "target for index {0} is not an integer") MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME,349, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") +MSG_DEF(JSMSG_DEPRECATED_SOURCE_MAP, 350, 0, JSEXN_SYNTAXERR, "Using //@ to indicate source map URL pragmas is deprecated. Use //# instead") +MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN, 351, 1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment") +MSG_DEF(JSMSG_BINARYDATA_ARRAYTYPE_BAD_ARGS, 352, 0, JSEXN_ERR, "Invalid arguments") +MSG_DEF(JSMSG_BINARYDATA_BINARYARRAY_BAD_INDEX, 353, 0, JSEXN_RANGEERR, "invalid or out-of-range index") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_ARGS, 354, 0, JSEXN_RANGEERR, "invalid field descriptor") +MSG_DEF(JSMSG_BINARYDATA_NOT_BINARYSTRUCT, 355, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct") +MSG_DEF(JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor") diff --git a/external/spidermonkey/include/android/js/Anchor.h b/external/spidermonkey/include/android/js/Anchor.h index d0c2476cf7..0d458e6fb6 100644 --- a/external/spidermonkey/include/android/js/Anchor.h +++ b/external/spidermonkey/include/android/js/Anchor.h @@ -6,8 +6,8 @@ /* JS::Anchor implementation. */ -#ifndef js_Anchor_h___ -#define js_Anchor_h___ +#ifndef js_Anchor_h +#define js_Anchor_h #include "mozilla/Attributes.h" @@ -159,4 +159,4 @@ inline Anchor::~Anchor() } // namespace JS -#endif /* js_Anchor_h___ */ +#endif /* js_Anchor_h */ diff --git a/external/spidermonkey/include/android/js/CallArgs.h b/external/spidermonkey/include/android/js/CallArgs.h index af78fde0a0..8027ffc71a 100644 --- a/external/spidermonkey/include/android/js/CallArgs.h +++ b/external/spidermonkey/include/android/js/CallArgs.h @@ -26,11 +26,12 @@ * methods' implementations, potentially under time pressure. */ -#ifndef js_CallArgs_h___ -#define js_CallArgs_h___ +#ifndef js_CallArgs_h +#define js_CallArgs_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/TypeTraits.h" #include "jstypes.h" @@ -44,6 +45,29 @@ class JSObject; typedef JSBool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp); +/* Typedef for native functions that may be called in parallel. */ +typedef js::ParallelResult +(* JSParallelNative)(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + +/* + * Typedef for native functions that may be called either in parallel or + * sequential execution. + */ +typedef JSBool +(* JSThreadSafeNative)(js::ThreadSafeContext *cx, unsigned argc, JS::Value *vp); + +/* + * Convenience wrappers for passing in ThreadSafeNative to places that expect + * a JSNative or a JSParallelNative. + */ +template +inline JSBool +JSNativeThreadSafeWrapper(JSContext *cx, unsigned argc, JS::Value *vp); + +template +inline js::ParallelResult +JSParallelNativeThreadSafeWrapper(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + /* * Compute |this| for the |vp| inside a JSNative, either boxing primitives or * replacing with the global object as necessary. @@ -58,6 +82,8 @@ JS_ComputeThis(JSContext *cx, JS::Value *vp); namespace JS { +extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; + /* * JS::CallReceiver encapsulates access to the callee, |this|, and eventual * return value for a function call. The principal way to create a @@ -92,30 +118,55 @@ namespace JS { * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallReceiver + +namespace detail { + +#ifdef DEBUG +extern JS_PUBLIC_API(void) +CheckIsValidConstructible(Value v); +#endif + +enum UsedRval { IncludeUsedRval, NoUsedRval }; + +template +class MOZ_STACK_CLASS UsedRvalBase; + +template<> +class MOZ_STACK_CLASS UsedRvalBase { protected: -#ifdef DEBUG mutable bool usedRval_; void setUsedRval() const { usedRval_ = true; } void clearUsedRval() const { usedRval_ = false; } -#else +}; + +template<> +class MOZ_STACK_CLASS UsedRvalBase +{ + protected: void setUsedRval() const {} void clearUsedRval() const {} +}; + +template +class MOZ_STACK_CLASS CallReceiverBase : public UsedRvalBase< +#ifdef DEBUG + WantUsedRval +#else + NoUsedRval #endif - + > +{ + protected: Value *argv_; - friend CallReceiver CallReceiverFromVp(Value *vp); - friend CallReceiver CallReceiverFromArgv(Value *argv); - public: /* * Returns the function being called, as an object. Must not be called * after rval() has been used! */ JSObject &callee() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return argv_[-2].toObject(); } @@ -124,7 +175,7 @@ class MOZ_STACK_CLASS CallReceiver * rval() has been used! */ HandleValue calleev() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return HandleValue::fromMarkedLocation(&argv_[-2]); } @@ -148,6 +199,14 @@ class MOZ_STACK_CLASS CallReceiver return JS_ComputeThis(cx, base()); } + bool isConstructing() const { +#ifdef DEBUG + if (this->usedRval_) + CheckIsValidConstructible(calleev()); +#endif + return argv_[-1].isMagic(); + } + /* * Returns the currently-set return value. The initial contents of this * value are unspecified. Once this method has been called, callee() and @@ -160,7 +219,7 @@ class MOZ_STACK_CLASS CallReceiver * fails. */ MutableHandleValue rval() const { - setUsedRval(); + this->setUsedRval(); return MutableHandleValue::fromMarkedLocation(&argv_[-2]); } @@ -171,7 +230,7 @@ class MOZ_STACK_CLASS CallReceiver Value *base() const { return argv_ - 2; } Value *spAfterCall() const { - setUsedRval(); + this->setUsedRval(); return argv_ - 1; } @@ -181,7 +240,7 @@ class MOZ_STACK_CLASS CallReceiver // it. You probably don't want to use these! void setCallee(Value aCalleev) const { - clearUsedRval(); + this->clearUsedRval(); argv_[-2] = aCalleev; } @@ -194,6 +253,15 @@ class MOZ_STACK_CLASS CallReceiver } }; +} // namespace detail + +class MOZ_STACK_CLASS CallReceiver : public detail::CallReceiverBase +{ + private: + friend CallReceiver CallReceiverFromVp(Value *vp); + friend CallReceiver CallReceiverFromArgv(Value *argv); +}; + MOZ_ALWAYS_INLINE CallReceiver CallReceiverFromArgv(Value *argv) { @@ -233,11 +301,59 @@ CallReceiverFromVp(Value *vp) * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallArgs : public CallReceiver +namespace detail { + +template +class MOZ_STACK_CLASS CallArgsBase : + public mozilla::Conditional >::Type { protected: unsigned argc_; + public: + /* Returns the number of arguments. */ + unsigned length() const { return argc_; } + + /* Returns the i-th zero-indexed argument. */ + MutableHandleValue operator[](unsigned i) const { + MOZ_ASSERT(i < argc_); + return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); + } + + /* + * Returns the i-th zero-indexed argument, or |undefined| if there's no + * such argument. + */ + HandleValue get(unsigned i) const { + return i < length() + ? HandleValue::fromMarkedLocation(&this->argv_[i]) + : UndefinedHandleValue; + } + + /* + * Returns true if the i-th zero-indexed argument is present and is not + * |undefined|. + */ + bool hasDefined(unsigned i) const { + return i < argc_ && !this->argv_[i].isUndefined(); + } + + public: + // These methods are publicly exposed, but we're less sure of the interface + // here than we'd like (because they're hackish and drop assertions). Try + // to avoid using these if you can. + + Value *array() const { return this->argv_; } + Value *end() const { return this->argv_ + argc_; } +}; + +} // namespace detail + +class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase +{ + private: friend CallArgs CallArgsFromVp(unsigned argc, Value *vp); friend CallArgs CallArgsFromSp(unsigned argc, Value *sp); @@ -249,45 +365,6 @@ class MOZ_STACK_CLASS CallArgs : public CallReceiver return args; } - public: - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - Value &operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return argv_[i]; - } - - /* Returns a mutable handle for the i-th zero-indexed argument. */ - MutableHandleValue handleAt(unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - Value get(unsigned i) const { - return i < length() ? argv_[i] : UndefinedValue(); - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !argv_[i].isUndefined(); - } - - public: - // These methods are publicly exposed, but we're less sure of the interface - // here than we'd like (because they're hackish and drop assertions). Try - // to avoid using these if you can. - - Value *array() const { return argv_; } - Value *end() const { return argv_ + argc_; } }; MOZ_ALWAYS_INLINE CallArgs @@ -345,4 +422,4 @@ JS_THIS(JSContext *cx, JS::Value *vp) */ #define JS_THIS_VALUE(cx,vp) ((vp)[1]) -#endif /* js_CallArgs_h___ */ +#endif /* js_CallArgs_h */ diff --git a/external/spidermonkey/include/android/js/CharacterEncoding.h b/external/spidermonkey/include/android/js/CharacterEncoding.h index 63e5cc6650..e88e08e1be 100644 --- a/external/spidermonkey/include/android/js/CharacterEncoding.h +++ b/external/spidermonkey/include/android/js/CharacterEncoding.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_CharacterEncoding_h___ -#define js_CharacterEncoding_h___ +#ifndef js_CharacterEncoding_h +#define js_CharacterEncoding_h #include "mozilla/Range.h" @@ -58,6 +58,20 @@ class Latin1CharsZ : public mozilla::RangedPtr char *c_str() { return reinterpret_cast(get()); } }; +class UTF8Chars : public mozilla::Range +{ + typedef mozilla::Range Base; + + public: + UTF8Chars() : Base() {} + UTF8Chars(char *aBytes, size_t aLength) + : Base(reinterpret_cast(aBytes), aLength) + {} + UTF8Chars(const char *aBytes, size_t aLength) + : Base(reinterpret_cast(const_cast(aBytes)), aLength) + {} +}; + /* * SpiderMonkey also deals directly with UTF-8 encoded text in some places. */ @@ -124,10 +138,12 @@ class TwoByteCharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: + TwoByteCharsZ() : Base(NULL, 0) {} + TwoByteCharsZ(jschar *chars, size_t length) : Base(chars, length) { - JS_ASSERT(chars[length] = '\0'); + JS_ASSERT(chars[length] == '\0'); } }; @@ -142,14 +158,34 @@ class TwoByteCharsZ : public mozilla::RangedPtr * This method cannot trigger GC. */ extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars); +LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); extern UTF8CharsZ -TwoByteCharsToNewUTF8CharsZ(JSContext *cx, TwoByteChars tbchars); +TwoByteCharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); + +uint32_t +Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length); + +/* + * Inflate bytes in UTF-8 encoding to jschars. + * - On error, returns an empty TwoByteCharsZ. + * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold + * its length; the length value excludes the trailing null. + */ +extern TwoByteCharsZ +UTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); + +/* + * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters + * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 + * input. + */ +extern TwoByteCharsZ +LossyUTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); } // namespace JS inline void JS_free(JS::Latin1CharsZ &ptr) { js_free((void*)ptr.get()); } inline void JS_free(JS::UTF8CharsZ &ptr) { js_free((void*)ptr.get()); } -#endif // js_CharacterEncoding_h___ +#endif /* js_CharacterEncoding_h */ diff --git a/external/spidermonkey/include/android/js/Date.h b/external/spidermonkey/include/android/js/Date.h index 7ca961e30a..6199f9eca5 100644 --- a/external/spidermonkey/include/android/js/Date.h +++ b/external/spidermonkey/include/android/js/Date.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_Date_h___ -#define js_Date_h___ +#ifndef js_Date_h +#define js_Date_h #include "jstypes.h" @@ -32,4 +32,4 @@ DayFromTime(double time); } // namespace JS -#endif /* js_Date_h___ */ +#endif /* js_Date_h */ diff --git a/external/spidermonkey/include/android/js/GCAPI.h b/external/spidermonkey/include/android/js/GCAPI.h index 1b0036116c..a9bef77c09 100644 --- a/external/spidermonkey/include/android/js/GCAPI.h +++ b/external/spidermonkey/include/android/js/GCAPI.h @@ -4,10 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_gc_api_h___ -#define js_gc_api_h___ +#ifndef js_GCAPI_h +#define js_GCAPI_h -#include "HeapAPI.h" +#include "js/HeapAPI.h" namespace JS { @@ -181,6 +181,9 @@ DisableIncrementalGC(JSRuntime *rt); extern JS_FRIEND_API(void) DisableGenerationalGC(JSRuntime *rt); +extern JS_FRIEND_API(void) +EnableGenerationalGC(JSRuntime *rt); + extern JS_FRIEND_API(bool) IsIncrementalBarrierNeeded(JSRuntime *rt); @@ -205,7 +208,7 @@ WasIncrementalGC(JSRuntime *rt); class ObjectPtr { - JSObject *value; + Heap value; public: ObjectPtr() : value(NULL) {} @@ -240,7 +243,7 @@ class ObjectPtr } void trace(JSTracer *trc, const char *name) { - JS_CallObjectTracer(trc, &value, name); + JS_CallHeapObjectTracer(trc, &value, name); } JSObject &operator*() const { return *value; } @@ -291,4 +294,4 @@ ExposeValueToActiveJS(const Value &v) } /* namespace JS */ -#endif /* js_gc_api_h___ */ +#endif /* js_GCAPI_h */ diff --git a/external/spidermonkey/include/android/js/HashTable.h b/external/spidermonkey/include/android/js/HashTable.h index 3402bfbff4..aa05b71472 100644 --- a/external/spidermonkey/include/android/js/HashTable.h +++ b/external/spidermonkey/include/android/js/HashTable.h @@ -4,17 +4,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_HashTable_h__ -#define js_HashTable_h__ +#ifndef js_HashTable_h +#define js_HashTable_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" #include "mozilla/PodOperations.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" #include "mozilla/Util.h" -#include "js/TemplateLib.h" #include "js/Utility.h" namespace js { @@ -68,15 +72,7 @@ class HashMap // HashMap construction is fallible (due to OOM); thus the user must call // init after constructing a HashMap and check the return value. - HashMap(AllocPolicy a = AllocPolicy()) - : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Key type must be relocatable"); - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Value type must be relocatable"); - } - + HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -142,18 +138,18 @@ class HashMap template bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } bool add(AddPtr &p, const Key &k) { Entry e(k, Value()); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } template bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.relookupOrAdd(p, k, Move(e)); + return impl.relookupOrAdd(p, k, mozilla::Move(e)); } // |all()| returns a Range containing |count()| elements. E.g.: @@ -203,10 +199,10 @@ class HashMap // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -235,7 +231,7 @@ class HashMap template bool putNew(const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.putNew(k, Move(e)); + return impl.putNew(k, mozilla::Move(e)); } // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. @@ -253,9 +249,17 @@ class HashMap remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const Key &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashMap is movable - HashMap(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashMap(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashMap is not copyable or assignable @@ -303,11 +307,7 @@ class HashSet // HashSet construction is fallible (due to OOM); thus the user must call // init after constructing a HashSet and check the return value. - HashSet(AllocPolicy a = AllocPolicy()) : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Set element type must be relocatable"); - } + HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -411,10 +411,10 @@ class HashSet // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -448,9 +448,17 @@ class HashSet remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const T &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashSet is movable - HashSet(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashSet(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashSet is not copyable or assignable @@ -532,7 +540,7 @@ struct DefaultHasher // Specialize hashing policy for pointer types. It assumes that the type is // at least word-aligned. For types with smaller size use PointerHasher. template -struct DefaultHasher : PointerHasher::result> +struct DefaultHasher : PointerHasher::value> {}; // For doubles, we can xor the two uint32s. @@ -542,18 +550,11 @@ struct DefaultHasher typedef double Lookup; static HashNumber hash(double d) { JS_STATIC_ASSERT(sizeof(HashNumber) == 4); - union { - struct { - uint32_t lo; - uint32_t hi; - } s; - double d; - } u; - u.d = d; - return u.s.lo ^ u.s.hi; + uint64_t u = mozilla::BitwiseCast(d); + return HashNumber(u ^ (u >> 32)); } static bool match(double lhs, double rhs) { - return lhs == rhs; + return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); } }; @@ -577,8 +578,8 @@ class HashMapEntry template HashMapEntry(const KeyInput &k, const ValueInput &v) : key(k), value(v) {} - HashMapEntry(MoveRef rhs) - : key(Move(rhs->key)), value(Move(rhs->value)) { } + HashMapEntry(mozilla::MoveRef rhs) + : key(mozilla::Move(rhs->key)), value(mozilla::Move(rhs->value)) { } typedef Key KeyType; typedef Value ValueType; @@ -647,8 +648,8 @@ class HashTableEntry } void swap(HashTableEntry *other) { - Swap(keyHash, other->keyHash); - Swap(mem, other->mem); + mozilla::Swap(keyHash, other->keyHash); + mozilla::Swap(mem, other->mem); } T &get() { JS_ASSERT(isLive()); return *mem.addr(); } @@ -807,10 +808,7 @@ class HashTable : private AllocPolicy // a new key at the new Lookup position. |front()| is invalid after // this operation until the next call to |popFront()|. void rekeyFront(const Lookup &l, const Key &k) { - typename HashTableEntry::NonConstT t(Move(this->cur->get())); - HashPolicy::setKey(t, const_cast(k)); - table.remove(*this->cur); - table.putNewInfallible(l, Move(t)); + table.rekey(*this->cur, l, k); rekeyed = true; this->validEntry = false; } @@ -832,13 +830,13 @@ class HashTable : private AllocPolicy }; // HashTable is movable - HashTable(MoveRef rhs) + HashTable(mozilla::MoveRef rhs) : AllocPolicy(*rhs) { mozilla::PodAssign(this, &*rhs); rhs->table = NULL; } - void operator=(MoveRef rhs) { + void operator=(mozilla::MoveRef rhs) { if (table) destroyTable(*this, table, capacity()); mozilla::PodAssign(this, &*rhs); @@ -882,7 +880,7 @@ class HashTable : private AllocPolicy # define METER(x) #endif - friend class js::ReentrancyGuard; + friend class mozilla::ReentrancyGuard; mutable mozilla::DebugOnly entered; mozilla::DebugOnly mutationCount; @@ -892,7 +890,7 @@ class HashTable : private AllocPolicy static const unsigned sMinCapacity = 1 << sMinCapacityLog2; static const unsigned sMaxInit = JS_BIT(23); static const unsigned sMaxCapacity = JS_BIT(24); - static const unsigned sHashBits = tl::BitSize::result; + static const unsigned sHashBits = mozilla::tl::BitSize::value; static const uint8_t sMinAlphaFrac = 64; // (0x100 * .25) static const uint8_t sMaxAlphaFrac = 192; // (0x100 * .75) static const uint8_t sInvMaxAlpha = 171; // (ceil(0x100 / .75) >> 1) @@ -1165,7 +1163,7 @@ class HashTable : private AllocPolicy for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) { if (src->isLive()) { HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive(hn, Move(src->get())); + findFreeEntry(hn).setLive(hn, mozilla::Move(src->get())); src->destroy(); } } @@ -1346,19 +1344,19 @@ class HashTable : private AllocPolicy return gen; } - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(table); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); } Ptr lookup(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); return Ptr(lookup(l, keyHash, 0)); } @@ -1371,7 +1369,7 @@ class HashTable : private AllocPolicy AddPtr lookupForAdd(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); Entry &entry = lookup(l, keyHash, sCollisionBit); AddPtr p(entry, keyHash); @@ -1382,7 +1380,7 @@ class HashTable : private AllocPolicy template bool add(AddPtr &p, const U &rhs) { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(mutationCount == p.mutationCount); JS_ASSERT(table); JS_ASSERT(!p.found()); @@ -1443,7 +1441,7 @@ class HashTable : private AllocPolicy { p.mutationCount = mutationCount; { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); p.entry_ = &lookup(l, p.keyHash, sCollisionBit); } return p.found() || add(p, u); @@ -1452,17 +1450,27 @@ class HashTable : private AllocPolicy void remove(Ptr p) { JS_ASSERT(table); - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(p.found()); remove(*p.entry_); checkUnderloaded(); } + void rekey(Ptr p, const Lookup &l, const Key &k) + { + JS_ASSERT(table); + mozilla::ReentrancyGuard g(*this); + JS_ASSERT(p.found()); + typename HashTableEntry::NonConstT t(mozilla::Move(*p)); + HashPolicy::setKey(t, const_cast(k)); + remove(*p.entry_); + putNewInfallible(l, mozilla::Move(t)); + } + #undef METER }; } // namespace detail } // namespace js -#endif // js_HashTable_h__ - +#endif /* js_HashTable_h */ diff --git a/external/spidermonkey/include/android/js/HeapAPI.h b/external/spidermonkey/include/android/js/HeapAPI.h index f0f4411ac9..4d739304bc 100644 --- a/external/spidermonkey/include/android/js/HeapAPI.h +++ b/external/spidermonkey/include/android/js/HeapAPI.h @@ -4,33 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_heap_api_h___ -#define js_heap_api_h___ +#ifndef js_HeapAPI_h +#define js_HeapAPI_h #include "jspubtd.h" +#include "js/Utility.h" + /* These values are private to the JS engine. */ namespace js { namespace gc { -/* - * Page size must be static to support our arena pointer optimizations, so we - * are forced to support each platform with non-4096 pages as a special case. - * Note: The freelist supports a maximum arena shift of 15. - * Note: Do not use JS_CPU_SPARC here, this header is used outside JS. - */ -#if (defined(SOLARIS) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ - (defined(__sparc) || defined(__sparcv9) || defined(__ia64)) -const size_t PageShift = 13; -const size_t ArenaShift = PageShift; -#elif defined(__powerpc64__) -const size_t PageShift = 16; const size_t ArenaShift = 12; -#else -const size_t PageShift = 12; -const size_t ArenaShift = PageShift; -#endif -const size_t PageSize = size_t(1) << PageShift; const size_t ArenaSize = size_t(1) << ArenaShift; const size_t ArenaMask = ArenaSize - 1; @@ -67,7 +52,7 @@ namespace shadow { struct ArenaHeader { - js::Zone *zone; + JS::Zone *zone; }; struct Zone @@ -153,10 +138,10 @@ IsIncrementalBarrierNeededOnGCThing(shadow::Runtime *rt, void *thing, JSGCTraceK { if (!rt->needsBarrier_) return false; - js::Zone *zone = GetGCThingZone(thing); + JS::Zone *zone = GetGCThingZone(thing); return reinterpret_cast(zone)->needsBarrier_; } } /* namespace JS */ -#endif /* js_heap_api_h___ */ +#endif /* js_HeapAPI_h */ diff --git a/external/spidermonkey/include/android/js/LegacyIntTypes.h b/external/spidermonkey/include/android/js/LegacyIntTypes.h index 387a68b9e9..2c8498c89e 100644 --- a/external/spidermonkey/include/android/js/LegacyIntTypes.h +++ b/external/spidermonkey/include/android/js/LegacyIntTypes.h @@ -17,13 +17,12 @@ * Indeed, if you use this header and third-party code defining these * types, *expect* to encounter either compile errors or link errors, * depending how these types are used and on the order of inclusion. - * It is safest to use only the JSAPI -style types, - * customizing those types using MOZ_CUSTOM_STDINT_H if necessary. + * It is safest to use only the types. */ -#ifndef PROTYPES_H -#define PROTYPES_H +#ifndef js_LegacyIntTypes_h +#define js_LegacyIntTypes_h -#include "mozilla/StandardInteger.h" +#include #include "js-config.h" @@ -57,4 +56,4 @@ typedef int16_t JSInt16; typedef int32_t JSInt32; typedef int64_t JSInt64; -#endif /* !defined(PROTYPES_H) */ +#endif /* js_LegacyIntTypes_h */ diff --git a/external/spidermonkey/include/android/js/MemoryMetrics.h b/external/spidermonkey/include/android/js/MemoryMetrics.h index 7e84f2ae11..ed61e1c427 100644 --- a/external/spidermonkey/include/android/js/MemoryMetrics.h +++ b/external/spidermonkey/include/android/js/MemoryMetrics.h @@ -10,6 +10,8 @@ // These declarations are not within jsapi.h because they are highly likely to // change in the future. Depend on them at your own risk. +#include "mozilla/MemoryReporting.h" + #include #include "jsalloc.h" @@ -91,7 +93,6 @@ struct TypeInferenceSizes // Data for tracking JIT-code memory usage. struct CodeSizes { - size_t jaeger; size_t ion; size_t asmJS; size_t baseline; @@ -136,7 +137,7 @@ struct RuntimeSizes size_t dtoa; size_t temporary; size_t regexpData; - size_t stack; + size_t interpreterStack; size_t gcMarker; size_t mathCache; size_t scriptData; @@ -153,9 +154,11 @@ struct ZoneStats gcHeapUnusedGcThings(0), gcHeapStringsNormal(0), gcHeapStringsShort(0), + gcHeapLazyScripts(0), gcHeapTypeObjects(0), gcHeapIonCodes(0), stringCharsNonHuge(0), + lazyScripts(0), typeObjects(0), typePool(0), hugeStrings() @@ -167,14 +170,16 @@ struct ZoneStats gcHeapUnusedGcThings(other.gcHeapUnusedGcThings), gcHeapStringsNormal(other.gcHeapStringsNormal), gcHeapStringsShort(other.gcHeapStringsShort), + gcHeapLazyScripts(other.gcHeapLazyScripts), gcHeapTypeObjects(other.gcHeapTypeObjects), gcHeapIonCodes(other.gcHeapIonCodes), stringCharsNonHuge(other.stringCharsNonHuge), + lazyScripts(other.lazyScripts), typeObjects(other.typeObjects), typePool(other.typePool), hugeStrings() { - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // Add other's numbers to this object's numbers. @@ -186,16 +191,18 @@ struct ZoneStats ADD(gcHeapStringsNormal); ADD(gcHeapStringsShort); + ADD(gcHeapLazyScripts); ADD(gcHeapTypeObjects); ADD(gcHeapIonCodes); ADD(stringCharsNonHuge); + ADD(lazyScripts); ADD(typeObjects); ADD(typePool); #undef ADD - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // This field can be used by embedders. @@ -207,10 +214,12 @@ struct ZoneStats size_t gcHeapStringsNormal; size_t gcHeapStringsShort; + size_t gcHeapLazyScripts; size_t gcHeapTypeObjects; size_t gcHeapIonCodes; size_t stringCharsNonHuge; + size_t lazyScripts; size_t typeObjects; size_t typePool; @@ -241,7 +250,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(0), shapesCompartmentTables(0), scriptData(0), - jaegerData(0), baselineData(0), baselineStubsFallback(0), baselineStubsOptimized(0), @@ -271,7 +279,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids), shapesCompartmentTables(other.shapesCompartmentTables), scriptData(other.scriptData), - jaegerData(other.jaegerData), baselineData(other.baselineData), baselineStubsFallback(other.baselineStubsFallback), baselineStubsOptimized(other.baselineStubsOptimized), @@ -306,7 +313,6 @@ struct CompartmentStats size_t shapesExtraTreeShapeKids; size_t shapesCompartmentTables; size_t scriptData; - size_t jaegerData; size_t baselineData; size_t baselineStubsFallback; size_t baselineStubsOptimized; @@ -339,7 +345,6 @@ struct CompartmentStats ADD(shapesExtraTreeShapeKids); ADD(shapesCompartmentTables); ADD(scriptData); - ADD(jaegerData); ADD(baselineData); ADD(baselineStubsFallback); ADD(baselineStubsOptimized); @@ -360,7 +365,7 @@ struct CompartmentStats struct RuntimeStats { - RuntimeStats(JSMallocSizeOfFun mallocSizeOf) + RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) : runtime(), gcHeapChunkTotal(0), gcHeapDecommittedArenas(0), @@ -417,7 +422,7 @@ struct RuntimeStats ZoneStats *currZoneStats; - JSMallocSizeOfFun mallocSizeOf_; + mozilla::MallocSizeOf mallocSizeOf_; virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0; virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0; @@ -454,4 +459,4 @@ PeakSizeOfTemporary(const JSRuntime *rt); } // namespace JS -#endif // js_MemoryMetrics_h +#endif /* js_MemoryMetrics_h */ diff --git a/external/spidermonkey/include/android/js/PropertyKey.h b/external/spidermonkey/include/android/js/PropertyKey.h index 53158c26f3..c949db13a5 100644 --- a/external/spidermonkey/include/android/js/PropertyKey.h +++ b/external/spidermonkey/include/android/js/PropertyKey.h @@ -6,8 +6,8 @@ /* JS::PropertyKey implementation. */ -#ifndef js_PropertyKey_h___ -#define js_PropertyKey_h___ +#ifndef js_PropertyKey_h +#define js_PropertyKey_h #include "mozilla/Attributes.h" @@ -95,4 +95,4 @@ ToPropertyKey(JSContext *cx, HandleValue v, PropertyKey *key) } // namespace JS -#endif /* js_PropertyKey_h___ */ +#endif /* js_PropertyKey_h */ diff --git a/external/spidermonkey/include/android/js/RequiredDefines.h b/external/spidermonkey/include/android/js/RequiredDefines.h index 2be2efbf9a..6af9ca871b 100644 --- a/external/spidermonkey/include/android/js/RequiredDefines.h +++ b/external/spidermonkey/include/android/js/RequiredDefines.h @@ -10,8 +10,8 @@ * or SpiderMonkey public headers may not work correctly. */ -#ifndef js_RequiredDefines_h___ -#define js_RequiredDefines_h___ +#ifndef js_RequiredDefines_h +#define js_RequiredDefines_h /* * The c99 defining the limit macros (UINT32_MAX for example), says: @@ -20,4 +20,4 @@ */ #define __STDC_LIMIT_MACROS -#endif /* js_RequiredDefines_h___ */ +#endif /* js_RequiredDefines_h */ diff --git a/external/spidermonkey/include/android/js/RootingAPI.h b/external/spidermonkey/include/android/js/RootingAPI.h index 3e2e0d2a7c..99295f1238 100644 --- a/external/spidermonkey/include/android/js/RootingAPI.h +++ b/external/spidermonkey/include/android/js/RootingAPI.h @@ -4,14 +4,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsgc_root_h__ -#define jsgc_root_h__ +#ifndef js_RootingAPI_h +#define js_RootingAPI_h #include "mozilla/GuardObjects.h" #include "mozilla/TypeTraits.h" #include "js/Utility.h" -#include "js/TemplateLib.h" #include "jspubtd.h" @@ -99,9 +98,10 @@ namespace js { class Module; +class ScriptSourceObject; template -struct RootMethods {}; +struct GCMethods {}; template class RootedBase {}; @@ -112,6 +112,9 @@ class HandleBase {}; template class MutableHandleBase {}; +template +class HeapBase {}; + /* * js::NullPtr acts like a NULL pointer in contexts that require a Handle. * @@ -130,6 +133,10 @@ struct NullPtr static void * const constNullValue; }; +namespace gc { +struct Cell; +} /* namespace gc */ + } /* namespace js */ namespace JS { @@ -161,6 +168,204 @@ struct JS_PUBLIC_API(NullPtr) static void * const constNullValue; }; +/* + * The Heap class is a C/C++ heap-stored reference to a JS GC thing. All + * members of heap classes that refer to GC thing should use Heap (or + * possibly TenuredHeap, described below). + * + * Heap wraps the complex mechanisms required to ensure GC safety for the + * contained reference into a C++ class that behaves similarly to a normal + * pointer. + * + * GC references stored on the C/C++ stack must use Rooted/Handle/MutableHandle + * instead. + * + * Requirements for type T: + * - Must be one of: Value, jsid, JSObject*, JSString*, JSScript* + */ +template +class Heap : public js::HeapBase +{ + public: + Heap() { + static_assert(sizeof(T) == sizeof(Heap), + "Heap must be binary compatible with T."); + init(js::GCMethods::initial()); + } + explicit Heap(T p) { init(p); } + explicit Heap(const Heap &p) { init(p.ptr); } + + ~Heap() { + if (js::GCMethods::needsPostBarrier(ptr)) + relocate(); + } + + bool operator==(const Heap &other) { return ptr == other.ptr; } + bool operator!=(const Heap &other) { return ptr != other.ptr; } + + bool operator==(const T &other) const { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + + operator T() const { return ptr; } + T operator->() const { return ptr; } + const T *address() const { return &ptr; } + const T &get() const { return ptr; } + + T *unsafeGet() { return &ptr; } + + Heap &operator=(T p) { + set(p); + return *this; + } + + void set(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (js::GCMethods::needsPostBarrier(newPtr)) { + ptr = newPtr; + post(); + } else if (js::GCMethods::needsPostBarrier(ptr)) { + relocate(); /* Called before overwriting ptr. */ + ptr = newPtr; + } else { + ptr = newPtr; + } + } + + private: + void init(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + ptr = newPtr; + if (js::GCMethods::needsPostBarrier(ptr)) + post(); + } + + void post() { +#ifdef JSGC_GENERATIONAL + JS_ASSERT(js::GCMethods::needsPostBarrier(ptr)); + js::GCMethods::postBarrier(&ptr); +#endif + } + + void relocate() { +#ifdef JSGC_GENERATIONAL + js::GCMethods::relocate(&ptr); +#endif + } + + T ptr; +}; + +#ifdef DEBUG +/* + * For generational GC, assert that an object is in the tenured generation as + * opposed to being in the nursery. + */ +extern JS_FRIEND_API(void) +AssertGCThingMustBeTenured(JSObject* obj); +#else +inline void +AssertGCThingMustBeTenured(JSObject *obj) {} +#endif + +/* + * The TenuredHeap class is similar to the Heap class above in that it + * encapsulates the GC concerns of an on-heap reference to a JS object. However, + * it has two important differences: + * + * 1) Pointers which are statically known to only reference "tenured" objects + * can avoid the extra overhead of SpiderMonkey's write barriers. + * + * 2) Objects in the "tenured" heap have stronger alignment restrictions than + * those in the "nursery", so it is possible to store flags in the lower + * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged + * pointer with a nice API for accessing the flag bits and adds various + * assertions to ensure that it is not mis-used. + * + * GC things are said to be "tenured" when they are located in the long-lived + * heap: e.g. they have gained tenure as an object by surviving past at least + * one GC. For performance, SpiderMonkey allocates some things which are known + * to normally be long lived directly into the tenured generation; for example, + * global objects. Additionally, SpiderMonkey does not visit individual objects + * when deleting non-tenured objects, so object with finalizers are also always + * tenured; for instance, this includes most DOM objects. + * + * The considerations to keep in mind when using a TenuredHeap vs a normal + * Heap are: + * + * - It is invalid for a TenuredHeap to refer to a non-tenured thing. + * - It is however valid for a Heap to refer to a tenured thing. + * - It is not possible to store flag bits in a Heap. + */ +template +class TenuredHeap : public js::HeapBase +{ + public: + TenuredHeap() : bits(0) { + static_assert(sizeof(T) == sizeof(TenuredHeap), + "TenuredHeap must be binary compatible with T."); + } + explicit TenuredHeap(T p) : bits(0) { setPtr(p); } + explicit TenuredHeap(const TenuredHeap &p) : bits(0) { setPtr(p.ptr); } + + bool operator==(const TenuredHeap &other) { return bits == other.bits; } + bool operator!=(const TenuredHeap &other) { return bits != other.bits; } + + void setPtr(T newPtr) { + JS_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (newPtr) + AssertGCThingMustBeTenured(newPtr); + bits = (bits & flagsMask) | reinterpret_cast(newPtr); + } + + void setFlags(uintptr_t flagsToSet) { + JS_ASSERT((flagsToSet & ~flagsMask) == 0); + bits |= flagsToSet; + } + + void unsetFlags(uintptr_t flagsToUnset) { + JS_ASSERT((flagsToUnset & ~flagsMask) == 0); + bits &= ~flagsToUnset; + } + + bool hasFlag(uintptr_t flag) const { + JS_ASSERT((flag & ~flagsMask) == 0); + return (bits & flag) != 0; + } + + T getPtr() const { return reinterpret_cast(bits & ~flagsMask); } + uintptr_t getFlags() const { return bits & flagsMask; } + + operator T() const { return getPtr(); } + T operator->() const { return getPtr(); } + + TenuredHeap &operator=(T p) { + setPtr(p); + return *this; + } + + /* + * Set the pointer to a value which will cause a crash if it is + * dereferenced. + */ + void setToCrashOnTouch() { + bits = (bits & flagsMask) | crashOnTouchPointer; + } + + bool isSetToCrashOnTouch() { + return (bits & ~flagsMask) == crashOnTouchPointer; + } + + private: + enum { + maskBits = 3, + flagsMask = (1 << maskBits) - 1, + crashOnTouchPointer = 1 << maskBits + }; + + uintptr_t bits; +}; + /* * Reference to a T that has been rooted elsewhere. This is most useful * as a parameter type, which guarantees that the T lvalue is properly @@ -170,7 +375,7 @@ struct JS_PUBLIC_API(NullPtr) * specialization, define a HandleBase specialization containing them. */ template -class MOZ_STACK_CLASS Handle : public js::HandleBase +class MOZ_NONHEAP_CLASS Handle : public js::HandleBase { friend class MutableHandle; @@ -180,20 +385,22 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase Handle(Handle handle, typename mozilla::EnableIf::value, int>::Type dummy = 0) { + static_assert(sizeof(Handle) == sizeof(T *), + "Handle must be binary compatible with T*."); ptr = reinterpret_cast(handle.address()); } /* Create a handle for a NULL pointer. */ Handle(js::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "js::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "js::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&js::NullPtr::constNullValue); } /* Create a handle for a NULL pointer. */ Handle(JS::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "JS::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "JS::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&JS::NullPtr::constNullValue); } @@ -202,11 +409,19 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase } /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. + * Take care when calling this method! * - * Create a Handle from a raw location of a T. + * This creates a Handle from the raw location of a T. + * + * It should be called only if the following conditions hold: + * + * 1) the location of the T is guaranteed to be marked (for some reason + * other than being a Rooted), e.g., if it is guaranteed to be reachable + * from an implicit root. + * + * 2) the contents of the location are immutable, or at least cannot change + * for the lifetime of the handle, as its users may not expect its value + * to change underneath them. */ static Handle fromMarkedLocation(const T *p) { Handle h; @@ -230,13 +445,17 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase typename mozilla::EnableIf::value, int>::Type dummy = 0); const T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a Handle to something that + * takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } - bool operator!=(const T &other) { return *ptr != other; } - bool operator==(const T &other) { return *ptr == other; } + bool operator!=(const T &other) const { return *ptr != other; } + bool operator==(const T &other) const { return *ptr == other; } private: Handle() {} @@ -247,13 +466,14 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase void operator=(S v) MOZ_DELETE; }; -typedef Handle HandleObject; -typedef Handle HandleModule; -typedef Handle HandleFunction; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleId; -typedef Handle HandleValue; +typedef Handle HandleObject; +typedef Handle HandleModule; +typedef Handle HandleScriptSource; +typedef Handle HandleFunction; +typedef Handle HandleScript; +typedef Handle HandleString; +typedef Handle HandleId; +typedef Handle HandleValue; /* * Similar to a handle, but the underlying storage can be changed. This is @@ -270,7 +490,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase inline MutableHandle(Rooted *root); void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -288,9 +508,13 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase } T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a MutableHandle to something that takes + * a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } private: @@ -298,8 +522,8 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase T *ptr; - template - void operator=(S v) MOZ_DELETE; + template void operator=(S v) MOZ_DELETE; + void operator=(MutableHandle other) MOZ_DELETE; }; typedef MutableHandle MutableHandleObject; @@ -309,6 +533,11 @@ typedef MutableHandle MutableHandleString; typedef MutableHandle MutableHandleId; typedef MutableHandle MutableHandleValue; +#ifdef JSGC_GENERATIONAL +JS_PUBLIC_API(void) HeapCellPostBarrier(js::gc::Cell **cellp); +JS_PUBLIC_API(void) HeapCellRelocate(js::gc::Cell **cellp); +#endif + } /* namespace JS */ namespace js { @@ -383,13 +612,28 @@ struct RootKind }; template -struct RootMethods +struct GCMethods { static T *initial() { return NULL; } static ThingRootKind kind() { return RootKind::rootKind(); } static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); } + static bool needsPostBarrier(T *v) { return v; } +#ifdef JSGC_GENERATIONAL + static void postBarrier(T **vp) { + JS::HeapCellPostBarrier(reinterpret_cast(vp)); + } + static void relocate(T **vp) { + JS::HeapCellRelocate(reinterpret_cast(vp)); + } +#endif }; +#if defined(DEBUG) +/* This helper allows us to assert that Rooted is scoped within a request. */ +extern JS_PUBLIC_API(bool) +IsInRequest(JSContext *cx); +#endif + } /* namespace js */ namespace JS { @@ -405,46 +649,63 @@ namespace JS { template class MOZ_STACK_CLASS Rooted : public js::RootedBase { - void init(JSContext *cxArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ContextFriendFields *cx = js::ContextFriendFields::get(cxArg); - commonInit(cx->thingGCRooters); -#endif - } + /* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */ + template + void init(CX *cx) { +#ifdef JSGC_TRACK_EXACT_ROOTS + js::ThingRootKind kind = js::GCMethods::kind(); + this->stack = &cx->thingGCRooters[kind]; + this->prev = *stack; + *stack = reinterpret_cast*>(this); - void init(js::PerThreadData *ptArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::PerThreadDataFriendFields *pt = js::PerThreadDataFriendFields::get(ptArg); - commonInit(pt->thingGCRooters); + JS_ASSERT(!js::GCMethods::poisoned(ptr)); #endif } public: Rooted(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - init(cx); + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); } Rooted(JSContext *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); + } + + Rooted(js::ContextFriendFields *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(cx); } - Rooted(js::PerThreadData *pt + Rooted(js::ContextFriendFields *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(cx); + } + + Rooted(js::PerThreadDataFriendFields *pt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(pt); } - Rooted(js::PerThreadData *pt, T initial + Rooted(js::PerThreadDataFriendFields *pt, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { @@ -452,18 +713,38 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase init(pt); } + Rooted(JSRuntime *rt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + + Rooted(JSRuntime *rt, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + ~Rooted() { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS JS_ASSERT(*stack == reinterpret_cast*>(this)); *stack = prev; #endif } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted *previous() { return prev; } #endif - operator T() const { return ptr; } + /* + * Important: Return a reference here so passing a Rooted to + * something that takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return ptr; } T operator->() const { return ptr; } T *address() { return &ptr; } const T *address() const { return &ptr; } @@ -471,7 +752,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!js::RootMethods::poisoned(value)); + JS_ASSERT(!js::GCMethods::poisoned(value)); ptr = value; return ptr; } @@ -481,28 +762,25 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } - - private: - void commonInit(Rooted **thingGCRooters) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ThingRootKind kind = js::RootMethods::kind(); - this->stack = &thingGCRooters[kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - - JS_ASSERT(!js::RootMethods::poisoned(ptr)); -#endif + void set(T value) { + JS_ASSERT(!js::GCMethods::poisoned(value)); + ptr = value; } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } + + private: +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted **stack, *prev; #endif #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) /* Has the rooting analysis ever scanned this Rooted's stack location? */ friend void JS::CheckStackRoots(JSContext*); +#endif + +#ifdef JSGC_ROOT_ANALYSIS bool scanned; #endif @@ -523,13 +801,14 @@ template <> class Rooted; #endif -typedef Rooted RootedObject; -typedef Rooted RootedModule; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedId; -typedef Rooted RootedValue; +typedef Rooted RootedObject; +typedef Rooted RootedModule; +typedef Rooted RootedScriptSource; +typedef Rooted RootedFunction; +typedef Rooted RootedScript; +typedef Rooted RootedString; +typedef Rooted RootedId; +typedef Rooted RootedValue; } /* namespace JS */ @@ -549,8 +828,9 @@ class SkipRoot const uint8_t *start; const uint8_t *end; - template - void init(SkipRoot **head, const T *ptr, size_t count) { + template + void init(CX *cx, const T *ptr, size_t count) { + SkipRoot **head = &cx->skipGCRooters; this->stack = head; this->prev = *stack; *stack = this; @@ -559,23 +839,6 @@ class SkipRoot } public: - template - SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(&ContextFriendFields::get(cx)->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - template - SkipRoot(js::PerThreadData *ptd, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - PerThreadDataFriendFields *ptff = PerThreadDataFriendFields::get(ptd); - init(&ptff->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~SkipRoot() { JS_ASSERT(*stack == this); *stack = prev; @@ -589,22 +852,36 @@ class SkipRoot #else /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {} + public: + +#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(ContextFriendFields::get(cx), ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } template - SkipRoot(PerThreadData *ptd, const T *ptr, size_t count = 1 + SkipRoot(ContextFriendFields *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(cx, ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } -#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + SkipRoot(PerThreadData *pt, const T *ptr, size_t count = 1 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + { + init(PerThreadDataFriendFields::get(pt), ptr, count); + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -614,15 +891,17 @@ template class FakeRooted : public RootedBase { public: - FakeRooted(JSContext *cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(RootMethods::initial()) + template + FakeRooted(CX *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } - FakeRooted(JSContext *cx, T initial - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + template + FakeRooted(CX *cx, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; @@ -636,13 +915,13 @@ class FakeRooted : public RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!RootMethods::poisoned(value)); + JS_ASSERT(!GCMethods::poisoned(value)); ptr = value; return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } private: T ptr; @@ -666,7 +945,7 @@ class FakeMutableHandle : public js::MutableHandleBase } void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -727,13 +1006,11 @@ template class MaybeRooted typedef FakeMutableHandle MutableHandleType; static inline JS::Handle toHandle(HandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::Handle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::MutableHandle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } }; @@ -761,6 +1038,8 @@ template inline MutableHandle::MutableHandle(Rooted *root) { + static_assert(sizeof(MutableHandle) == sizeof(T *), + "MutableHandle must be binary compatible with T*."); ptr = root->address(); } @@ -779,10 +1058,6 @@ inline void MaybeCheckStackRoots(JSContext *cx) #endif } -namespace gc { -struct Cell; -} /* namespace gc */ - /* Base class for automatic read-only object rooting during compilation. */ class CompilerRootNode { @@ -801,4 +1076,4 @@ class CompilerRootNode } /* namespace js */ -#endif /* jsgc_root_h___ */ +#endif /* js_RootingAPI_h */ diff --git a/external/spidermonkey/include/android/js/TemplateLib.h b/external/spidermonkey/include/android/js/TemplateLib.h deleted file mode 100644 index a4ff682912..0000000000 --- a/external/spidermonkey/include/android/js/TemplateLib.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_template_lib_h__ -#define js_template_lib_h__ - -#include "jstypes.h" - -/* - * Library of reusable template meta-functions (that is, functions on types and - * compile-time values). Meta-functions are placed inside the 'tl' namespace to - * avoid conflict with non-meta functions that logically have the same name - * (e.g., js::tl::Min vs. js::Min). - */ - -namespace js { -namespace tl { - -/* Compute min/max/clamp. */ -template struct Min { - static const size_t result = i < j ? i : j; -}; -template struct Max { - static const size_t result = i > j ? i : j; -}; -template struct Clamp { - static const size_t result = i < min ? min : (i > max ? max : i); -}; - -/* Compute x^y. */ -template struct Pow { - static const size_t result = x * Pow::result; -}; -template struct Pow { - static const size_t result = 1; -}; - -/* Compute floor(log2(i)). */ -template struct FloorLog2 { - static const size_t result = 1 + FloorLog2::result; -}; -template <> struct FloorLog2<0> { /* Error */ }; -template <> struct FloorLog2<1> { static const size_t result = 0; }; - -/* Compute ceiling(log2(i)). */ -template struct CeilingLog2 { - static const size_t result = FloorLog2<2 * i - 1>::result; -}; - -/* Round up to the nearest power of 2. */ -template struct RoundUpPow2 { - static const size_t result = size_t(1) << CeilingLog2::result; -}; -template <> struct RoundUpPow2<0> { - static const size_t result = 1; -}; - -/* Compute the number of bits in the given unsigned type. */ -template struct BitSize { - static const size_t result = sizeof(T) * JS_BITS_PER_BYTE; -}; - -/* - * Produce an N-bit mask, where N <= BitSize::result. Handle the - * language-undefined edge case when N = BitSize::result. - */ -template struct NBitMask { - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |result| to assure - // its computation. - static const size_t checkPrecondition = 0 / size_t(N < BitSize::result); - static const size_t result = (size_t(1) << N) - 1 + checkPrecondition; -}; -template <> struct NBitMask::result> { - static const size_t result = size_t(-1); -}; - -/* - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template struct MulOverflowMask { - static const size_t result = - ~NBitMask::result - CeilingLog2::result>::result; -}; -template <> struct MulOverflowMask<0> { /* Error */ }; -template <> struct MulOverflowMask<1> { static const size_t result = 0; }; - -/* - * Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized - * array of T's is big enough to cause a ptrdiff_t overflow when subtracting - * a pointer to the end of the array from the beginning. - */ -template struct UnsafeRangeSizeMask { - /* - * The '2' factor means the top bit is clear, sizeof(T) converts from - * units of elements to bytes. - */ - static const size_t result = MulOverflowMask<2 * sizeof(T)>::result; -}; - -template struct If { static const T result = v1; }; -template struct If { static const T result = v2; }; - -/* - * Traits class for identifying types that are implicitly barriered. - */ -template struct IsRelocatableHeapType { static const bool result = true; }; - -} /* namespace tl */ -} /* namespace js */ - -#endif /* js_template_lib_h__ */ diff --git a/external/spidermonkey/include/android/js/Utility.h b/external/spidermonkey/include/android/js/Utility.h index c4ebf7ced6..9d391e5c8a 100644 --- a/external/spidermonkey/include/android/js/Utility.h +++ b/external/spidermonkey/include/android/js/Utility.h @@ -4,13 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_utility_h__ -#define js_utility_h__ +#ifndef js_Utility_h +#define js_Utility_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" +#include "mozilla/Move.h" #include "mozilla/Scoped.h" +#include "mozilla/TemplateLib.h" #include #include @@ -22,8 +24,6 @@ #include "jstypes.h" -#include "js/TemplateLib.h" - /* The public JS engine namespace. */ namespace JS {} @@ -41,7 +41,6 @@ namespace js {} #define JS_ASSERT(expr) MOZ_ASSERT(expr) #define JS_ASSERT_IF(cond, expr) MOZ_ASSERT_IF(cond, expr) -#define JS_NOT_REACHED(reason) MOZ_NOT_REACHED(reason) #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr) #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr) @@ -63,7 +62,7 @@ namespace js {} # define JS_DIAGNOSTICS_ASSERT(expr) ((void) 0) #endif -#define JS_STATIC_ASSERT(cond) MOZ_STATIC_ASSERT(cond, "JS_STATIC_ASSERT") +#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") #define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") extern MOZ_NORETURN JS_PUBLIC_API(void) @@ -84,10 +83,11 @@ extern JS_PUBLIC_API(void) JS_Abort(void); #else # ifdef DEBUG /* - * In order to test OOM conditions, when the shell command-line option - * |-A NUM| is passed, we fail continuously after the NUM'th allocation. + * In order to test OOM conditions, when the testing function + * oomAfterAllocations COUNT is passed, we fail continuously after the NUM'th + * allocation from now. */ -extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set from shell/js.cpp */ +extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set in builtins/TestingFunctions.cpp */ extern JS_PUBLIC_DATA(uint32_t) OOM_counter; /* data race, who cares. */ #ifdef JS_OOM_DO_BACKTRACES @@ -157,6 +157,12 @@ static JS_INLINE void* js_calloc(size_t bytes) return calloc(bytes, 1); } +static JS_INLINE void* js_calloc(size_t nmemb, size_t size) +{ + JS_OOM_POSSIBLY_FAIL(); + return calloc(nmemb, size); +} + static JS_INLINE void* js_realloc(void* p, size_t bytes) { JS_OOM_POSSIBLY_FAIL(); @@ -169,205 +175,6 @@ static JS_INLINE void js_free(void* p) } #endif/* JS_USE_CUSTOM_ALLOCATOR */ -JS_BEGIN_EXTERN_C - -/* - * Replace bit-scanning code sequences with CPU-specific instructions to - * speedup calculations of ceiling/floor log2. - * - * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129. - * - * SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856. - */ -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) - -unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); -unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward,_BitScanReverse) - -__forceinline static int -__BitScanForward32(unsigned int val) -{ - unsigned long idx; - - _BitScanForward(&idx, (unsigned long)val); - return (int)idx; -} -__forceinline static int -__BitScanReverse32(unsigned int val) -{ - unsigned long idx; - - _BitScanReverse(&idx, (unsigned long)val); - return (int)(31-idx); -} -# define js_bitscan_ctz32(val) __BitScanForward32(val) -# define js_bitscan_clz32(val) __BitScanReverse32(val) -# define JS_HAS_BUILTIN_BITSCAN32 - -#if defined(_M_AMD64) || defined(_M_X64) -unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask); -unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask); -# pragma intrinsic(_BitScanForward64,_BitScanReverse64) - -__forceinline static int -__BitScanForward64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanForward64(&idx, val); - return (int)idx; -} -__forceinline static int -__BitScanReverse64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanReverse64(&idx, val); - return (int)(63-idx); -} -# define js_bitscan_ctz64(val) __BitScanForward64(val) -# define js_bitscan_clz64(val) __BitScanReverse64(val) -# define JS_HAS_BUILTIN_BITSCAN64 -#endif -#elif MOZ_IS_GCC - -#if MOZ_GCC_VERSION_AT_LEAST(3, 4, 0) -# define USE_BUILTIN_CTZ -#endif - -#elif defined(__clang__) - -#if __has_builtin(__builtin_ctz) -# define USE_BUILTIN_CTZ -#endif - -#endif - -#if defined(USE_BUILTIN_CTZ) -# define js_bitscan_ctz32(val) __builtin_ctz(val) -# define js_bitscan_clz32(val) __builtin_clz(val) -# define JS_HAS_BUILTIN_BITSCAN32 -# if (JS_BYTES_PER_WORD == 8) -# define js_bitscan_ctz64(val) __builtin_ctzll(val) -# define js_bitscan_clz64(val) __builtin_clzll(val) -# define JS_HAS_BUILTIN_BITSCAN64 -# endif - -# undef USE_BUILTIN_CTZ - -#endif - -/* -** Macro version of JS_CeilingLog2: Compute the log of the least power of -** 2 greater than or equal to _n. The result is returned in _log2. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)). - * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is - * undefined. - */ -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - unsigned int j_ = (unsigned int)(_n); \ - (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \ - JS_END_MACRO -#else -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) & ((j_)-1)) \ - (_log2) += 1; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -/* -** Macro version of JS_FloorLog2: Compute the log of the greatest power of -** 2 less than or equal to _n. The result is returned in _log2. -** -** This is equivalent to finding the highest set bit in the word. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)). - * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1 - * to ensure 0 result when _n == 0. - */ -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \ - JS_END_MACRO -#else -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -#if JS_BYTES_PER_WORD == 4 -# ifdef JS_HAS_BUILTIN_BITSCAN32 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#elif JS_BYTES_PER_WORD == 8 -# ifdef JS_HAS_BUILTIN_BITSCAN64 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#else -# error "NOT SUPPORTED" -#endif - -JS_END_EXTERN_C - -/* - * Internal function. - * Compute the log of the least power of 2 greater than or equal to n. This is - * a version of JS_CeilingLog2 that operates on unsigned integers with - * CPU-dependant size. - */ -#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) - -/* - * Internal function. - * Compute the log of the greatest power of 2 less than or equal to n. - * This is a version of JS_FloorLog2 that operates on unsigned integers with - * CPU-dependant size and requires that n != 0. - */ -static MOZ_ALWAYS_INLINE size_t -JS_FLOOR_LOG2W(size_t n) -{ - JS_ASSERT(n != 0); - return js_FloorLog2wImpl(n); -} - /* * JS_ROTATE_LEFT32 * @@ -552,7 +359,7 @@ template static JS_ALWAYS_INLINE T * js_pod_malloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_malloc(numElems * sizeof(T)); } @@ -561,7 +368,7 @@ template static JS_ALWAYS_INLINE T * js_pod_calloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_calloc(numElems * sizeof(T)); } @@ -595,175 +402,6 @@ SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) namespace js { -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables also need to - * be resized. - * - * The details of the optimization, and whether it's worth applying, vary from - * one type to the next. And while some constructor calls are moves, many really - * are copies, and can't be optimized this way. So we need: - * - * 1) a way for a particular invocation of a copy constructor to say that it's - * really a move, and that the value of the original isn't important - * afterwards (althought it must still be safe to destroy); and - * - * 2) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation. - * - * The Move(T &) function takes a reference to a T, and returns an MoveRef - * referring to the same value; that's 1). An MoveRef is simply a reference - * to a T, annotated to say that a copy constructor applied to it may move that - * T, instead of copying it. Finally, a constructor that accepts an MoveRef - * should perform a more efficient move, instead of a copy, providing 2). - * - * So, where we might define a copy constructor for a class C like this: - * - * C(const C &rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(MoveRef rhs) { ... move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)) - * - * Note that MoveRef implicitly converts to T &, so you can pass an - * MoveRef to an ordinary copy constructor for a type that doesn't support a - * special move constructor, and you'll just get a copy. This means that - * templates can use Move whenever they know they won't use the original value - * any more, even if they're not sure whether the type at hand has a specialized - * move constructor. If it doesn't, the MoveRef will just convert to a T &, - * and the ordinary copy constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator, - * which runs this's destructor, and then applies the move constructor to - * *this's memory. A typical definition: - * - * C &operator=(MoveRef rhs) { - * this->~C(); - * new(this) C(rhs); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * This header file defines MoveRef and Move in the js namespace. It's up to - * individual containers to annotate moves as such, by calling Move; and it's up - * to individual types to define move constructors. - * - * One hint: if you're writing a move constructor where the type has members - * that should be moved themselves, it's much nicer to write this: - * - * C(MoveRef c) : x(c->x), y(c->y) { } - * - * than the equivalent: - * - * C(MoveRef c) { new(&x) X(c->x); new(&y) Y(c->y); } - * - * especially since GNU C++ fails to notice that this does indeed initialize x - * and y, which may matter if they're const. - */ -template -class MoveRef { - public: - typedef T Referent; - explicit MoveRef(T &t) : pointer(&t) { } - T &operator*() const { return *pointer; } - T *operator->() const { return pointer; } - operator T& () const { return *pointer; } - private: - T *pointer; -}; - -template -MoveRef Move(T &t) { return MoveRef(t); } - -template -MoveRef Move(const T &t) { return MoveRef(const_cast(t)); } - -/* Useful for implementing containers that assert non-reentrancy */ -class ReentrancyGuard -{ - /* ReentrancyGuard is not copyable. */ - ReentrancyGuard(const ReentrancyGuard &); - void operator=(const ReentrancyGuard &); - -#ifdef DEBUG - bool &entered; -#endif - public: - template -#ifdef DEBUG - ReentrancyGuard(T &obj) - : entered(obj.entered) -#else - ReentrancyGuard(T &/*obj*/) -#endif - { -#ifdef DEBUG - JS_ASSERT(!entered); - entered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - entered = false; -#endif - } -}; - -template -JS_ALWAYS_INLINE static void -Swap(T &t, T &u) -{ - T tmp(Move(t)); - t = Move(u); - u = Move(tmp); -} - -/* - * Round x up to the nearest power of 2. This function assumes that the most - * significant bit of x is not set, which would lead to overflow. - */ -JS_ALWAYS_INLINE size_t -RoundUpPow2(size_t x) -{ - return size_t(1) << JS_CEILING_LOG2W(x); -} - /* Integral types for all hash functions. */ typedef uint32_t HashNumber; const unsigned HashNumberSizeBits = 32; @@ -845,11 +483,6 @@ inline bool IsPoisonedPtr(T *v) } -/* - * This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|. - */ -typedef size_t(*JSMallocSizeOfFun)(const void *p); - /* sixgill annotation defines */ #ifndef HAVE_STATIC_ANNOTATIONS # define HAVE_STATIC_ANNOTATIONS @@ -891,4 +524,4 @@ typedef size_t(*JSMallocSizeOfFun)(const void *p); # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) #endif /* HAVE_STATIC_ANNOTATIONS */ -#endif /* js_utility_h__ */ +#endif /* js_Utility_h */ diff --git a/external/spidermonkey/include/android/js/Value.h b/external/spidermonkey/include/android/js/Value.h index 2c7fa1a600..9b2c5dd6f9 100644 --- a/external/spidermonkey/include/android/js/Value.h +++ b/external/spidermonkey/include/android/js/Value.h @@ -6,8 +6,8 @@ /* JS::Value implementation. */ -#ifndef js_Value_h___ -#define js_Value_h___ +#ifndef js_Value_h +#define js_Value_h #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" @@ -53,7 +53,7 @@ namespace JS { class Value; } * nice symbolic type tags, however we can only do this when we can force the * underlying type of the enum to be the desired size. */ -#if defined(__cplusplus) && !defined(__SUNPRO_CC) && !defined(__xlC__) +#if !defined(__SUNPRO_CC) && !defined(__xlC__) #if defined(_MSC_VER) # define JS_ENUM_HEADER(id, type) enum id : type @@ -132,7 +132,7 @@ JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64_t)); #endif -#else /* defined(__cplusplus) */ +#else /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ typedef uint8_t JSValueType; #define JSVAL_TYPE_DOUBLE ((uint8_t)0x00) @@ -180,7 +180,7 @@ typedef uint64_t JSValueShiftedTag; #define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) #endif /* JS_BITS_PER_WORD */ -#endif /* defined(__cplusplus) && !defined(__SUNPRO_CC) */ +#endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT @@ -265,7 +265,7 @@ typedef union jsval_layout typedef union jsval_layout { uint64_t asBits; -#if (!defined(_WIN64) && defined(__cplusplus)) +#if !defined(_WIN64) /* MSVC does not pack these correctly :-( */ struct { uint64_t payload47 : 47; @@ -321,7 +321,6 @@ typedef union jsval_layout int32_t i32; uint32_t u32; JSWhyMagic why; - uintptr_t word; } payload; } s; double asDouble; @@ -803,22 +802,31 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) #endif /* JS_BITS_PER_WORD */ -static inline double -JS_CANONICALIZE_NAN(double d) -{ - if (MOZ_UNLIKELY(d != d)) { - jsval_layout l; - l.asBits = 0x7FF8000000000000LL; - return l.asDouble; - } - return d; -} - static inline jsval_layout JSVAL_TO_IMPL(JS::Value v); static inline JS::Value IMPL_TO_JSVAL(jsval_layout l); namespace JS { +/** + * Returns a generic quiet NaN value, with all payload bits set to zero. + * + * Among other properties, this NaN's bit pattern conforms to JS::Value's + * bit pattern restrictions. + */ +static MOZ_ALWAYS_INLINE double +GenericNaN() +{ + return mozilla::SpecificNaN(0, 0x8000000000000ULL); +} + +static inline double +CanonicalizeNaN(double d) +{ + if (MOZ_UNLIKELY(mozilla::IsNaN(d))) + return GenericNaN(); + return d; +} + /* * JS::Value is the interface for a single JavaScript Engine value. A few * general notes on JS::Value: @@ -1393,22 +1401,35 @@ SameType(const Value &lhs, const Value &rhs) /************************************************************************/ +#ifdef JSGC_GENERATIONAL +namespace JS { +JS_PUBLIC_API(void) HeapValuePostBarrier(Value *valuep); +JS_PUBLIC_API(void) HeapValueRelocate(Value *valuep); +} +#endif + namespace js { -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } }; -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } + static bool needsPostBarrier(const JS::Value &v) { return v.isMarkable(); } +#ifdef JSGC_GENERATIONAL + static void postBarrier(JS::Value *v) { JS::HeapValuePostBarrier(v); } + static void relocate(JS::Value *v) { JS::HeapValueRelocate(v); } +#endif }; +template class UnbarrieredMutableValueOperations; template class MutableValueOperations; /* @@ -1420,7 +1441,9 @@ template class MutableValueOperations; template class ValueOperations { + friend class UnbarrieredMutableValueOperations; friend class MutableValueOperations; + const JS::Value * value() const { return static_cast(this)->extract(); } public: @@ -1453,19 +1476,22 @@ class ValueOperations void *toGCThing() const { return value()->toGCThing(); } JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); } + uint32_t toPrivateUint32() const { return value()->toPrivateUint32(); } JSWhyMagic whyMagic() const { return value()->whyMagic(); } }; /* - * A class designed for CRTP use in implementing the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible extractMutable() and extract() - * methods returning the const Value* and Value* abstracted by Outer. + * A class designed for CRTP use in implementing the mutating parts of the Value + * interface in Value-like classes that don't need post barriers. Outer must be + * a class inheriting UnbarrieredMutableValueOperations with visible + * extractMutable() and extract() methods returning the const Value* and Value* + * abstracted by Outer. */ template -class MutableValueOperations : public ValueOperations +class UnbarrieredMutableValueOperations : public ValueOperations { + friend class MutableValueOperations; JS::Value * value() { return static_cast(this)->extractMutable(); } public: @@ -1473,14 +1499,66 @@ class MutableValueOperations : public ValueOperations void setUndefined() { value()->setUndefined(); } void setInt32(int32_t i) { value()->setInt32(i); } void setDouble(double d) { value()->setDouble(d); } - void setString(JSString *str) { value()->setString(str); } - void setString(const JS::Anchor &str) { value()->setString(str); } - void setObject(JSObject &obj) { value()->setObject(obj); } void setBoolean(bool b) { value()->setBoolean(b); } void setMagic(JSWhyMagic why) { value()->setMagic(why); } bool setNumber(uint32_t ui) { return value()->setNumber(ui); } bool setNumber(double d) { return value()->setNumber(d); } - void setObjectOrNull(JSObject *arg) { value()->setObjectOrNull(arg); } +}; + +/* + * A class designed for CRTP use in implementing all the mutating parts of the + * Value interface in Value-like classes. Outer must be a class inheriting + * MutableValueOperations with visible extractMutable() and extract() + * methods returning the const Value* and Value* abstracted by Outer. + */ +template +class MutableValueOperations : public UnbarrieredMutableValueOperations +{ + public: + void setString(JSString *str) { this->value()->setString(str); } + void setString(const JS::Anchor &str) { this->value()->setString(str); } + void setObject(JSObject &obj) { this->value()->setObject(obj); } + void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); } +}; + +/* + * Augment the generic Heap interface when T = Value with + * type-querying, value-extracting, and mutating operations. + */ +template <> +class HeapBase : public UnbarrieredMutableValueOperations > +{ + typedef JS::Heap Outer; + + friend class ValueOperations; + friend class UnbarrieredMutableValueOperations; + + const JS::Value * extract() const { return static_cast(this)->address(); } + JS::Value * extractMutable() { return static_cast(this)->unsafeGet(); } + + /* + * Setters that potentially change the value to a GC thing from a non-GC + * thing must call JS::Heap::set() to trigger the post barrier. + * + * Changing from a GC thing to a non-GC thing value will leave the heap + * value in the store buffer, but it will be ingored so this is not a + * problem. + */ + void setBarriered(const JS::Value &v) { + static_cast *>(this)->set(v); + } + + public: + void setString(JSString *str) { setBarriered(JS::StringValue(str)); } + void setString(const JS::Anchor &str) { setBarriered(JS::StringValue(str.get())); } + void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); } + + void setObjectOrNull(JSObject *arg) { + if (arg) + setObject(*arg); + else + setNull(); + } }; /* @@ -1508,6 +1586,7 @@ class MutableHandleBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1526,6 +1605,7 @@ class RootedBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1574,12 +1654,12 @@ inline Anchor::~Anchor() namespace detail { struct ValueAlignmentTester { char c; JS::Value v; }; -MOZ_STATIC_ASSERT(sizeof(ValueAlignmentTester) == 16, - "JS::Value must be 16-byte-aligned"); +static_assert(sizeof(ValueAlignmentTester) == 16, + "JS::Value must be 16-byte-aligned"); struct LayoutAlignmentTester { char c; jsval_layout l; }; -MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, - "jsval_layout must be 16-byte-aligned"); +static_assert(sizeof(LayoutAlignmentTester) == 16, + "jsval_layout must be 16-byte-aligned"); } // namespace detail #endif /* DEBUG */ @@ -1593,8 +1673,8 @@ MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, */ typedef JS::Value jsval; -MOZ_STATIC_ASSERT(sizeof(jsval_layout) == sizeof(JS::Value), - "jsval_layout and JS::Value must have identical layouts"); +static_assert(sizeof(jsval_layout) == sizeof(JS::Value), + "jsval_layout and JS::Value must have identical layouts"); /************************************************************************/ @@ -1762,4 +1842,4 @@ JSVAL_TO_PRIVATE(jsval v) return JSVAL_TO_PRIVATE_PTR_IMPL(JSVAL_TO_IMPL(v)); } -#endif /* js_Value_h___ */ +#endif /* js_Value_h */ diff --git a/external/spidermonkey/include/android/js/Vector.h b/external/spidermonkey/include/android/js/Vector.h index 5f40dd634b..b14d75c758 100644 --- a/external/spidermonkey/include/android/js/Vector.h +++ b/external/spidermonkey/include/android/js/Vector.h @@ -4,14 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsvector_h_ -#define jsvector_h_ +#ifndef js_Vector_h +#define js_Vector_h -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "TemplateLib.h" -#include "Utility.h" +#include "mozilla/Vector.h" /* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ #ifdef _MSC_VER @@ -23,1085 +19,48 @@ namespace js { class TempAllocPolicy; -template +// using Vector = mozilla::Vector; +// +// ...and get rid of all the CRTP madness in mozilla::Vector(Base). But we +// can't because compiler support's not up to snuff. (Template aliases are in +// gcc 4.7 and clang 3.0 and are expected to be in MSVC 2013.) Instead, have a +// completely separate class inheriting from mozilla::Vector, and throw CRTP at +// the problem til things work. +// +// This workaround presents a couple issues. First, because js::Vector is a +// distinct type from mozilla::Vector, overload resolution, method calls, etc. +// are affected. *Hopefully* this won't be too bad in practice. (A bunch of +// places had to be fixed when mozilla::Vector was introduced, but it wasn't a +// crazy number.) Second, mozilla::Vector's interface has to be made subclass- +// ready via CRTP -- or rather, via mozilla::VectorBase, which basically no one +// should use. :-) Third, we have to redefine the constructors and the non- +// inherited operators. Blech. Happily there aren't too many of these, so it +// isn't the end of the world. + +template -class Vector; - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that cap*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring - * this. - */ -template -static bool CapacityHasExcessSpace(size_t cap) +class Vector + : public mozilla::VectorBase > { - size_t size = cap * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* Destroys constructed objects in the range [begin, end). */ - static inline void destroy(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - p->~T(); - } - - /* Constructs objects in the uninitialized range [begin, end). */ - static inline void initialize(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - /* - * Copy-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(*p); - } - - /* - * Move-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(Move(*p)); - } - - /* - * Copy-constructs objects in the uninitialized range [dst, dst+n) from the - * same object u. - */ - template - static inline void copyConstructN(T *dst, size_t n, const U &u) { - for (T *end = dst + n; dst != end; ++dst) - new(dst) T(u); - } - - /* - * Grows the given buffer to have capacity newCap, preserving the objects - * constructed in the range [begin, end) and updating v. Assumes that (1) - * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will - * not overflow. - */ - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); - if (!newbuf) - return false; - for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src) - new(dst) T(Move(*src)); - VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); - v.free_(v.mBegin); - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - static inline void destroy(T *, T *) {} - - static inline void initialize(T *begin, T *end) { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(begin, 0, sizeof(T) * (end-begin)); - */ - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); - */ - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - *dst = *p; - } - - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - copyConstruct(dst, srcbeg, srcend); - } - - static inline void copyConstructN(T *dst, size_t n, const T &t) { - for (T *p = dst, *end = dst + n; p != end; ++p) - *p = t; - } - - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - size_t oldSize = sizeof(T) * v.mCapacity; - size_t newSize = sizeof(T) * newCap; - T *newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); - if (!newbuf) - return false; - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * JS-friendly, STL-like container providing a short-lived, dynamic buffer. - * Vector calls the constructors/destructors of all elements stored in - * its internal buffer, so non-PODs may be safely used. Additionally, - * Vector will store the first N elements in-place before resorting to - * dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * N requirements: - * - any value, however, N is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in jsalloc.h (default js::TempAllocPolicy) - * - * N.B: Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object. - */ -template -class Vector : private AllocPolicy -{ - // typedef typename tl::StaticAssert::result>::result _; - - /* utilities */ - - static const bool sElemIsPod = mozilla::IsPod::value; - typedef VectorImpl Impl; - friend struct VectorImpl; - - bool growStorageBy(size_t incr); - bool convertToHeapStorage(size_t newCap); - - template inline bool growByImpl(size_t inc); - - /* magic constants */ - - static const int sMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are - * 0 inline elements. This allows us to compile when the definition - * of the element type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so - * in order to keep everything here, we use a dummy template - * parameter with partial specialization. - */ - template - struct ElemSize { - static const size_t result = sizeof(T); - }; - template - struct ElemSize<0, Dummy> { - static const size_t result = 1; - }; - - static const size_t sInlineCapacity = - tl::Min::result>::result; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t sInlineBytes = - tl::Max<1, sInlineCapacity * ElemSize::result>::result; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T *mBegin; - size_t mLength; /* Number of elements in the Vector. */ - size_t mCapacity; /* Max number of elements storable in the Vector without resizing. */ -#ifdef DEBUG - size_t mReserved; /* Max elements of reserved or used space in this vector. */ -#endif - - mozilla::AlignedStorage storage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool entered; -#endif - - Vector(const Vector &) MOZ_DELETE; - Vector &operator=(const Vector &) MOZ_DELETE; - - /* private accessors */ - - bool usingInlineStorage() const { - return mBegin == inlineStorage(); - } - - T *inlineStorage() const { - return (T *)storage.addr(); - } - - T *beginNoCheck() const { - return mBegin; - } - - T *endNoCheck() { - return mBegin + mLength; - } - - const T *endNoCheck() const { - return mBegin + mLength; - } - -#ifdef DEBUG - size_t reserved() const { - JS_ASSERT(mReserved <= mCapacity); - JS_ASSERT(mLength <= mReserved); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U u); - void internalAppendN(const T &t, size_t n); - template void internalAppend(const U *begin, size_t length); - template void internalAppend(const Vector &other); + typedef typename mozilla::VectorBase Base; public: - static const size_t sMaxInlineStorage = N; - - typedef T ElementType; - - Vector(AllocPolicy = AllocPolicy()); - Vector(MoveRef); /* Move constructor. */ - Vector &operator=(MoveRef); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy &allocPolicy() const { - return *this; + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector &operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); } - - AllocPolicy &allocPolicy() { - return *this; - } - - enum { InlineLength = N }; - - size_t length() const { - return mLength; - } - - bool empty() const { - return mLength == 0; - } - - size_t capacity() const { - return mCapacity; - } - - T *begin() { - JS_ASSERT(!entered); - return mBegin; - } - - const T *begin() const { - JS_ASSERT(!entered); - return mBegin; - } - - T *end() { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - const T *end() const { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - T &operator[](size_t i) { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - const T &operator[](size_t i) const { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - T &back() { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - const T &back() const { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - class Range { - friend class Vector; - T *cur_, *end_; - Range(T *cur, T *end) : cur_(cur), end_(end) {} - public: - Range() {} - bool empty() const { return cur_ == end_; } - size_t remain() const { return end_ - cur_; } - T &front() const { return *cur_; } - void popFront() { JS_ASSERT(!empty()); ++cur_; } - T popCopyFront() { JS_ASSERT(!empty()); return *cur_++; } - }; - - Range all() { - return Range(begin(), end()); - } - - /* mutators */ - - /* Given that the Vector is empty and has no inline storage, grow to |capacity|. */ - bool initCapacity(size_t request); - - /* If reserve(length() + N) succeeds, the N next appends are guaranteed to succeed. */ - bool reserve(size_t request); - - /* - * Destroy elements in the range [end() - incr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t incr); - - /* Grow the vector by incr elements. */ - bool growBy(size_t incr); - - /* Call shrinkBy or growBy based on whether newSize > length(). */ - bool resize(size_t newLength); - - /* Leave new elements as uninitialized memory. */ - bool growByUninitialized(size_t incr); - bool resizeUninitialized(size_t newLength); - - /* Shorthand for shrinkBy(length()). */ - void clear(); - - /* Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /* If true, appending |needed| elements will not call realloc(). */ - bool canAppendWithoutRealloc(size_t needed) const; - - /* - * Potentially fallible append operations. - * - * The function templates that take an unspecified type U require a - * const T & or a MoveRef. The MoveRef variants move their - * operands into the vector, instead of copying them. If they fail, the - * operand is left unmoved. - */ - template bool append(U t); - bool appendN(const T &t, size_t n); - template bool append(const U *begin, const U *end); - template bool append(const U *begin, size_t length); - template bool append(const Vector &other); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. - */ - template void infallibleAppend(const U &u) { - internalAppend(u); - } - void infallibleAppendN(const T &t, size_t n) { - internalAppendN(t, n); - } - template void infallibleAppend(const U *aBegin, const U *aEnd) { - internalAppend(aBegin, mozilla::PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U *aBegin, size_t aLength) { - internalAppend(aBegin, aLength); - } - template void infallibleAppend(const Vector &other) { - internalAppend(other); - } - - void popBack(); - - T popCopy(); - - /* - * Transfers ownership of the internal buffer used by Vector to the caller. - * After this call, the Vector is empty. Since the returned buffer may need - * to be allocated (if the elements are currently stored in-place), the - * call can fail, returning NULL. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - T *extractRawBuffer(); - - /* - * Transfer ownership of an array of objects into the Vector. - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T *p, size_t length); - - /* - * Places |val| at position |p|, shifting existing elements from |p| - * onward one position higher. On success, |p| should not be reused - * because it will be a dangling pointer if reallocation of the vector - * storage occurred; the return value should be used instead. On failure, - * NULL is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) - * - * - */ - T *insert(T *p, const T &val); - - /* - * Removes the element |t|, which must fall in the bounds [begin, end), - * shifting existing elements from |t + 1| onward one position lower. - */ - void erase(T *t); - - /* - * Measure the size of the Vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - /* - * Like sizeOfExcludingThis, but also measures the size of the Vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - void swap(Vector &other); }; -/* This does the re-entrancy check plus several other sanity checks. */ -#define REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - JS_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ - JS_ASSERT(reserved() <= mCapacity); \ - JS_ASSERT(mLength <= reserved()); \ - JS_ASSERT(mLength <= mCapacity) +} // namespace js -/* Vector Implementation */ - -template -JS_ALWAYS_INLINE -Vector::Vector(AllocPolicy ap) - : AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0), - mCapacity(sInlineCapacity) -#ifdef DEBUG - , mReserved(sInlineCapacity), entered(false) -#endif -{} - -/* Move constructor. */ -template -JS_ALWAYS_INLINE -Vector::Vector(MoveRef rhs) - : AllocPolicy(rhs) -#ifdef DEBUG - , entered(false) -#endif -{ - mLength = rhs->mLength; - mCapacity = rhs->mCapacity; -#ifdef DEBUG - mReserved = rhs->mReserved; -#endif - - if (rhs->usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = (T *)storage.addr(); - Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); - /* - * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = rhs->mBegin; - rhs->mBegin = (T *) rhs->storage.addr(); - rhs->mCapacity = sInlineCapacity; - rhs->mLength = 0; -#ifdef DEBUG - rhs->mReserved = sInlineCapacity; -#endif - } -} - -/* Move assignment. */ -template -JS_ALWAYS_INLINE -Vector & -Vector::operator=(MoveRef rhs) -{ - this->~Vector(); - new(this) Vector(rhs); - return *this; -} - -template -JS_ALWAYS_INLINE -Vector::~Vector() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); -} - -/* - * This function will create a new heap buffer with capacity newCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t newCap) -{ - JS_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); - if (!newBuf) - return false; - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = newCap; - return true; -} - -template -JS_NEVER_INLINE bool -Vector::growStorageBy(size_t incr) -{ - JS_ASSERT(mLength + incr > mCapacity); - JS_ASSERT_IF(!usingInlineStorage(), !CapacityHasExcessSpace(mCapacity)); - - /* - * When choosing a new capacity, its size should is as close to 2^N bytes - * as possible. 2^N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2^N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2^N request size. - */ - - size_t newCap; - - if (incr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::result; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength*4*sizeof(T) overflow? This condition limits a Vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. - * It also ensures that the ((char *)end() - (char *)begin()) does not - * overflow ptrdiff_t (see Bug 510319). - */ - if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::result) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is - * already as close to 2^N as sizeof(T) will allow. Just double the - * capacity, and then there might be space for one more element. - */ - newCap = mLength * 2; - if (CapacityHasExcessSpace(newCap)) - newCap += 1; - - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + incr; - - /* Did mLength+incr overflow? Will newCap*sizeof(T) overflow? */ - if (newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { - convert: - return convertToHeapStorage(newCap); - } - - grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t request) -{ - JS_ASSERT(empty()); - JS_ASSERT(usingInlineStorage()); - if (request == 0) - return true; - T *newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); - if (!newbuf) - return false; - mBegin = newbuf; - mCapacity = request; -#ifdef DEBUG - mReserved = request; -#endif - return true; -} - -template -inline bool -Vector::reserve(size_t request) -{ - REENTRANCY_GUARD_ET_AL; - if (request > mCapacity && !growStorageBy(request - mLength)) - return false; - -#ifdef DEBUG - if (request > mReserved) - mReserved = request; - JS_ASSERT(mLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(incr <= mLength); - Impl::destroy(endNoCheck() - incr, endNoCheck()); - mLength -= incr; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::growByImpl(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - if (incr > mCapacity - mLength && !growStorageBy(incr)) - return false; - - JS_ASSERT(mLength + incr <= mCapacity); - T *newend = endNoCheck() + incr; - if (InitNewElems) - Impl::initialize(endNoCheck(), newend); - mLength += incr; -#ifdef DEBUG - if (mLength > mReserved) - mReserved = mLength; -#endif - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::growBy(size_t incr) -{ - return growByImpl(incr); -} - -template -JS_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t incr) -{ - return growByImpl(incr); -} - -template -STATIC_POSTCONDITION(!return || ubound(this->begin()) >= newLength) -inline bool -Vector::resize(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growBy(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growByUninitialized(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -inline void -Vector::clear() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) - return; - - this->free_(beginNoCheck()); - mBegin = (T *)storage.addr(); - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t needed) const -{ - return mLength + needed <= mCapacity; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(U t) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity && !growStorageBy(1)) - return false; - -#ifdef DEBUG - if (mLength + 1 > mReserved) - mReserved = mLength + 1; -#endif - internalAppend(t); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(U u) -{ - JS_ASSERT(mLength + 1 <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - new(endNoCheck()) T(u); - ++mLength; -} - -template -JS_ALWAYS_INLINE bool -Vector::appendN(const T &t, size_t needed) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppendN(t, needed); - return true; -} - -template -JS_ALWAYS_INLINE void -Vector::internalAppendN(const T &t, size_t needed) -{ - JS_ASSERT(mLength + needed <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), needed, t); - mLength += needed; -} - -template -inline T * -Vector::insert(T *p, const T &val) -{ - JS_ASSERT(begin() <= p && p <= end()); - size_t pos = p - begin(); - JS_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(val)) - return NULL; - } else { - T oldBack = back(); - if (!append(oldBack)) /* Dup the last element. */ - return NULL; - for (size_t i = oldLength; i > pos; --i) - (*this)[i] = (*this)[i - 1]; - (*this)[pos] = val; - } - return begin() + pos; -} - -template -inline void -Vector::erase(T *it) -{ - JS_ASSERT(begin() <= it && it < end()); - while (it + 1 != end()) { - *it = *(it + 1); - ++it; - } - popBack(); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, const U *insEnd) -{ - REENTRANCY_GUARD_ET_AL; - size_t needed = mozilla::PointerRangeSize(insBegin, insEnd); - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppend(insBegin, needed); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(const U *insBegin, size_t insLength) -{ - JS_ASSERT(mLength + insLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); - mLength += insLength; -} - -template -template -inline bool -Vector::append(const Vector &other) -{ - return append(other.begin(), other.end()); -} - -template -template -inline void -Vector::internalAppend(const Vector &other) -{ - internalAppend(other.begin(), other.length()); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, size_t insLength) -{ - return this->append(insBegin, insBegin + insLength); -} - -template -JS_ALWAYS_INLINE void -Vector::popBack() -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -JS_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T * -Vector::extractRawBuffer() -{ - T *ret; - if (usingInlineStorage()) { - ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); - if (!ret) - return NULL; - Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - /* mBegin, mCapacity are unchanged. */ - mLength = 0; - } else { - ret = mBegin; - mBegin = (T *)storage.addr(); - mLength = 0; - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif - } - return ret; -} - -template -inline void -Vector::replaceRawBuffer(T *p, size_t aLength) -{ - REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); - - /* Take in the new buffer. */ - if (aLength <= sInlineCapacity) { - /* - * We convert to inline storage if possible, even though p might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = (T *)storage.addr(); - mLength = aLength; - mCapacity = sInlineCapacity; - Impl::moveConstruct(mBegin, p, p + aLength); - Impl::destroy(p, p + aLength); - this->free_(p); - } else { - mBegin = p; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); -} - -template -inline void -Vector::swap(Vector &other) -{ - // TODO Implement N != 0 - JS_STATIC_ASSERT(N == 0); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && other.usingInlineStorage()) { - other.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !other.usingInlineStorage()) { - mBegin = other.mBegin; - other.mBegin = other.inlineStorage(); - } else if (!usingInlineStorage() && !other.usingInlineStorage()) { - Swap(mBegin, other.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, other.mLength); - Swap(mCapacity, other.mCapacity); -#ifdef DEBUG - Swap(mReserved, other.mReserved); -#endif -} - -} /* namespace js */ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* jsvector_h_ */ +#endif /* js_Vector_h */ diff --git a/external/spidermonkey/include/android/jsalloc.h b/external/spidermonkey/include/android/jsalloc.h index e7e64fc540..3abc4966d1 100644 --- a/external/spidermonkey/include/android/jsalloc.h +++ b/external/spidermonkey/include/android/jsalloc.h @@ -4,32 +4,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsalloc_h_ -#define jsalloc_h_ +/* JS allocation policies. */ + +#ifndef jsalloc_h +#define jsalloc_h + +#include "mozilla/AllocPolicy.h" #include "js/Utility.h" -#include "jstypes.h" struct JSContext; namespace js { -/* - * Allocation policies. These model the concept: - * - public copy constructor, assignment, destructor - * - void *malloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *calloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *realloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * The *used* bytes of the previous buffer is passed in - * (rather than the old allocation size), in addition to - * the *new* allocation size requested. - * - void free_(void *) - * - reportAllocOverflow() - * Called on overflow before the container returns NULL. - */ +class ContextFriendFields; /* Policy for using system memory functions and doing no error reporting. */ class SystemAllocPolicy @@ -53,7 +41,7 @@ class SystemAllocPolicy */ class TempAllocPolicy { - JSContext *const cx_; + ContextFriendFields *const cx_; /* * Non-inline helper to call JSRuntime::onOutOfMemory with minimal @@ -62,11 +50,8 @@ class TempAllocPolicy JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes); public: - TempAllocPolicy(JSContext *cx) : cx_(cx) {} - - JSContext *context() const { - return cx_; - } + TempAllocPolicy(JSContext *cx) : cx_((ContextFriendFields *) cx) {} // :( + TempAllocPolicy(ContextFriendFields *cx) : cx_(cx) {} void *malloc_(size_t bytes) { void *p = js_malloc(bytes); @@ -98,4 +83,4 @@ class TempAllocPolicy } /* namespace js */ -#endif /* jsalloc_h_ */ +#endif /* jsalloc_h */ diff --git a/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id b/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id index db9dbac6b4..27b6bbed78 100644 --- a/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id +++ b/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id @@ -1 +1 @@ -0ec74a6f5f2aa9bbaa6a8cbf6e2ae95ec7c4ee43 \ No newline at end of file +e14ea931f699b1808c06886e55e977c9819f3774 \ No newline at end of file diff --git a/external/spidermonkey/include/android/jsclass.h b/external/spidermonkey/include/android/jsclass.h index c9b53c7679..def641715d 100644 --- a/external/spidermonkey/include/android/jsclass.h +++ b/external/spidermonkey/include/android/jsclass.h @@ -4,14 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclass_h__ -#define jsclass_h__ +#ifndef jsclass_h +#define jsclass_h /* * A JSClass acts as a vtable for JS objects that allows JSAPI clients to * control various aspects of the behavior of an object like property lookup. * js::Class is an engine-private extension that allows more control over * object behavior and, e.g., allows custom slow layout. */ + #include "jsapi.h" #include "jsprvtd.h" @@ -21,6 +22,10 @@ class PropertyName; class SpecialId; class PropertyId; +// This is equal to JSFunction::class_. Use it in places where you don't want +// to #include jsfun.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionClassPtr; + static JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid); @@ -195,7 +200,7 @@ typedef void const char *name; \ uint32_t flags; \ \ - /* Mandatory non-null function pointer members. */ \ + /* Mandatory function pointer members. */ \ JSPropertyOp addProperty; \ JSDeletePropertyOp delProperty; \ JSPropertyOp getProperty; \ @@ -203,9 +208,9 @@ typedef void JSEnumerateOp enumerate; \ JSResolveOp resolve; \ JSConvertOp convert; \ - FinalizeOp finalize; \ \ - /* Optionally non-null members start here. */ \ + /* Optional members (may be null). */ \ + FinalizeOp finalize; \ JSCheckAccessOp checkAccess; \ JSNative call; \ JSHasInstanceOp hasInstance; \ @@ -214,7 +219,7 @@ typedef void /* * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much - * we have to padd js::Class to match the size of JSClass; + * we have to pad js::Class to match the size of JSClass. */ struct ClassSizeMeasurement { @@ -312,8 +317,9 @@ struct Class return flags & JSCLASS_EMULATES_UNDEFINED; } - /* Defined in jsfuninlines.h */ - inline bool isCallable() const; + bool isCallable() const { + return this == js::FunctionClassPtr || call; + } static size_t offsetOfFlags() { return offsetof(Class, flags); } }; @@ -387,7 +393,7 @@ IsPoisonedSpecialId(js::SpecialId iden) return false; } -template <> struct RootMethods +template <> struct GCMethods { static SpecialId initial() { return SpecialId(); } static ThingRootKind kind() { return THING_ROOT_ID; } @@ -396,4 +402,4 @@ template <> struct RootMethods } /* namespace js */ -#endif /* jsclass_h__ */ +#endif /* jsclass_h */ diff --git a/external/spidermonkey/include/android/jsclist.h b/external/spidermonkey/include/android/jsclist.h index 8782307fa4..23da9b8cd5 100644 --- a/external/spidermonkey/include/android/jsclist.h +++ b/external/spidermonkey/include/android/jsclist.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclist_h___ -#define jsclist_h___ +#ifndef jsclist_h +#define jsclist_h #include "jstypes.h" @@ -104,4 +104,4 @@ typedef struct JSCListStr { #define JS_INIT_STATIC_CLIST(_l) \ {(_l), (_l)} -#endif /* jsclist_h___ */ +#endif /* jsclist_h */ diff --git a/external/spidermonkey/include/android/jscpucfg.h b/external/spidermonkey/include/android/jscpucfg.h index 6bb62b420f..c79bd7ad14 100644 --- a/external/spidermonkey/include/android/jscpucfg.h +++ b/external/spidermonkey/include/android/jscpucfg.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_cpucfg___ -#define js_cpucfg___ +#ifndef jscpucfg_h +#define jscpucfg_h #define JS_HAVE_LONG_LONG @@ -114,4 +114,4 @@ # endif #endif -#endif /* js_cpucfg___ */ +#endif /* jscpucfg_h */ diff --git a/external/spidermonkey/include/android/jsdbgapi.h b/external/spidermonkey/include/android/jsdbgapi.h index 4907d913a0..0ce7101337 100644 --- a/external/spidermonkey/include/android/jsdbgapi.h +++ b/external/spidermonkey/include/android/jsdbgapi.h @@ -4,12 +4,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsdbgapi_h___ -#define jsdbgapi_h___ +#ifndef jsdbgapi_h +#define jsdbgapi_h /* * JS debugger API. */ -#include "jsapi.h" + #include "jsprvtd.h" namespace JS { @@ -111,7 +111,7 @@ JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapHandler *handlerp, jsval *closurep); extern JS_PUBLIC_API(void) -JS_ClearScriptTraps(JSContext *cx, JSScript *script); +JS_ClearScriptTraps(JSRuntime *rt, JSScript *script); extern JS_PUBLIC_API(void) JS_ClearAllTrapsForCompartment(JSContext *cx); @@ -224,12 +224,6 @@ JS_GetScriptLineExtent(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(JSVersion) JS_GetScriptVersion(JSContext *cx, JSScript *script); -extern JS_PUBLIC_API(bool) -JS_GetScriptUserBit(JSScript *script); - -extern JS_PUBLIC_API(void) -JS_SetScriptUserBit(JSScript *script, bool b); - extern JS_PUBLIC_API(bool) JS_GetScriptIsSelfHosted(JSScript *script); @@ -433,9 +427,6 @@ JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); /************************************************************************/ -extern JS_FRIEND_API(void) -js_RevertVersion(JSContext *cx); - extern JS_PUBLIC_API(const JSDebugHooks *) JS_GetGlobalDebugHooks(JSRuntime *rt); @@ -465,4 +456,4 @@ JS_DumpCompartmentPCCounts(JSContext *cx); extern JS_FRIEND_API(JSBool) js_CallContextDebugHandler(JSContext *cx); -#endif /* jsdbgapi_h___ */ +#endif /* jsdbgapi_h */ diff --git a/external/spidermonkey/include/android/jsdhash.h b/external/spidermonkey/include/android/jsdhash.h deleted file mode 100644 index 1f7830fd2b..0000000000 --- a/external/spidermonkey/include/android/jsdhash.h +++ /dev/null @@ -1,612 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef jsdhash_h___ -#define jsdhash_h___ - -/* - * Double hashing, a la Knuth 6. - * - * Try to keep this file in sync with xpcom/glue/pldhash.h. - */ -#include "jstypes.h" -#include "jsutil.h" - -#if defined(__GNUC__) && defined(__i386__) && !defined(XP_OS2) -#define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall)) -#elif defined(XP_WIN) -#define JS_DHASH_FASTCALL __fastcall -#else -#define JS_DHASH_FASTCALL -#endif - -#ifdef DEBUG_XXXbrendan -#define JS_DHASHMETER 1 -#endif - -/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ -#undef JS_DHASH_SIZE_LIMIT -#define JS_DHASH_SIZE_LIMIT JS_BIT(24) - -/* Minimum table size, or gross entry count (net is at most .75 loaded). */ -#ifndef JS_DHASH_MIN_SIZE -#define JS_DHASH_MIN_SIZE 16 -#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0 -#error "JS_DHASH_MIN_SIZE must be a power of two!" -#endif - -/* - * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - * expressed as a fixed-point 32-bit fraction. - */ -#define JS_DHASH_BITS 32 -#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U - -/* Primitive and forward-struct typedefs. */ -typedef uint32_t JSDHashNumber; -typedef struct JSDHashEntryHdr JSDHashEntryHdr; -typedef struct JSDHashEntryStub JSDHashEntryStub; -typedef struct JSDHashTable JSDHashTable; -typedef struct JSDHashTableOps JSDHashTableOps; - -/* - * Table entry header structure. - * - * In order to allow in-line allocation of key and value, we do not declare - * either here. Instead, the API uses const void *key as a formal parameter. - * The key need not be stored in the entry; it may be part of the value, but - * need not be stored at all. - * - * Callback types are defined below and grouped into the JSDHashTableOps - * structure, for single static initialization per hash table sub-type. - * - * Each hash table sub-type should nest the JSDHashEntryHdr structure at the - * front of its particular entry type. The keyHash member contains the result - * of multiplying the hash code returned from the hashKey callback (see below) - * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 - * and 1 values. The stored keyHash value is table size invariant, and it is - * maintained automatically by JS_DHashTableOperate -- users should never set - * it, and its only uses should be via the entry macros below. - * - * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor - * removed. An entry may be either busy or free; if busy, it may be live or - * removed. Consumers of this API should not access members of entries that - * are not live. - * - * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries - * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a - * non-live, busy (i.e., removed) entry pointer to its caller. See below for - * more details on JS_DHashTableOperate's calling rules. - */ -struct JSDHashEntryHdr { - JSDHashNumber keyHash; /* every entry must begin like this */ -}; - -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_FREE(JSDHashEntryHdr* entry) -{ - return entry->keyHash == 0; -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_BUSY(JSDHashEntryHdr* entry) -{ - return !JS_DHASH_ENTRY_IS_FREE(entry); -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_LIVE(JSDHashEntryHdr* entry) -{ - return entry->keyHash >= 2; -} - -/* - * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead) - * on most architectures, and may be allocated on the stack or within another - * structure or class (see below for the Init and Finish functions to use). - * - * To decide whether to use double hashing vs. chaining, we need to develop a - * trade-off relation, as follows: - * - * Let alpha be the load factor, esize the entry size in words, count the - * entry count, and pow2 the power-of-two table size in entries. - * - * (JSDHashTable overhead) > (JSHashTable overhead) - * (unused table entry space) > (malloc and .next overhead per entry) + - * (buckets overhead) - * (1 - alpha) * esize * pow2 > 2 * count + pow2 - * - * Notice that alpha is by definition (count / pow2): - * - * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2 - * (1 - alpha) * esize > 2 * alpha + 1 - * - * esize > (1 + 2 * alpha) / (1 - alpha) - * - * This assumes both tables must keep keyHash, key, and value for each entry, - * where key and value point to separately allocated strings or structures. - * If key and value can be combined into one pointer, then the trade-off is: - * - * esize > (1 + 3 * alpha) / (1 - alpha) - * - * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type - * that must be allocated separately and referenced by an entry.value pointer - * member, and provided key's allocation can be fused with its entry's, then - * k (the words wasted per entry with chaining) is 4. - * - * To see these curves, feed gnuplot input like so: - * - * gnuplot> f(x,k) = (1 + k * x) / (1 - x) - * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4) - * - * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4 - * words for chaining to be more space-efficient than double hashing. - * - * Solving for alpha helps us decide when to shrink an underloaded table: - * - * esize > (1 + k * alpha) / (1 - alpha) - * esize - alpha * esize > 1 + k * alpha - * esize - 1 > (k + esize) * alpha - * (esize - 1) / (k + esize) > alpha - * - * alpha < (esize - 1) / (esize + k) - * - * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k), - * assuming esize is not too large (in which case, chaining should probably be - * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3 - * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5 - * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below. - * - * The current implementation uses a configurable lower bound on alpha, which - * defaults to .25, when deciding to shrink the table (while still respecting - * JS_DHASH_MIN_SIZE). - * - * Note a qualitative difference between chaining and double hashing: under - * chaining, entry addresses are stable across table shrinks and grows. With - * double hashing, you can't safely hold an entry pointer and use it after an - * ADD or REMOVE operation, unless you sample table->generation before adding - * or removing, and compare the sample after, dereferencing the entry pointer - * only if table->generation has not changed. - * - * The moral of this story: there is no one-size-fits-all hash table scheme, - * but for small table entry size, and assuming entry address stability is not - * required, double hashing wins. - */ -struct JSDHashTable { - const JSDHashTableOps *ops; /* virtual operations, see below */ - void *data; /* ops- and instance-specific data */ - int16_t hashShift; /* multiplicative hash shift */ - uint8_t maxAlphaFrac; /* 8-bit fixed point max alpha */ - uint8_t minAlphaFrac; /* 8-bit fixed point min alpha */ - uint32_t entrySize; /* number of bytes in an entry */ - uint32_t entryCount; /* number of entries in table */ - uint32_t removedCount; /* removed entry sentinels in table */ - uint32_t generation; /* entry storage generation number */ - char *entryStore; /* entry storage */ -#ifdef JS_DHASHMETER - struct JSDHashStats { - uint32_t searches; /* total number of table searches */ - uint32_t steps; /* hash chain links traversed */ - uint32_t hits; /* searches that found key */ - uint32_t misses; /* searches that didn't find key */ - uint32_t lookups; /* number of JS_DHASH_LOOKUPs */ - uint32_t addMisses; /* adds that miss, and do work */ - uint32_t addOverRemoved; /* adds that recycled a removed entry */ - uint32_t addHits; /* adds that hit an existing entry */ - uint32_t addFailures; /* out-of-memory during add growth */ - uint32_t removeHits; /* removes that hit, and do work */ - uint32_t removeMisses; /* useless removes that miss */ - uint32_t removeFrees; /* removes that freed entry directly */ - uint32_t removeEnums; /* removes done by Enumerate */ - uint32_t grows; /* table expansions */ - uint32_t shrinks; /* table contractions */ - uint32_t compresses; /* table compressions */ - uint32_t enumShrinks; /* contractions after Enumerate */ - } stats; -#endif -}; - -/* - * Size in entries (gross, not net of free and removed sentinels) for table. - * We store hashShift rather than sizeLog2 to optimize the collision-free case - * in SearchTable. - */ -#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift) - -/* - * Table space at entryStore is allocated and freed using these callbacks. - * The allocator should return null on error only (not if called with nbytes - * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). - */ -typedef void * -(* JSDHashAllocTable)(JSDHashTable *table, uint32_t nbytes); - -typedef void -(* JSDHashFreeTable) (JSDHashTable *table, void *ptr); - -/* - * Compute the hash code for a given key to be looked up, added, or removed - * from table. A hash code may have any JSDHashNumber value. - */ -typedef JSDHashNumber -(* JSDHashHashKey) (JSDHashTable *table, const void *key); - -/* - * Compare the key identifying entry in table with the provided key parameter. - * Return JS_TRUE if keys match, JS_FALSE otherwise. - */ -typedef JSBool -(* JSDHashMatchEntry)(JSDHashTable *table, const JSDHashEntryHdr *entry, - const void *key); - -/* - * Copy the data starting at from to the new entry storage at to. Do not add - * reference counts for any strong references in the entry, however, as this - * is a "move" operation: the old entry storage at from will be freed without - * any reference-decrementing callback shortly. - */ -typedef void -(* JSDHashMoveEntry)(JSDHashTable *table, const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -/* - * Clear the entry and drop any strong references it holds. This callback is - * invoked during a JS_DHASH_REMOVE operation (see below for operation codes), - * but only if the given key is found in the table. - */ -typedef void -(* JSDHashClearEntry)(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Called when a table (whether allocated dynamically by itself, or nested in - * a larger structure, or allocated on the stack) is finished. This callback - * allows table->ops-specific code to finalize table->data. - */ -typedef void -(* JSDHashFinalize) (JSDHashTable *table); - -/* - * Initialize a new entry, apart from keyHash. This function is called when - * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the - * given key, and must add a new one. At that point, entry->keyHash is not - * set yet, to avoid claiming the last free entry in a severely overloaded - * table. - */ -typedef JSBool -(* JSDHashInitEntry)(JSDHashTable *table, JSDHashEntryHdr *entry, - const void *key); - -/* - * Finally, the "vtable" structure for JSDHashTable. The first eight hooks - * must be provided by implementations; they're called unconditionally by the - * generic jsdhash.c code. Hooks after these may be null. - * - * Summary of allocation-related hook usage with C++ placement new emphasis: - * allocTable Allocate raw bytes with malloc, no ctors run. - * freeTable Free raw bytes with free, no dtors run. - * initEntry Call placement new using default key-based ctor. - * Return JS_TRUE on success, JS_FALSE on error. - * moveEntry Call placement new using copy ctor, run dtor on old - * entry storage. - * clearEntry Run dtor on entry. - * finalize Stub unless table->data was initialized and needs to - * be finalized. - * - * Note the reason why initEntry is optional: the default hooks (stubs) clear - * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD), - * the returned entry pointer addresses an entry struct whose keyHash member - * has been set non-zero, but all other entry members are still clear (null). - * JS_DHASH_ADD callers can test such members to see whether the entry was - * newly created by the JS_DHASH_ADD call that just succeeded. If placement - * new or similar initialization is required, define an initEntry hook. Of - * course, the clearEntry hook must zero or null appropriately. - * - * XXX assumes 0 is null for pointer types. - */ -struct JSDHashTableOps { - /* Mandatory hooks. All implementations must provide these. */ - JSDHashAllocTable allocTable; - JSDHashFreeTable freeTable; - JSDHashHashKey hashKey; - JSDHashMatchEntry matchEntry; - JSDHashMoveEntry moveEntry; - JSDHashClearEntry clearEntry; - JSDHashFinalize finalize; - - /* Optional hooks start here. If null, these are not called. */ - JSDHashInitEntry initEntry; -}; - -/* - * Default implementations for the above ops. - */ -extern JS_PUBLIC_API(void *) -JS_DHashAllocTable(JSDHashTable *table, uint32_t nbytes); - -extern JS_PUBLIC_API(void) -JS_DHashFreeTable(JSDHashTable *table, void *ptr); - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashStringKey(JSDHashTable *table, const void *key); - -/* A minimal entry contains a keyHash header and a void key pointer. */ -struct JSDHashEntryStub { - JSDHashEntryHdr hdr; - const void *key; -}; - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchStringKey(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(void) -JS_DHashMoveEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -extern JS_PUBLIC_API(void) -JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFinalizeStub(JSDHashTable *table); - -/* - * If you use JSDHashEntryStub or a subclass of it as your entry struct, and - * if your entries move via memcpy and clear via memset(0), you can use these - * stub operations. - */ -extern JS_PUBLIC_API(const JSDHashTableOps *) -JS_DHashGetStubOps(void); - -/* - * Dynamically allocate a new JSDHashTable using malloc, initialize it using - * JS_DHashTableInit, and return its address. Return null on malloc failure. - * Note that the entry storage at table->entryStore will be allocated using - * the ops->allocTable callback. - */ -extern JS_PUBLIC_API(JSDHashTable *) -JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32_t entrySize, - uint32_t capacity); - -/* - * Finalize table's data, free its entry storage (via table->ops->freeTable), - * and return the memory starting at table to the malloc heap. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableDestroy(JSDHashTable *table); - -/* - * Initialize table with ops, data, entrySize, and capacity. Capacity is a - * guess for the smallest table size at which the table will usually be less - * than 75% loaded (the table will grow or shrink as needed; capacity serves - * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE). - */ -extern JS_PUBLIC_API(JSBool) -JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, - uint32_t entrySize, uint32_t capacity); - -/* - * Set maximum and minimum alpha for table. The defaults are 0.75 and .25. - * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if - * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or - * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that - * we don't shrink on the very next remove after growing a table upon adding - * an entry that brings entryCount past maxAlpha * tableSize. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableSetAlphaBounds(JSDHashTable *table, - float maxAlpha, - float minAlpha); - -/* - * Call this macro with k, the number of pointer-sized words wasted per entry - * under chaining, to compute the minimum alpha at which double hashing still - * beats chaining. - */ -#define JS_DHASH_MIN_ALPHA(table, k) \ - ((float)((table)->entrySize / sizeof(void *) - 1) \ - / ((table)->entrySize / sizeof(void *) + (k))) - -/* - * Default max/min alpha, and macros to compute the value for the |capacity| - * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any - * max alpha, such that adding entryCount entries right after initializing the - * table will not require a reallocation (so JS_DHASH_ADD can't fail for those - * JS_DHashTableOperate calls). - * - * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY. - * Don't use it directly! - */ -#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 -#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 - -#define JS_DHASH_CAP(entryCount, maxAlpha) \ - ((uint32_t)((double)(entryCount) / (maxAlpha))) - -#define JS_DHASH_CAPACITY(entryCount, maxAlpha) \ - (JS_DHASH_CAP(entryCount, maxAlpha) + \ - (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8_t)(0x100 * (maxAlpha))) \ - >> 8) < (entryCount))) - -#define JS_DHASH_DEFAULT_CAPACITY(entryCount) \ - JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) - -/* - * Finalize table's data, free its entry storage using table->ops->freeTable, - * and leave its members unchanged from their last live values (which leaves - * pointers dangling). If you want to burn cycles clearing table, it's up to - * your code to call memset. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableFinish(JSDHashTable *table); - -/* - * To consolidate keyHash computation and table grow/shrink code, we use a - * single entry point for lookup, add, and remove operations. The operation - * codes are declared here, along with codes returned by JSDHashEnumerator - * functions, which control JS_DHashTableEnumerate's behavior. - */ -typedef enum JSDHashOperator { - JS_DHASH_LOOKUP = 0, /* lookup entry */ - JS_DHASH_ADD = 1, /* add entry */ - JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */ - JS_DHASH_NEXT = 0, /* enumerator says continue */ - JS_DHASH_STOP = 1 /* enumerator says stop */ -} JSDHashOperator; - -/* - * To lookup a key in table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); - * - * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies - * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found. - * - * To add an entry identified by key to table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD); - * - * If entry is null upon return, then either the table is severely overloaded, - * and memory can't be allocated for entry storage via table->ops->allocTable; - * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may - * have returned false. - * - * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry) - * is true, and it is up to the caller to initialize the key and value parts - * of the entry sub-type, if they have not been set already (i.e. if entry was - * not already in the table, and if the optional initEntry hook was not used). - * - * To remove an entry identified by key from table, call: - * - * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); - * - * If key's entry is found, it is cleared (via table->ops->clearEntry) and - * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation - * returns null unconditionally; you should ignore its return value. - */ -extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL -JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); - -/* - * Remove an entry already accessed via LOOKUP or ADD. - * - * NB: this is a "raw" or low-level routine, intended to be used only where - * the inefficiency of a full JS_DHashTableOperate (which rehashes in order - * to find the entry given its key) is not tolerable. This function does not - * shrink the table if it is underloaded. It does not update stats #ifdef - * JS_DHASHMETER, either. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Enumerate entries in table using etor: - * - * count = JS_DHashTableEnumerate(table, etor, arg); - * - * JS_DHashTableEnumerate calls etor like so: - * - * op = etor(table, entry, number, arg); - * - * where number is a zero-based ordinal assigned to live entries according to - * their order in table->entryStore. - * - * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT, - * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via - * table->ops->clearEntry) and free entry. Then we check whether op contains - * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries - * that were enumerated so far. Return the total number of live entries when - * enumeration completes normally. - * - * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it - * must return JS_DHASH_STOP; otherwise undefined behavior results. - * - * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk - * or compressed after enumeration, but before JS_DHashTableEnumerate returns. - * Such an enumerator therefore can't safely set aside entry pointers, but an - * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries - * aside, e.g., to avoid copying live entries into an array of the entry type. - * Copying entry pointers is cheaper, and safe so long as the caller of such a - * "stable" Enumerate doesn't use the set-aside pointers after any call either - * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might - * grow or shrink entryStore. - * - * If your enumerator wants to remove certain entries, but set aside pointers - * to other entries that it retains, it can use JS_DHashTableRawRemove on the - * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if - * you want to remove entries, but for some reason you do not want entryStore - * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on - * the entry being enumerated, rather than returning JS_DHASH_REMOVE. - */ -typedef JSDHashOperator -(* JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number, void *arg); - -extern JS_PUBLIC_API(uint32_t) -JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); - -typedef size_t -(* JSDHashSizeOfEntryExcludingThisFun)(JSDHashEntryHdr *hdr, - JSMallocSizeOfFun mallocSizeOf, - void *arg); - -/** - * Measure the size of the table's entry storage, and if - * |sizeOfEntryExcludingThis| is non-NULL, measure the size of things pointed - * to by entries. Doesn't measure |ops| because it's often shared between - * tables, nor |data| because it's opaque. - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfExcludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -/** - * Like JS_DHashTableSizeOfExcludingThis, but includes sizeof(*this). - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfIncludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -#ifdef DEBUG -/** - * Mark a table as immutable for the remainder of its lifetime. This - * changes the implementation from ASSERTing one set of invariants to - * ASSERTing a different set. - * - * When a table is NOT marked as immutable, the table implementation - * asserts that the table is not mutated from its own callbacks. It - * assumes the caller protects the table from being accessed on multiple - * threads simultaneously. - * - * When the table is marked as immutable, the re-entry assertions will - * no longer trigger erroneously due to multi-threaded access. Instead, - * mutations will cause assertions. - */ -extern JS_PUBLIC_API(void) -JS_DHashMarkTableImmutable(JSDHashTable *table); -#endif - -#ifdef JS_DHASHMETER -#include - -extern JS_PUBLIC_API(void) -JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp); -#endif - -#endif /* jsdhash_h___ */ diff --git a/external/spidermonkey/include/android/jsfriendapi.h b/external/spidermonkey/include/android/jsfriendapi.h index 848049ffe3..a1c3024fed 100644 --- a/external/spidermonkey/include/android/jsfriendapi.h +++ b/external/spidermonkey/include/android/jsfriendapi.h @@ -4,15 +4,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsfriendapi_h___ -#define jsfriendapi_h___ +#ifndef jsfriendapi_h +#define jsfriendapi_h -#include "mozilla/GuardObjects.h" +#include "mozilla/MemoryReporting.h" #include "jsclass.h" -#include "jscpucfg.h" -#include "jspubtd.h" #include "jsprvtd.h" +#include "jspubtd.h" + +#include "js/CallArgs.h" /* * This macro checks if the stack pointer has exceeded a given limit. If @@ -29,6 +30,11 @@ #define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0) +namespace JS { +template +class Heap; +} /* namespace JS */ + extern JS_FRIEND_API(void) JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data); @@ -48,7 +54,7 @@ extern JS_FRIEND_API(JSObject *) JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JSHandleObject obj); +JS_ObjectCountDynamicSlots(JS::HandleObject obj); extern JS_FRIEND_API(size_t) JS_SetProtoCalled(JSContext *cx); @@ -118,14 +124,27 @@ extern JS_FRIEND_API(JSObject *) JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(JSString *) -JS_BasicObjectToString(JSContext *cx, JSHandleObject obj); +JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); extern JS_FRIEND_API(JSBool) -js_GetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp); +js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JSBool strict, + JS::MutableHandleValue vp); JS_FRIEND_API(void) js_ReportOverRecursed(JSContext *maybecx); +JS_FRIEND_API(bool) +js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); + +JS_FRIEND_API(const char *) +js_ObjectClassName(JSContext *cx, JS::HandleObject obj); + +JS_FRIEND_API(bool) +js_AddObjectRoot(JSRuntime *rt, JSObject **objp); + +JS_FRIEND_API(void) +js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp); + #ifdef DEBUG /* @@ -157,7 +176,7 @@ extern JS_FRIEND_API(JSBool) JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props); extern JS_FRIEND_API(JSBool) -JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, +JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op, js::MutableHandleValue statep, js::MutableHandleId idp); struct JSFunctionSpecWithHelp { @@ -177,25 +196,24 @@ struct JSFunctionSpecWithHelp { extern JS_FRIEND_API(bool) JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs); -typedef bool (* JS_SourceHook)(JSContext *cx, JSScript *script, jschar **src, uint32_t *length); +typedef bool (* JS_SourceHook)(JSContext *cx, JS::Handle script, + jschar **src, uint32_t *length); extern JS_FRIEND_API(void) JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook); namespace js { -extern mozilla::ThreadLocal TlsPerThreadData; - inline JSRuntime * GetRuntime(const JSContext *cx) { - return ContextFriendFields::get(cx)->runtime; + return ContextFriendFields::get(cx)->runtime_; } inline JSCompartment * GetContextCompartment(const JSContext *cx) { - return ContextFriendFields::get(cx)->compartment; + return ContextFriendFields::get(cx)->compartment_; } inline JS::Zone * @@ -217,19 +235,6 @@ typedef bool extern JS_FRIEND_API(void) DumpHeapComplete(JSRuntime *rt, FILE *fp); -class JS_FRIEND_API(AutoSwitchCompartment) { - private: - JSContext *cx; - JSCompartment *oldCompartment; - public: - AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - AutoSwitchCompartment(JSContext *cx, JSHandleObject target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoSwitchCompartment(); - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - #ifdef OLD_GETTER_SETTER_METHODS JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, unsigned argc, js::Value *vp); JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, unsigned argc, js::Value *vp); @@ -254,6 +259,15 @@ IsAtomsCompartment(JSCompartment *comp); extern JS_FRIEND_API(bool) ReportIfUndeclaredVarAssignment(JSContext *cx, HandleString propname); +/* + * Returns whether we're in a non-strict property set (in that we're in a + * non-strict script and the bytecode we're on is a property set). The return + * value does NOT indicate any sort of exception was thrown: it's just a + * boolean. + */ +extern JS_FRIEND_API(bool) +IsInNonStrictPropertySet(JSContext *cx); + struct WeakMapTracer; /* @@ -301,7 +315,7 @@ IterateGrayObjects(JS::Zone *zone, GCThingCallback cellCallback, void *data); #ifdef JS_HAS_CTYPES extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(JSMallocSizeOfFun mallocSizeOf, JSObject *obj); +SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject *obj); #endif extern JS_FRIEND_API(JSCompartment *) @@ -321,8 +335,9 @@ struct TypeObject { }; struct BaseShape { - js::Class *clasp; - JSObject *parent; + js::Class *clasp; + JSObject *parent; + JSObject *_1; JSCompartment *compartment; }; @@ -365,19 +380,22 @@ struct Function { }; struct Atom { - size_t _; + static const size_t LENGTH_SHIFT = 4; + size_t lengthAndFlags; const jschar *chars; }; } /* namespace shadow */ -extern JS_FRIEND_DATA(js::Class) CallClass; -extern JS_FRIEND_DATA(js::Class) DeclEnvClass; -extern JS_FRIEND_DATA(js::Class) FunctionClass; -extern JS_FRIEND_DATA(js::Class) FunctionProxyClass; -extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectClass; +// These are equal to |&{Function,Object,OuterWindow}ProxyObject::class_|. Use +// them in places where you don't want to #include vm/ProxyObject.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) ObjectProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr; + +// This is equal to |&JSObject::class_|. Use it in places where you don't want +// to #include jsobj.h. +extern JS_FRIEND_DATA(js::Class* const) ObjectClassPtr; inline js::Class * GetObjectClass(JSObject *obj) @@ -401,9 +419,15 @@ IsOuterObject(JSObject *obj) { return !!GetObjectClass(obj)->ext.innerObject; } +JS_FRIEND_API(bool) +IsFunctionObject(JSObject *obj); + JS_FRIEND_API(bool) IsScopeObject(JSObject *obj); +JS_FRIEND_API(bool) +IsCallObject(JSObject *obj); + inline JSObject * GetObjectParent(JSObject *obj) { @@ -423,6 +447,13 @@ GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +// For legacy consumers only. This whole concept is going away soon. +JS_FRIEND_API(JSObject *) +DefaultObjectForContextOrNull(JSContext *cx); + +JS_FRIEND_API(void) +SetDefaultObjectForContext(JSContext *cx, JSObject *obj); + JS_FRIEND_API(void) NotifyAnimationActivity(JSObject *obj); @@ -469,11 +500,11 @@ inline bool GetObjectProto(JSContext *cx, JS::Handle obj, JS::MutableHandle proto) { js::Class *clasp = GetObjectClass(obj); - if (clasp == &js::ObjectProxyClass || - clasp == &js::OuterWindowProxyClass || - clasp == &js::FunctionProxyClass) + if (clasp == js::ObjectProxyClassPtr || + clasp == js::OuterWindowProxyClassPtr || + clasp == js::FunctionProxyClassPtr) { - return JS_GetPrototype(cx, obj, proto.address()); + return JS_GetPrototype(cx, obj, proto); } proto.set(reinterpret_cast(obj.get())->type->proto); @@ -535,6 +566,13 @@ GetAtomChars(JSAtom *atom) return reinterpret_cast(atom)->chars; } +inline size_t +GetAtomLength(JSAtom *atom) +{ + using shadow::Atom; + return reinterpret_cast(atom)->lengthAndFlags >> Atom::LENGTH_SHIFT; +} + inline JSLinearString * AtomToLinearString(JSAtom *atom) { @@ -589,6 +627,12 @@ GetNativeStackLimit(const JSRuntime *rt) return PerThreadDataFriendFields::getMainThread(rt)->nativeStackLimit; } +inline uintptr_t +GetNativeStackLimit(JSContext *cx) +{ + return GetNativeStackLimit(GetRuntime(cx)); +} + /* * These macros report a stack overflow and run |onerror| if we are close to * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little @@ -598,18 +642,15 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \ js_ReportOverRecursed(cx); \ onerror; \ } \ JS_END_MACRO -#define JS_CHECK_RECURSION_WITH_EXTRA_DONT_REPORT(cx, extra, onerror) \ +#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ JS_BEGIN_MACRO \ - uint8_t stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ - &stackDummy_ - (extra))) \ - { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ onerror; \ } \ JS_END_MACRO @@ -617,7 +658,7 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_CHROME_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ + if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \ &stackDummy_, \ 1024 * sizeof(size_t))) \ { \ @@ -754,13 +795,13 @@ extern JS_FRIEND_API(bool) IsContextRunningJS(JSContext *cx); typedef void -(* AnalysisPurgeCallback)(JSRuntime *rt, JSFlatString *desc); +(* AnalysisPurgeCallback)(JSRuntime *rt, JS::Handle desc); extern JS_FRIEND_API(AnalysisPurgeCallback) SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback); typedef JSBool -(* DOMInstanceClassMatchesProto)(JSHandleObject protoObject, uint32_t protoID, +(* DOMInstanceClassMatchesProto)(JS::HandleObject protoObject, uint32_t protoID, uint32_t depth); struct JSDOMCallbacks { DOMInstanceClassMatchesProto instanceClassMatchesProto; @@ -851,10 +892,10 @@ NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& targetFilter, NukeReferencesToWindow nukeReferencesToWindow); -/* Specify information about ListBase proxies in the DOM, for use by ICs. */ +/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ /* - * The ListBaseShadowsCheck function will be called to check if the property for + * The DOMProxyShadowsCheck function will be called to check if the property for * id should be gotten from the prototype, or if there is an own property that * shadows it. * If DoesntShadow is returned then the slot at listBaseExpandoSlot should @@ -873,25 +914,31 @@ struct ExpandoAndGeneration { generation(0) {} - Value expando; + void Unlink() + { + ++generation; + expando.setUndefined(); + } + + JS::Heap expando; uint32_t generation; }; -typedef enum ListBaseShadowsResult { +typedef enum DOMProxyShadowsResult { ShadowCheckFailed, Shadows, DoesntShadow, DoesntShadowUnique -} ListBaseShadowsResult; -typedef ListBaseShadowsResult -(* ListBaseShadowsCheck)(JSContext* cx, JSHandleObject object, JSHandleId id); +} DOMProxyShadowsResult; +typedef DOMProxyShadowsResult +(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); JS_FRIEND_API(void) -SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot, - ListBaseShadowsCheck listBaseShadowsCheck); +SetDOMProxyInformation(void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, + DOMProxyShadowsCheck domProxyShadowsCheck); -void *GetListBaseHandlerFamily(); -uint32_t GetListBaseExpandoSlot(); -ListBaseShadowsCheck GetListBaseShadowsCheck(); +void *GetDOMProxyHandlerFamily(); +uint32_t GetDOMProxyExpandoSlot(); +DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); } /* namespace js */ @@ -960,6 +1007,137 @@ enum ViewType { }; } /* namespace ArrayBufferView */ + +/* + * A helper for building up an ArrayBuffer object's data + * before creating the ArrayBuffer itself. Will do doubling + * based reallocation, up to an optional maximum growth given. + * + * When all the data has been appended, call getArrayBuffer, + * passing in the JSContext* for which the ArrayBuffer object + * is to be created. This also implicitly resets the builder, + * or it can be reset explicitly at any point by calling reset(). + */ +class ArrayBufferBuilder +{ + void *rawcontents_; + uint8_t *dataptr_; + uint32_t capacity_; + uint32_t length_; + public: + ArrayBufferBuilder() + : rawcontents_(NULL), + dataptr_(NULL), + capacity_(0), + length_(0) + { + } + + ~ArrayBufferBuilder() { + reset(); + } + + void reset() { + if (rawcontents_) + JS_free(NULL, rawcontents_); + rawcontents_ = dataptr_ = NULL; + capacity_ = length_ = 0; + } + + // will truncate if newcap is < length() + bool setCapacity(uint32_t newcap) { + if (!JS_ReallocateArrayBufferContents(NULL, newcap, &rawcontents_, &dataptr_)) + return false; + + capacity_ = newcap; + if (length_ > newcap) + length_ = newcap; + + return true; + } + + // Append datalen bytes from data to the current buffer. If we + // need to grow the buffer, grow by doubling the size up to a + // maximum of maxgrowth (if given). If datalen is greater than + // what the new capacity would end up as, then grow by datalen. + // + // The data parameter must not overlap with anything beyond the + // builder's current valid contents [0..length) + bool append(const uint8_t *newdata, uint32_t datalen, uint32_t maxgrowth = 0) { + if (length_ + datalen > capacity_) { + uint32_t newcap; + // double while under maxgrowth or if not specified + if (!maxgrowth || capacity_ < maxgrowth) + newcap = capacity_ * 2; + else + newcap = capacity_ + maxgrowth; + + // but make sure there's always enough to satisfy our request + if (newcap < length_ + datalen) + newcap = length_ + datalen; + + // did we overflow? + if (newcap < capacity_) + return false; + + if (!setCapacity(newcap)) + return false; + } + + // assert that the region isn't overlapping so we can memcpy; + JS_ASSERT(!areOverlappingRegions(newdata, datalen, dataptr_ + length_, datalen)); + + memcpy(dataptr_ + length_, newdata, datalen); + length_ += datalen; + + return true; + } + + uint8_t *data() { + return dataptr_; + } + + uint32_t length() { + return length_; + } + + uint32_t capacity() { + return capacity_; + } + + JSObject* getArrayBuffer(JSContext *cx) { + // we need to check for length_ == 0, because nothing may have been + // added + if (capacity_ > length_ || length_ == 0) { + if (!setCapacity(length_)) + return NULL; + } + + JSObject* obj = JS_NewArrayBufferWithContents(cx, rawcontents_); + if (!obj) + return NULL; + + rawcontents_ = dataptr_ = NULL; + length_ = capacity_ = 0; + + return obj; + } + +protected: + + static bool areOverlappingRegions(const uint8_t *start1, uint32_t length1, + const uint8_t *start2, uint32_t length2) + { + const uint8_t *end1 = start1 + length1; + const uint8_t *end2 = start2 + length2; + + const uint8_t *max_start = start1 > start2 ? start1 : start2; + const uint8_t *min_end = end1 < end2 ? end1 : end2; + + return max_start < min_end; + } +}; + } /* namespace js */ typedef js::ArrayBufferView::ViewType JSArrayBufferViewType; @@ -1296,26 +1474,116 @@ JS_GetDataViewByteLength(JSObject *obj); JS_FRIEND_API(void *) JS_GetDataViewData(JSObject *obj); +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitGetterOp. + */ +class JSJitGetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitGetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args.rval()) + {} + + explicit JSJitGetterCallArgs(JS::Rooted* rooted) + : JS::MutableHandleValue(rooted) + {} + + JS::MutableHandleValue rval() { + return *this; + } +}; + +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitSetterOp. + */ +class JSJitSetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitSetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args[0]) + {} + + JS::MutableHandleValue operator[](unsigned i) { + MOZ_ASSERT(i == 0); + return *this; + } + + unsigned length() const { return 1; } + + // Add get() or maybe hasDefined() as needed +}; + +struct JSJitMethodCallArgsTraits; + +/* + * A class, expected to be passed by reference, which represents the CallArgs + * for a JSJitMethodOp. + */ +class JSJitMethodCallArgs : protected JS::detail::CallArgsBase +{ + private: + typedef JS::detail::CallArgsBase Base; + friend struct JSJitMethodCallArgsTraits; + + public: + explicit JSJitMethodCallArgs(const JS::CallArgs& args) { + argv_ = args.array(); + argc_ = args.length(); + } + + JS::MutableHandleValue rval() const { + return Base::rval(); + } + + unsigned length() const { return Base::length(); } + + JS::MutableHandleValue operator[](unsigned i) const { + return Base::operator[](i); + } + + bool hasDefined(unsigned i) const { + return Base::hasDefined(i); + } + + // Add get() as needed +}; + +struct JSJitMethodCallArgsTraits +{ + static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); + static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); +}; + /* * This struct contains metadata passed from the DOM to the JS Engine for JIT * optimizations on DOM property accessors. Eventually, this should be made * available to general JSAPI users, but we are not currently ready to do so. */ typedef bool -(* JSJitPropertyOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, JS::Value *vp); +(* JSJitGetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitGetterCallArgs args); typedef bool -(* JSJitMethodOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, unsigned argc, JS::Value *vp); +(* JSJitSetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitSetterCallArgs args); +typedef bool +(* JSJitMethodOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, const JSJitMethodCallArgs& args); struct JSJitInfo { enum OpType { Getter, Setter, - Method + Method, + OpType_None }; - JSJitPropertyOp op; + union { + JSJitGetterOp getter; + JSJitSetterOp setter; + JSJitMethodOp method; + }; uint32_t protoID; uint32_t depth; OpType type; @@ -1325,12 +1593,18 @@ struct JSJitInfo { keep returning the same value for the given "this" object" */ JSValueType returnType; /* The return type tag. Might be JSVAL_TYPE_UNKNOWN */ + + /* An alternative native that's safe to call in parallel mode. */ + JSParallelNative parallelNative; }; +#define JS_JITINFO_NATIVE_PARALLEL(op) \ + {{NULL},0,0,JSJitInfo::OpType_None,false,false,false,JSVAL_TYPE_MISSING,op} + static JS_ALWAYS_INLINE const JSJitInfo * FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) { - JS_ASSERT(js::GetObjectClass(&v.toObject()) == &js::FunctionClass); + JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr); return reinterpret_cast(&v.toObject())->jitinfo; } @@ -1482,9 +1756,46 @@ assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id); inline void assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id) {}; #endif +typedef bool +(* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata); + +/* + * Specify a callback to invoke when creating each JS object in the current + * compartment, which may return a metadata object to associate with the + * object. Objects with different metadata have different shape hierarchies, + * so for efficiency, objects should generally try to share metadata objects. + */ +JS_FRIEND_API(void) +SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback); + +/* Manipulate the metadata associated with an object. */ + +JS_FRIEND_API(bool) +SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata); + +JS_FRIEND_API(JSObject *) +GetObjectMetadata(JSObject *obj); + /* ES5 8.12.8. */ extern JS_FRIEND_API(JSBool) -DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); +DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValue vp); + +/* + * Helper function. To approximate a call to the [[DefineOwnProperty]] internal + * method described in ES5, first call this, then call JS_DefinePropertyById. + * + * JS_DefinePropertyById by itself does not enforce the invariants on + * non-configurable properties when obj->isNative(). This function performs the + * relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11), + * but only if obj is native. + * + * The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as + * a sort of extension point, but there is no hook in js::Class, + * js::ProxyHandler, or the JSAPI with precisely the right semantics for it. + */ +extern JS_FRIEND_API(bool) +CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, + PropertyOp getter, StrictPropertyOp setter, unsigned attrs); } /* namespace js */ @@ -1495,4 +1806,26 @@ js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, extern JS_FRIEND_API(JSBool) js_ReportIsNotFunction(JSContext *cx, const JS::Value& v); -#endif /* jsfriendapi_h___ */ +#ifdef JSGC_GENERATIONAL +extern JS_FRIEND_API(void) +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data); + +extern JS_FRIEND_API(void) +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data); +#else +inline void +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data) {} + +inline void +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data) {} +#endif /* JSGC_GENERATIONAL */ + +#endif /* jsfriendapi_h */ diff --git a/external/spidermonkey/include/android/jslock.h b/external/spidermonkey/include/android/jslock.h index b4a28a9fa9..522034ad68 100644 --- a/external/spidermonkey/include/android/jslock.h +++ b/external/spidermonkey/include/android/jslock.h @@ -4,18 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jslock_h__ -#define jslock_h__ - -#include "jsapi.h" +#ifndef jslock_h +#define jslock_h #ifdef JS_THREADSAFE +# include "jsapi.h" # include "pratom.h" -# include "prlock.h" # include "prcvar.h" -# include "prthread.h" # include "prinit.h" +# include "prlock.h" +# include "prthread.h" # define JS_ATOMIC_INCREMENT(p) PR_ATOMIC_INCREMENT((int32_t *)(p)) # define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p)) @@ -40,4 +39,4 @@ typedef struct PRLock PRLock; #endif /* JS_THREADSAFE */ -#endif /* jslock_h___ */ +#endif /* jslock_h */ diff --git a/external/spidermonkey/include/android/json.h b/external/spidermonkey/include/android/json.h deleted file mode 100644 index 7fa2c117c8..0000000000 --- a/external/spidermonkey/include/android/json.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef json_h___ -#define json_h___ - -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsapi.h" - -#include "js/Vector.h" - -#define JSON_MAX_DEPTH 2048 -#define JSON_PARSER_BUFSIZE 1024 - -extern JSObject * -js_InitJSONClass(JSContext *cx, js::HandleObject obj); - -extern JSBool -js_Stringify(JSContext *cx, js::MutableHandleValue vp, - JSObject *replacer, js::Value space, - js::StringBuffer &sb); - -// Avoid build errors on certain platforms that define these names as constants -#undef STRICT -#undef LEGACY - -/* - * The type of JSON decoding to perform. Strict decoding is to-the-spec; - * legacy decoding accepts a few non-JSON syntaxes historically accepted by the - * implementation. (Full description of these deviations is deliberately - * omitted.) New users should use strict decoding rather than legacy decoding, - * as legacy decoding might be removed at a future time. - */ -enum DecodingMode { STRICT, LEGACY }; - -namespace js { - -extern JS_FRIEND_API(JSBool) -ParseJSONWithReviver(JSContext *cx, JS::StableCharPtr chars, size_t length, HandleValue filter, - MutableHandleValue vp, DecodingMode decodingMode = STRICT); - -} /* namespace js */ - -#endif /* json_h___ */ diff --git a/external/spidermonkey/include/android/jsperf.h b/external/spidermonkey/include/android/jsperf.h index a0287b4a57..468ce8609c 100644 --- a/external/spidermonkey/include/android/jsperf.h +++ b/external/spidermonkey/include/android/jsperf.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsperf_h___ -#define jsperf_h___ +#ifndef perf_jsperf_h +#define perf_jsperf_h #include "jsapi.h" @@ -127,4 +127,4 @@ extern JS_FRIEND_API(PerfMeasurement*) } // namespace JS -#endif // jsperf_h___ +#endif /* perf_jsperf_h */ diff --git a/external/spidermonkey/include/android/jsprf.h b/external/spidermonkey/include/android/jsprf.h index c0891f0e9e..ce159d8115 100644 --- a/external/spidermonkey/include/android/jsprf.h +++ b/external/spidermonkey/include/android/jsprf.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprf_h___ -#define jsprf_h___ +#ifndef jsprf_h +#define jsprf_h /* ** API for PR printf like routines. Supports the following formats @@ -24,9 +24,11 @@ ** %f - float ** %g - float */ -#include "jstypes.h" -#include + #include +#include + +#include "jstypes.h" /* ** sprintf into a fixed size buffer. Guarantees that a NUL is at the end @@ -75,4 +77,4 @@ extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); extern JS_PUBLIC_API(uint32_t) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); -#endif /* jsprf_h___ */ +#endif /* jsprf_h */ diff --git a/external/spidermonkey/include/android/jsprototypes.h b/external/spidermonkey/include/android/jsprototypes.h index 007d25d720..f9bacac409 100644 --- a/external/spidermonkey/include/android/jsprototypes.h +++ b/external/spidermonkey/include/android/jsprototypes.h @@ -6,8 +6,8 @@ /* A higher-order macro for enumerating all JSProtoKey values. */ -#ifndef jsprototypes_h___ -#define jsprototypes_h___ +#ifndef jsprototypes_h +#define jsprototypes_h #include "jsversion.h" @@ -56,5 +56,20 @@ macro(DataView, 35, js_InitTypedArrayClasses) \ macro(ParallelArray, 36, js_InitParallelArrayClass) \ macro(Intl, 37, js_InitIntlClass) \ + macro(Type, 38, js_InitBinaryDataClasses) \ + macro(Data, 39, js_InitBinaryDataClasses) \ + macro(uint8, 40, js_InitBinaryDataClasses) \ + macro(uint16, 41, js_InitBinaryDataClasses) \ + macro(uint32, 42, js_InitBinaryDataClasses) \ + macro(uint64, 43, js_InitBinaryDataClasses) \ + macro(int8, 44, js_InitBinaryDataClasses) \ + macro(int16, 45, js_InitBinaryDataClasses) \ + macro(int32, 46, js_InitBinaryDataClasses) \ + macro(int64, 47, js_InitBinaryDataClasses) \ + macro(float32, 48, js_InitBinaryDataClasses) \ + macro(float64, 49, js_InitBinaryDataClasses) \ + macro(ArrayType, 50, js_InitBinaryDataClasses) \ + macro(StructType, 51, js_InitBinaryDataClasses) \ + macro(ArrayTypeObject, 52, js_InitBinaryDataClasses) \ -#endif /* jsprototypes_h___ */ +#endif /* jsprototypes_h */ diff --git a/external/spidermonkey/include/android/jsproxy.h b/external/spidermonkey/include/android/jsproxy.h index 399490eddc..56868a05c3 100644 --- a/external/spidermonkey/include/android/jsproxy.h +++ b/external/spidermonkey/include/android/jsproxy.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsproxy_h___ -#define jsproxy_h___ +#ifndef jsproxy_h +#define jsproxy_h #include "jsapi.h" #include "jsfriendapi.h" @@ -129,7 +129,7 @@ class JS_FRIEND_API(BaseProxyHandler) MutableHandleValue vp); /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) = 0; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) = 0; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -190,7 +190,7 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -242,7 +242,7 @@ class Proxy static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); /* Spidermonkey extensions. */ - static bool isExtensible(JSObject *proxy); + static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -259,12 +259,17 @@ class Proxy inline bool IsObjectProxyClass(const Class *clasp) { - return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass; + return clasp == js::ObjectProxyClassPtr || clasp == js::OuterWindowProxyClassPtr; } inline bool IsFunctionProxyClass(const Class *clasp) { - return clasp == &js::FunctionProxyClass; + return clasp == js::FunctionProxyClassPtr; +} + +inline bool IsProxyClass(const Class *clasp) +{ + return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); } inline bool IsObjectProxy(JSObject *obj) @@ -279,36 +284,33 @@ inline bool IsFunctionProxy(JSObject *obj) inline bool IsProxy(JSObject *obj) { - Class *clasp = GetObjectClass(obj); - return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); + return IsProxyClass(GetObjectClass(obj)); } -/* Shared between object and function proxies. */ /* - * NOTE: JSSLOT_PROXY_PRIVATE is 0, because that way slot 0 is usable by API + * These are part of the API. + * + * NOTE: PROXY_PRIVATE_SLOT is 0 because that way slot 0 is usable by API * clients for both proxy and non-proxy objects. So an API client that only * needs to store one slot's worth of data doesn't need to branch on what sort * of object it has. */ -const uint32_t JSSLOT_PROXY_PRIVATE = 0; -const uint32_t JSSLOT_PROXY_HANDLER = 1; -const uint32_t JSSLOT_PROXY_EXTRA = 2; -/* Function proxies only. */ -const uint32_t JSSLOT_PROXY_CALL = 4; -const uint32_t JSSLOT_PROXY_CONSTRUCT = 5; +const uint32_t PROXY_PRIVATE_SLOT = 0; +const uint32_t PROXY_HANDLER_SLOT = 1; +const uint32_t PROXY_EXTRA_SLOT = 2; inline BaseProxyHandler * GetProxyHandler(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return (BaseProxyHandler *) GetReservedSlot(obj, JSSLOT_PROXY_HANDLER).toPrivate(); + return (BaseProxyHandler *) GetReservedSlot(obj, PROXY_HANDLER_SLOT).toPrivate(); } inline const Value & GetProxyPrivate(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE); + return GetReservedSlot(obj, PROXY_PRIVATE_SLOT); } inline JSObject * @@ -322,14 +324,14 @@ inline const Value & GetProxyExtra(JSObject *obj, size_t n) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n); + return GetReservedSlot(obj, PROXY_EXTRA_SLOT + n); } inline void SetProxyHandler(JSObject *obj, BaseProxyHandler *handler) { JS_ASSERT(IsProxy(obj)); - SetReservedSlot(obj, JSSLOT_PROXY_HANDLER, PrivateValue(handler)); + SetReservedSlot(obj, PROXY_HANDLER_SLOT, PrivateValue(handler)); } inline void @@ -337,7 +339,7 @@ SetProxyExtra(JSObject *obj, size_t n, const Value &extra) { JS_ASSERT(IsProxy(obj)); JS_ASSERT(n <= 1); - SetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n, extra); + SetReservedSlot(obj, PROXY_EXTRA_SLOT + n, extra); } enum ProxyCallable { @@ -346,7 +348,7 @@ enum ProxyCallable { }; JS_FRIEND_API(JSObject *) -NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv, +NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto, JSObject *parent, ProxyCallable callable = ProxyNotCallable); JSObject * @@ -426,6 +428,6 @@ class JS_FRIEND_API(AutoWaivePolicy) { } /* namespace js */ extern JS_FRIEND_API(JSObject *) -js_InitProxyClass(JSContext *cx, JSHandleObject obj); +js_InitProxyClass(JSContext *cx, JS::HandleObject obj); -#endif +#endif /* jsproxy_h */ diff --git a/external/spidermonkey/include/android/jsprvtd.h b/external/spidermonkey/include/android/jsprvtd.h index 4db5ed8c36..1fbc086a7c 100644 --- a/external/spidermonkey/include/android/jsprvtd.h +++ b/external/spidermonkey/include/android/jsprvtd.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprvtd_h___ -#define jsprvtd_h___ +#ifndef jsprvtd_h +#define jsprvtd_h /* * JS private typename definitions. * @@ -56,13 +56,7 @@ typedef struct JSStackHeader JSStackHeader; typedef struct JSSubString JSSubString; typedef struct JSSpecializedNative JSSpecializedNative; -/* - * Template declarations. - * - * jsprvtd.h can be included in both C and C++ translation units. For C++, it - * may possibly be wrapped in an extern "C" block which does not agree with - * templates. - */ +/* String typedefs. */ class JSDependentString; class JSExtensibleString; class JSExternalString; @@ -76,6 +70,7 @@ namespace js { struct ArgumentsData; struct Class; +class AutoNameVector; class RegExpGuard; class RegExpObject; class RegExpObjectBuilder; @@ -83,6 +78,7 @@ class RegExpShared; class RegExpStatics; class MatchPairs; class PropertyName; +class LazyScript; enum RegExpFlag { @@ -95,19 +91,14 @@ enum RegExpFlag AllFlags = 0x0f }; -class ExecuteArgsGuard; -class InvokeFrameGuard; -class InvokeArgsGuard; class StringBuffer; class FrameRegs; class StackFrame; -class StackSegment; -class StackSpace; -class ContextStack; class ScriptFrameIter; class Proxy; +class JS_FRIEND_API(AutoEnterPolicy); class JS_FRIEND_API(BaseProxyHandler); class JS_FRIEND_API(Wrapper); class JS_FRIEND_API(CrossCompartmentWrapper); @@ -140,24 +131,29 @@ class WatchpointMap; typedef JSObject Env; typedef JSNative Native; +typedef JSParallelNative ParallelNative; +typedef JSThreadSafeNative ThreadSafeNative; typedef JSPropertyOp PropertyOp; typedef JSStrictPropertyOp StrictPropertyOp; typedef JSPropertyDescriptor PropertyDescriptor; +struct SourceCompressionToken; + namespace frontend { struct BytecodeEmitter; struct Definition; +class FullParseHandler; class FunctionBox; class ObjectBox; struct Token; struct TokenPos; class TokenStream; class ParseMapPool; -struct ParseNode; +class ParseNode; template -struct Parser; +class Parser; } /* namespace frontend */ @@ -284,18 +280,18 @@ typedef void * if an error or exception was thrown on cx. */ typedef JSObject * -(* JSObjectOp)(JSContext *cx, JSHandleObject obj); +(* JSObjectOp)(JSContext *cx, JS::Handle obj); /* Signature for class initialization ops. */ typedef JSObject * -(* JSClassInitializerOp)(JSContext *cx, JSHandleObject obj); +(* JSClassInitializerOp)(JSContext *cx, JS::HandleObject obj); /* * Hook that creates an iterator object for a given object. Returns the * iterator object or null if an error or exception was thrown on cx. */ typedef JSObject * -(* JSIteratorOp)(JSContext *cx, JSHandleObject obj, JSBool keysonly); +(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, JSBool keysonly); -#endif /* jsprvtd_h___ */ +#endif /* jsprvtd_h */ diff --git a/external/spidermonkey/include/android/jspubtd.h b/external/spidermonkey/include/android/jspubtd.h index 6b7e63e6ba..96f5dd8297 100644 --- a/external/spidermonkey/include/android/jspubtd.h +++ b/external/spidermonkey/include/android/jspubtd.h @@ -4,16 +4,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jspubtd_h___ -#define jspubtd_h___ +#ifndef jspubtd_h +#define jspubtd_h /* * JS public API typedefs. */ +#include "mozilla/PodOperations.h" + #include "jsprototypes.h" #include "jstypes.h" +#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) +# define JSGC_TRACK_EXACT_ROOTS +#endif + namespace JS { /* @@ -25,6 +31,8 @@ class Value; template class Rooted; +class JS_PUBLIC_API(AutoGCRooter); + struct Zone; } /* namespace JS */ @@ -44,10 +52,8 @@ struct Zone; * oblivious to the change. This feature can be explicitly disabled in debug * builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. */ - // Needed for cocos2d-js -#define JS_NO_JSVAL_JSID_STRUCT_TYPES - +#define JS_NO_JSVAL_JSID_STRUCT_TYPES # if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) # define JS_USE_JSID_STRUCT_TYPES # endif @@ -154,9 +160,10 @@ typedef enum { JSTRACE_SCRIPT, /* - * Trace kinds internal to the engine. The embedding can only them if it - * implements JSTraceCallback. + * Trace kinds internal to the engine. The embedding can only see them if + * it implements JSTraceCallback. */ + JSTRACE_LAZY_SCRIPT, JSTRACE_IONCODE, JSTRACE_SHAPE, JSTRACE_BASE_SHAPE, @@ -229,6 +236,18 @@ struct Runtime namespace js { +/* + * Parallel operations in general can have one of three states. They may + * succeed, fail, or "bail", where bail indicates that the code encountered an + * unexpected condition and should be re-run sequentially. Different + * subcategories of the "bail" state are encoded as variants of TP_RETRY_*. + */ +enum ParallelResult { TP_SUCCESS, TP_RETRY_SEQUENTIALLY, TP_RETRY_AFTER_GC, TP_FATAL }; + +struct ThreadSafeContext; +struct ForkJoinSlice; +class ExclusiveContext; + class Allocator; class SkipRoot; @@ -273,18 +292,28 @@ template <> struct RootKind : SpecificRootKind struct RootKind : SpecificRootKind {}; template <> struct RootKind : SpecificRootKind {}; -struct ContextFriendFields { - JSRuntime *const runtime; +struct ContextFriendFields +{ + protected: + JSRuntime *const runtime_; /* The current compartment. */ - JSCompartment *compartment; + JSCompartment *compartment_; /* The current zone. */ JS::Zone *zone_; + public: explicit ContextFriendFields(JSRuntime *rt) - : runtime(rt), compartment(NULL), zone_(NULL) - { } + : runtime_(rt), compartment_(NULL), zone_(NULL), autoGCRooters(NULL) + { +#ifdef JSGC_TRACK_EXACT_ROOTS + mozilla::PodArrayZero(thingGCRooters); +#endif +#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) + skipGCRooters = NULL; +#endif + } static const ContextFriendFields *get(const JSContext *cx) { return reinterpret_cast(cx); @@ -294,7 +323,7 @@ struct ContextFriendFields { return reinterpret_cast(cx); } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -313,6 +342,13 @@ struct ContextFriendFields { */ SkipRoot *skipGCRooters; #endif + + /* Stack of thread-stack-allocated GC roots. */ + JS::AutoGCRooter *autoGCRooters; + + friend JSRuntime *GetRuntime(const JSContext *cx); + friend JSCompartment *GetContextCompartment(const JSContext *cx); + friend JS::Zone *GetContextZone(const JSContext *cx); }; class PerThreadData; @@ -338,7 +374,7 @@ struct PerThreadDataFriendFields PerThreadDataFriendFields(); -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -384,4 +420,4 @@ struct PerThreadDataFriendFields } /* namespace js */ -#endif /* jspubtd_h___ */ +#endif /* jspubtd_h */ diff --git a/external/spidermonkey/include/android/jstypes.h b/external/spidermonkey/include/android/jstypes.h index e4c02f8d8d..17f67f70e1 100644 --- a/external/spidermonkey/include/android/jstypes.h +++ b/external/spidermonkey/include/android/jstypes.h @@ -18,8 +18,8 @@ ** for all C files. **/ -#ifndef jstypes_h___ -#define jstypes_h___ +#ifndef jstypes_h +#define jstypes_h #include "mozilla/Attributes.h" #include "mozilla/Util.h" @@ -279,4 +279,4 @@ typedef int JSBool; # define JS_EXTENSION_(s) s #endif -#endif /* jstypes_h___ */ +#endif /* jstypes_h */ diff --git a/external/spidermonkey/include/android/jsutil.h b/external/spidermonkey/include/android/jsutil.h index 49e1641c61..4020822be1 100644 --- a/external/spidermonkey/include/android/jsutil.h +++ b/external/spidermonkey/include/android/jsutil.h @@ -8,19 +8,19 @@ * PR assertion checker. */ -#ifndef jsutil_h___ -#define jsutil_h___ +#ifndef jsutil_h +#define jsutil_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/GuardObjects.h" -#include "js/Utility.h" - #ifdef USE_ZLIB -#include "zlib.h" +#include #endif +#include "js/Utility.h" + /* Forward declarations. */ struct JSContext; @@ -204,15 +204,6 @@ UnsignedPtrDiff(const void *bigger, const void *smaller) return size_t(bigger) - size_t(smaller); } -/* - * Ordinarily, a function taking a JSContext* 'cx' parameter reports errors on - * the context. In some cases, functions optionally report and indicate this by - * taking a nullable 'maybecx' parameter. In some cases, though, a function - * always needs a 'cx', but optionally reports. This option is presented by the - * MaybeReportError. - */ -enum MaybeReportError { REPORT_ERROR = true, DONT_REPORT_ERROR = false }; - /*****************************************************************************/ /* A bit array is an array of bits represented by an array of words (size_t). */ @@ -391,4 +382,4 @@ typedef size_t jsbitmap; JS_END_MACRO #endif -#endif /* jsutil_h___ */ +#endif /* jsutil_h */ diff --git a/external/spidermonkey/include/android/jsversion.h b/external/spidermonkey/include/android/jsversion.h index f3169fb5d1..1780616a32 100644 --- a/external/spidermonkey/include/android/jsversion.h +++ b/external/spidermonkey/include/android/jsversion.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsversion_h___ -#define jsversion_h___ +#ifndef jsversion_h +#define jsversion_h /* * Deprecated JS_VERSION handler. @@ -61,7 +61,7 @@ # define NEW_OBJECT_REPRESENTATION_ONLY() ((void)0) #else # define NEW_OBJECT_REPRESENTATION_ONLY() \ - MOZ_NOT_REACHED("don't call this! to be used in the new object representation") + MOZ_ASSUME_UNREACHABLE("don't call this! to be used in the new object representation") #endif -#endif /* jsversion_h___ */ +#endif /* jsversion_h */ diff --git a/external/spidermonkey/include/android/jswrapper.h b/external/spidermonkey/include/android/jswrapper.h index d0c0fc625c..f78df7db60 100644 --- a/external/spidermonkey/include/android/jswrapper.h +++ b/external/spidermonkey/include/android/jswrapper.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jswrapper_h___ -#define jswrapper_h___ +#ifndef jswrapper_h +#define jswrapper_h #include "mozilla/Attributes.h" @@ -66,8 +66,6 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler static Wrapper singleton; static Wrapper singletonWithPrototype; - - static void *getWrapperFamily(); }; /* Base class for all cross compartment wrapper handlers. */ @@ -105,7 +103,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -139,7 +137,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base public: SecurityWrapper(unsigned flags); - virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) MOZ_OVERRIDE; @@ -185,7 +183,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -297,4 +295,4 @@ struct JS_FRIEND_API(AutoMaybeTouchDeadZones) } /* namespace js */ -#endif +#endif /* jswrapper_h */ diff --git a/external/spidermonkey/include/android/mozilla/AllocPolicy.h b/external/spidermonkey/include/android/mozilla/AllocPolicy.h new file mode 100644 index 0000000000..20087e93bb --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/AllocPolicy.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * An allocation policy concept, usable for structures and algorithms to + * control how memory is allocated and how failures are handled. + */ + +#ifndef mozilla_AllocPolicy_h +#define mozilla_AllocPolicy_h + +#include +#include + +namespace mozilla { + +/* + * Allocation policies are used to implement the standard allocation behaviors + * in a customizable way. Additionally, custom behaviors may be added to these + * behaviors, such as additionally reporting an error through an out-of-band + * mechanism when OOM occurs. The concept modeled here is as follows: + * + * - public copy constructor, assignment, destructor + * - void* malloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* calloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* realloc_(void*, size_t, size_t) + * Responsible for OOM reporting when null is returned. The *used* bytes + * of the previous buffer is passed in (rather than the old allocation + * size), in addition to the *new* allocation size requested. + * - void free_(void*) + * - void reportAllocOverflow() const + * Called on allocation overflow (that is, an allocation implicitly tried + * to allocate more than the available memory space -- think allocating an + * array of large-size objects, where N * size overflows) before null is + * returned. + * + * mfbt provides (and typically uses by default) only MallocAllocPolicy, which + * does nothing more than delegate to the malloc/alloc/free functions. + */ + +/* + * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no + * extra behaviors. + */ +class MallocAllocPolicy +{ + public: + void* malloc_(size_t bytes) { return malloc(bytes); } + void* calloc_(size_t bytes) { return calloc(bytes, 1); } + void* realloc_(void* p, size_t oldBytes, size_t bytes) { return realloc(p, bytes); } + void free_(void* p) { free(p); } + void reportAllocOverflow() const {} +}; + + +} // namespace mozilla + +#endif /* mozilla_AllocPolicy_h */ diff --git a/external/spidermonkey/include/android/mozilla/Array.h b/external/spidermonkey/include/android/mozilla/Array.h new file mode 100644 index 0000000000..5af9aaa133 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Array.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A compile-time constant-length array with bounds-checking assertions. */ + +#ifndef mozilla_Array_h +#define mozilla_Array_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" + +#include + +namespace mozilla { + +template +class Array +{ + T arr[Length]; + + public: + T& operator[](size_t i) { + MOZ_ASSERT(i < Length); + return arr[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(i < Length); + return arr[i]; + } +}; + +template +class Array +{ + public: + T& operator[](size_t i) { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } + + const T& operator[](size_t i) const { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } +}; + +} /* namespace mozilla */ + +#endif /* mozilla_Array_h */ diff --git a/external/spidermonkey/include/android/mozilla/Assertions.h b/external/spidermonkey/include/android/mozilla/Assertions.h index 5ead7f493e..00b7037802 100644 --- a/external/spidermonkey/include/android/mozilla/Assertions.h +++ b/external/spidermonkey/include/android/mozilla/Assertions.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of runtime and static assertion macros for C and C++. */ -#ifndef mozilla_Assertions_h_ -#define mozilla_Assertions_h_ +#ifndef mozilla_Assertions_h +#define mozilla_Assertions_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" @@ -39,44 +40,24 @@ #endif /* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time*. This - * can be useful when you make certain assumptions about what must hold for + * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. + * In C++11, static_assert is provided by the compiler to the same effect. + * This can be useful when you make certain assumptions about what must hold for * optimal, or even correct, behavior. For example, you might assert that the * size of a struct is a multiple of the target architecture's word size: * * struct S { ... }; + * // C * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, * "S should be a multiple of word size for efficiency"); + * // C++11 + * static_assert(sizeof(S) % sizeof(size_t) == 0, + * "S should be a multiple of word size for efficiency"); * * This macro can be used in any location where both an extern declaration and a * typedef could be used. - * - * Be aware of the gcc 4.2 concerns noted further down when writing patches that - * use this macro, particularly if a patch only bounces on OS X. */ -#ifdef __cplusplus -# if defined(__clang__) -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_extension(cxx_static_assert) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__GNUC__) -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(_MSC_VER) -# if _MSC_VER >= 1600 /* MSVC 10 */ -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__HP_aCC) -# if __HP_aCC >= 62500 && defined(_HP_CXX0x_SOURCE) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# endif -#endif -#ifndef MOZ_STATIC_ASSERT +#ifndef __cplusplus /* * Some of the definitions below create an otherwise-unused typedef. This * triggers compiler warnings with some versions of gcc, so mark the typedefs @@ -124,78 +105,23 @@ # define MOZ_STATIC_ASSERT(cond, reason) \ extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE # endif -#endif #define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) +#else +#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) +#endif #ifdef __cplusplus extern "C" { #endif -/* - * MOZ_CRASH crashes the program, plain and simple, in a Breakpad-compatible - * way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. We use TerminateProcess - * with the exit code aborting would generate because we don't want to invoke - * atexit handlers, destructors, library unload handlers, and so on when our - * process might be in a compromised state. We don't use abort() because - * it'd cause Windows to annoyingly pop up the process error dialog multiple - * times. See bug 345118 and bug 426163. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - TerminateProcess(GetCurrentProcess(), 3); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - ::abort(); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - abort(); \ - } while (0) -# endif -#endif - /* * Prints |s| as an assertion failure (using file and ln as the location of the * assertion) to the standard debug-output channel. * - * Usually you should use MOZ_ASSERT instead of this method. This method is - * primarily for internal use in this header, and only secondarily for use in - * implementing release-build assertions. + * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This + * method is primarily for internal use in this header, and only secondarily + * for use in implementing release-build assertions. */ static MOZ_ALWAYS_INLINE void MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) @@ -209,6 +135,112 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif } +static MOZ_ALWAYS_INLINE void +MOZ_ReportCrash(const char* s, const char* file, int ln) +{ +#ifdef ANDROID + __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", + "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); + fflush(stderr); +#endif +} + +/** + * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should + * call MOZ_CRASH instead. + */ +#if defined(_MSC_VER) + /* + * On MSVC use the __debugbreak compiler intrinsic, which produces an inline + * (not nested in a system function) breakpoint. This distinctively invokes + * Breakpad without requiring system library symbols on all stack-processing + * machines, as a nested breakpoint would require. + * + * We use TerminateProcess with the exit code aborting would generate + * because we don't want to invoke atexit handlers, destructors, library + * unload handlers, and so on when our process might be in a compromised + * state. + * + * We don't use abort() because it'd cause Windows to annoyingly pop up the + * process error dialog multiple times. See bug 345118 and bug 426163. + * + * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the + * compiler doesn't hassle us to provide a return statement after a + * MOZ_REALLY_CRASH() call. + * + * (Technically these are Windows requirements, not MSVC requirements. But + * practically you need MSVC for debugging, and we only ship builds created + * by MSVC, so doing it this way reduces complexity.) + */ + +__declspec(noreturn) __inline void MOZ_NoReturn() {} + +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + ::TerminateProcess(::GetCurrentProcess(), 3); \ + ::MOZ_NoReturn(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + TerminateProcess(GetCurrentProcess(), 3); \ + MOZ_NoReturn(); \ + } while (0) +# endif +#else +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + ::abort(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + abort(); \ + } while (0) +# endif +#endif + +/* + * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a + * Breakpad-compatible way, in both debug and release builds. + * + * MOZ_CRASH is a good solution for "handling" failure cases when you're + * unwilling or unable to handle them more cleanly -- for OOM, for likely memory + * corruption, and so on. It's also a good solution if you need safe behavior + * in release builds as well as debug builds. But if the failure is one that + * should be debugged and fixed, MOZ_ASSERT is generally preferable. + * + * The optional explanation-string, if provided, must be a string literal + * explaining why we're crashing. This argument is intended for use with + * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's + * obvious why we're crashing. + * + * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an + * explanation-string, we print the string to stderr. Otherwise, we don't + * print anything; this is because we want MOZ_CRASH to be 100% safe in release + * builds, and it's hard to print to stderr safely when memory might have been + * corrupted. + */ +#ifndef DEBUG +# define MOZ_CRASH(...) MOZ_REALLY_CRASH() +#else +# define MOZ_CRASH(...) \ + do { \ + MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ + MOZ_REALLY_CRASH(); \ + } while(0) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif @@ -251,7 +283,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* Now the two-argument form. */ @@ -259,7 +291,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* And now, helper macrology up the wazoo. */ @@ -310,14 +342,14 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif /* - * MOZ_NOT_REACHED_MARKER() expands to an expression which states that it is + * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that it is * undefined behavior for execution to reach this point. No guarantees are made * about what will happen if this is reached at runtime. Most code should - * probably use the higher level MOZ_NOT_REACHED, which uses this when + * probably use the higher level MOZ_ASSUME_UNREACHABLE, which uses this when * appropriate. */ #if defined(__clang__) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() #elif defined(__GNUC__) /* * __builtin_unreachable() was implemented in gcc 4.5. If we don't have @@ -325,49 +357,71 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) * in C++ in case there's another abort() visible in local scope. */ # if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() # else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif # endif #elif defined(_MSC_VER) -# define MOZ_NOT_REACHED_MARKER() __assume(0) +# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) #else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif #endif /* - * MOZ_NOT_REACHED(reason) indicates that the given point can't be reached - * during execution: simply reaching that point in execution is a bug. It takes - * as an argument an error message indicating the reason why that point should - * not have been reachable. + * MOZ_ASSUME_UNREACHABLE([reason]) tells the compiler that it can assume that + * the macro call cannot be reached during execution. This lets the compiler + * generate better-optimized code under some circumstances, at the expense of + * the program's behavior being undefined if control reaches the + * MOZ_ASSUME_UNREACHABLE. * - * // ...in a language parser... - * void handle(BooleanLiteralNode node) + * In Gecko, you probably should not use this macro outside of performance- or + * size-critical code, because it's unsafe. If you don't care about code size + * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. + * + * SpiderMonkey is a different beast, and there it's acceptable to use + * MOZ_ASSUME_UNREACHABLE more widely. + * + * Note that MOZ_ASSUME_UNREACHABLE is noreturn, so it's valid not to return a + * value following a MOZ_ASSUME_UNREACHABLE call. + * + * Example usage: + * + * enum ValueType { + * VALUE_STRING, + * VALUE_INT, + * VALUE_FLOAT + * }; + * + * int ptrToInt(ValueType type, void* value) { * { - * if (node.isTrue()) - * handleTrueLiteral(); - * else if (node.isFalse()) - * handleFalseLiteral(); - * else - * MOZ_NOT_REACHED("boolean literal that's not true or false?"); + * // We know for sure that type is either INT or FLOAT, and we want this + * // code to run as quickly as possible. + * switch (type) { + * case VALUE_INT: + * return *(int*) value; + * case VALUE_FLOAT: + * return (int) *(float*) value; + * default: + * MOZ_ASSUME_UNREACHABLE("can only handle VALUE_INT and VALUE_FLOAT"); + * } * } */ #if defined(DEBUG) -# define MOZ_NOT_REACHED(reason) \ +# define MOZ_ASSUME_UNREACHABLE(...) \ do { \ - MOZ_ASSERT(false, reason); \ - MOZ_NOT_REACHED_MARKER(); \ + MOZ_ASSERT(false, "MOZ_ASSUME_UNREACHABLE(" __VA_ARGS__ ")"); \ + MOZ_ASSUME_UNREACHABLE_MARKER(); \ } while (0) #else -# define MOZ_NOT_REACHED(reason) MOZ_NOT_REACHED_MARKER() +# define MOZ_ASSUME_UNREACHABLE(reason) MOZ_ASSUME_UNREACHABLE_MARKER() #endif /* @@ -384,4 +438,4 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) # define MOZ_ALWAYS_FALSE(expr) ((void)(expr)) #endif -#endif /* mozilla_Assertions_h_ */ +#endif /* mozilla_Assertions_h */ diff --git a/external/spidermonkey/include/android/mozilla/Atomics.h b/external/spidermonkey/include/android/mozilla/Atomics.h new file mode 100644 index 0000000000..f876683c3e --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Atomics.h @@ -0,0 +1,1014 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Implements (almost always) lock-free atomic operations. The operations here + * are a subset of that which can be found in C++11's header, with a + * different API to enforce consistent memory ordering constraints. + * + * Anyone caught using |volatile| for inter-thread memory safety needs to be + * sent a copy of this header and the C++11 standard. + */ + +#ifndef mozilla_Atomics_h +#define mozilla_Atomics_h + +#include "mozilla/Assertions.h" +#include "mozilla/TypeTraits.h" + +#include + +/* + * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK + * does not have . So be sure to check for support + * along with C++0x support. + */ +#if defined(__clang__) + /* + * clang doesn't like libstdc++'s version of before GCC 4.7, + * due to the loose typing of the __sync_* family of functions done by + * GCC. We do not have a particularly good way to detect this sort of + * case at this point, so just assume that if we're on a Linux system, + * we can't use the system's . + * + * OpenBSD uses an old libstdc++ 4.2.1 and thus doesnt have . + */ +# if !defined(__linux__) && !defined(__OpenBSD__) && \ + (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && \ + __has_include() +# define MOZ_HAVE_CXX11_ATOMICS +# endif +/* + * Android uses a different C++ standard library that does not provide + * support for . + * + * GCC 4.5.x and 4.6.x's unspecialized std::atomic template doesn't include + * inline definitions for the functions declared therein. This oversight + * leads to linking errors when using atomic enums. We therefore require + * GCC 4.7 or higher. + */ +#elif defined(__GNUC__) && !defined(__ANDROID__) +# include "mozilla/Compiler.h" +# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && \ + MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) +# define MOZ_HAVE_CXX11_ATOMICS +# endif +#elif defined(_MSC_VER) && _MSC_VER >= 1700 +# define MOZ_HAVE_CXX11_ATOMICS +#endif + +namespace mozilla { + +/** + * An enum of memory ordering possibilities for atomics. + * + * Memory ordering is the observable state of distinct values in memory. + * (It's a separate concept from atomicity, which concerns whether an + * operation can ever be observed in an intermediate state. Don't + * conflate the two!) Given a sequence of operations in source code on + * memory, it is *not* always the case that, at all times and on all + * cores, those operations will appear to have occurred in that exact + * sequence. First, the compiler might reorder that sequence, if it + * thinks another ordering will be more efficient. Second, the CPU may + * not expose so consistent a view of memory. CPUs will often perform + * their own instruction reordering, above and beyond that performed by + * the compiler. And each core has its own memory caches, and accesses + * (reads and writes both) to "memory" may only resolve to out-of-date + * cache entries -- not to the "most recently" performed operation in + * some global sense. Any access to a value that may be used by + * multiple threads, potentially across multiple cores, must therefore + * have a memory ordering imposed on it, for all code on all + * threads/cores to have a sufficiently coherent worldview. + * + * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and + * http://en.cppreference.com/w/cpp/atomic/memory_order go into more + * detail on all this, including examples of how each mode works. + * + * Note that for simplicity and practicality, not all of the modes in + * C++11 are supported. The missing C++11 modes are either subsumed by + * the modes we provide below, or not relevant for the CPUs we support + * in Gecko. These three modes are confusing enough as it is! + */ +enum MemoryOrdering { + /* + * Relaxed ordering is the simplest memory ordering: none at all. + * When the result of a write is observed, nothing may be inferred + * about other memory. Writes ostensibly performed "before" on the + * writing thread may not yet be visible. Writes performed "after" on + * the writing thread may already be visible, if the compiler or CPU + * reordered them. (The latter can happen if reads and/or writes get + * held up in per-processor caches.) Relaxed ordering means + * operations can always use cached values (as long as the actual + * updates to atomic values actually occur, correctly, eventually), so + * it's usually the fastest sort of atomic access. For this reason, + * *it's also the most dangerous kind of access*. + * + * Relaxed ordering is good for things like process-wide statistics + * counters that don't need to be consistent with anything else, so + * long as updates themselves are atomic. (And so long as any + * observations of that value can tolerate being out-of-date -- if you + * need some sort of up-to-date value, you need some sort of other + * synchronizing operation.) It's *not* good for locks, mutexes, + * reference counts, etc. that mediate access to other memory, or must + * be observably consistent with other memory. + * + * x86 architectures don't take advantage of the optimization + * opportunities that relaxed ordering permits. Thus it's possible + * that using relaxed ordering will "work" on x86 but fail elsewhere + * (ARM, say, which *does* implement non-sequentially-consistent + * relaxed ordering semantics). Be extra-careful using relaxed + * ordering if you can't easily test non-x86 architectures! + */ + Relaxed, + /* + * When an atomic value is updated with ReleaseAcquire ordering, and + * that new value is observed with ReleaseAcquire ordering, prior + * writes (atomic or not) are also observable. What ReleaseAcquire + * *doesn't* give you is any observable ordering guarantees for + * ReleaseAcquire-ordered operations on different objects. For + * example, if there are two cores that each perform ReleaseAcquire + * operations on separate objects, each core may or may not observe + * the operations made by the other core. The only way the cores can + * be synchronized with ReleaseAcquire is if they both + * ReleaseAcquire-access the same object. This implies that you can't + * necessarily describe some global total ordering of ReleaseAcquire + * operations. + * + * ReleaseAcquire ordering is good for (as the name implies) atomic + * operations on values controlling ownership of things: reference + * counts, mutexes, and the like. However, if you are thinking about + * using these to implement your own locks or mutexes, you should take + * a good, hard look at actual lock or mutex primitives first. + */ + ReleaseAcquire, + /* + * When an atomic value is updated with SequentiallyConsistent + * ordering, all writes observable when the update is observed, just + * as with ReleaseAcquire ordering. But, furthermore, a global total + * ordering of SequentiallyConsistent operations *can* be described. + * For example, if two cores perform SequentiallyConsistent operations + * on separate objects, one core will observably perform its update + * (and all previous operations will have completed), then the other + * core will observably perform its update (and all previous + * operations will have completed). (Although those previous + * operations aren't themselves ordered -- they could be intermixed, + * or ordered if they occur on atomic values with ordering + * requirements.) SequentiallyConsistent is the *simplest and safest* + * ordering of atomic operations -- it's always as if one operation + * happens, then another, then another, in some order -- and every + * core observes updates to happen in that single order. Because it + * has the most synchronization requirements, operations ordered this + * way also tend to be slowest. + * + * SequentiallyConsistent ordering can be desirable when multiple + * threads observe objects, and they all have to agree on the + * observable order of changes to them. People expect + * SequentiallyConsistent ordering, even if they shouldn't, when + * writing code, atomic or otherwise. SequentiallyConsistent is also + * the ordering of choice when designing lockless data structures. If + * you don't know what order to use, use this one. + */ + SequentiallyConsistent, +}; + +} // namespace mozilla + +// Build up the underlying intrinsics. +#ifdef MOZ_HAVE_CXX11_ATOMICS + +# include + +namespace mozilla { +namespace detail { + +/* + * We provide CompareExchangeFailureOrder to work around a bug in some + * versions of GCC's header. See bug 898491. + */ +template struct AtomicOrderConstraints; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; + static const std::memory_order LoadOrder = std::memory_order_relaxed; + static const std::memory_order StoreOrder = std::memory_order_relaxed; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_relaxed; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; + static const std::memory_order LoadOrder = std::memory_order_acquire; + static const std::memory_order StoreOrder = std::memory_order_release; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_acquire; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; + static const std::memory_order LoadOrder = std::memory_order_seq_cst; + static const std::memory_order StoreOrder = std::memory_order_seq_cst; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_seq_cst; +}; + +template +struct IntrinsicBase +{ + typedef std::atomic ValueType; + typedef AtomicOrderConstraints OrderedOp; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T load(const typename Base::ValueType& ptr) { + return ptr.load(Base::OrderedOp::LoadOrder); + } + static void store(typename Base::ValueType& ptr, T val) { + ptr.store(val, Base::OrderedOp::StoreOrder); + } + static T exchange(typename Base::ValueType& ptr, T val) { + return ptr.exchange(val, Base::OrderedOp::AtomicRMWOrder); + } + static bool compareExchange(typename Base::ValueType& ptr, T oldVal, T newVal) { + return ptr.compare_exchange_strong(oldVal, newVal, + Base::OrderedOp::AtomicRMWOrder, + Base::OrderedOp::CompareExchangeFailureOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T add(typename Base::ValueType& ptr, T val) { + return ptr.fetch_add(val, Base::OrderedOp::AtomicRMWOrder); + } + static T sub(typename Base::ValueType& ptr, T val) { + return ptr.fetch_sub(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T* add(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_add(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + static T* sub(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_sub(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + private: + /* + * GCC 4.6's header has a bug where adding X to an + * atomic is not the same as adding X to a T*. Hence the need + * for this function to provide the correct addend. + */ + static ptrdiff_t fixupAddend(ptrdiff_t val) { +#if defined(__clang__) || defined(_MSC_VER) + return val; +#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \ + !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) + return val * sizeof(T); +#else + return val; +#endif + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + typedef IntrinsicBase Base; + static T inc(typename Base::ValueType& ptr) { + return IntrinsicAddSub::add(ptr, 1); + } + static T dec(typename Base::ValueType& ptr) { + return IntrinsicAddSub::sub(ptr, 1); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + typedef IntrinsicBase Base; + static T or_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_or(val, Base::OrderedOp::AtomicRMWOrder); + } + static T xor_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_xor(val, Base::OrderedOp::AtomicRMWOrder); + } + static T and_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_and(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct AtomicIntrinsics + : public IntrinsicMemoryOps, public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(__GNUC__) + +namespace mozilla { +namespace detail { + +/* + * The __sync_* family of intrinsics is documented here: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html + * + * While these intrinsics are deprecated in favor of the newer __atomic_* + * family of intrincs: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html + * + * any GCC version that supports the __atomic_* intrinsics will also support + * the header and so will be handled above. We provide a version of + * atomics using the __sync_* intrinsics to support older versions of GCC. + * + * All __sync_* intrinsics that we use below act as full memory barriers, for + * both compiler and hardware reordering, except for __sync_lock_test_and_set, + * which is a only an acquire barrier. When we call __sync_lock_test_and_set, + * we add a barrier above it as appropriate. + */ + +template struct Barrier; + +/* + * Some processors (in particular, x86) don't require quite so many calls to + * __sync_sychronize as our specializations of Barrier produce. If + * performance turns out to be an issue, defining these specializations + * on a per-processor basis would be a good first tuning step. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() { __sync_synchronize(); } + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() { __sync_synchronize(); } +}; + +template +struct IntrinsicMemoryOps +{ + static T load(const T& ptr) { + Barrier::beforeLoad(); + T val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(T& ptr, T val) { + Barrier::beforeStore(); + ptr = val; + Barrier::afterStore(); + } + static T exchange(T& ptr, T val) { + // __sync_lock_test_and_set is only an acquire barrier; loads and stores + // can't be moved up from after to before it, but they can be moved down + // from before to after it. We may want a stricter ordering, so we need + // an explicit barrier. + + Barrier::beforeStore(); + return __sync_lock_test_and_set(&ptr, val); + } + static bool compareExchange(T& ptr, T oldVal, T newVal) { + return __sync_bool_compare_and_swap(&ptr, oldVal, newVal); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T ValueType; + static T add(T& ptr, T val) { + return __sync_fetch_and_add(&ptr, val); + } + static T sub(T& ptr, T val) { + return __sync_fetch_and_sub(&ptr, val); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T* ValueType; + /* + * The reinterpret_casts are needed so that + * __sync_fetch_and_{add,sub} will properly type-check. + * + * Also, these functions do not provide standard semantics for + * pointer types, so we need to adjust the addend. + */ + static ValueType add(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_add(&ptr, amount); + } + static ValueType sub(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_sub(&ptr, amount); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static T inc(T& ptr) { return IntrinsicAddSub::add(ptr, 1); } + static T dec(T& ptr) { return IntrinsicAddSub::sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static T or_(T& ptr, T val) { + return __sync_fetch_and_or(&ptr, val); + } + static T xor_(T& ptr, T val) { + return __sync_fetch_and_xor(&ptr, val); + } + static T and_(T& ptr, T val) { + return __sync_fetch_and_and(&ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(_MSC_VER) + +/* + * Windows comes with a full complement of atomic operations. + * Unfortunately, most of those aren't available for Windows XP (even if + * the compiler supports intrinsics for them), which is the oldest + * version of Windows we support. Therefore, we only provide operations + * on 32-bit datatypes for 32-bit Windows versions; for 64-bit Windows + * versions, we support 64-bit datatypes as well. + * + * To avoid namespace pollution issues, we declare whatever functions we + * need ourselves. + */ + +extern "C" { +long __cdecl _InterlockedExchangeAdd(long volatile* dst, long value); +long __cdecl _InterlockedOr(long volatile* dst, long value); +long __cdecl _InterlockedXor(long volatile* dst, long value); +long __cdecl _InterlockedAnd(long volatile* dst, long value); +long __cdecl _InterlockedExchange(long volatile *dst, long value); +long __cdecl _InterlockedCompareExchange(long volatile *dst, long newVal, long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd) +# pragma intrinsic(_InterlockedOr) +# pragma intrinsic(_InterlockedXor) +# pragma intrinsic(_InterlockedAnd) +# pragma intrinsic(_InterlockedExchange) +# pragma intrinsic(_InterlockedCompareExchange) + +namespace mozilla { +namespace detail { + +# if !defined(_M_IX86) && !defined(_M_X64) + /* + * The implementations below are optimized for x86ish systems. You + * will have to modify them if you are porting to Windows on a + * different architecture. + */ +# error "Unknown CPU type" +# endif + +/* + * The PrimitiveIntrinsics template should define |Type|, the datatype of size + * DataSize upon which we operate, and the following eight functions. + * + * static Type add(Type* ptr, Type val); + * static Type sub(Type* ptr, Type val); + * static Type or_(Type* ptr, Type val); + * static Type xor_(Type* ptr, Type val); + * static Type and_(Type* ptr, Type val); + * + * These functions perform the obvious operation on the value contained in + * |*ptr| combined with |val| and return the value previously stored in + * |*ptr|. + * + * static void store(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and must provide a full + * memory fence after the store to prevent compiler and hardware instruction + * reordering. It should also act as a compiler barrier to prevent reads and + * writes from moving to after the store. + * + * static Type exchange(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and returns the previous + * contents of *ptr; + * + * static bool compareExchange(Type* ptr, Type oldVal, Type newVal); + * + * This function atomically performs the following operation: + * + * if (*ptr == oldVal) { + * *ptr = newVal; + * return true; + * } else { + * return false; + * } + * + */ +template struct PrimitiveIntrinsics; + +template<> +struct PrimitiveIntrinsics<4> +{ + typedef long Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * _InterlockedExchangeSubtract isn't available before Windows 7, + * and we must support Windows XP. + */ + return _InterlockedExchangeAdd(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange(ptr, newVal, oldVal) == oldVal; + } +}; + +# if defined(_M_X64) + +extern "C" { +long long __cdecl _InterlockedExchangeAdd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedOr64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedXor64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedAnd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedExchange64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedCompareExchange64(long long volatile* dst, + long long newVal, + long long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd64) +# pragma intrinsic(_InterlockedOr64) +# pragma intrinsic(_InterlockedXor64) +# pragma intrinsic(_InterlockedAnd64) +# pragma intrinsic(_InterlockedExchange64) +# pragma intrinsic(_InterlockedCompareExchange64) + +template <> +struct PrimitiveIntrinsics<8> +{ + typedef __int64 Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd64(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * There is no _InterlockedExchangeSubtract64. + */ + return _InterlockedExchangeAdd64(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr64(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor64(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd64(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange64(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange64(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange64(ptr, newVal, oldVal) == oldVal; + } +}; + +# endif + +extern "C" { void _ReadWriteBarrier(); } + +# pragma intrinsic(_ReadWriteBarrier) + +template struct Barrier; + +/* + * We do not provide an afterStore method in Barrier, as Relaxed and + * ReleaseAcquire orderings do not require one, and the required barrier + * for SequentiallyConsistent is handled by PrimitiveIntrinsics. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template<> +struct Barrier +{ + static void beforeLoad() { _ReadWriteBarrier(); } + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T val) { return static_cast(val); } + static T fromPrimType(PrimType val) { return static_cast(val); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T* val) { return reinterpret_cast(val); } + static T* fromPrimType(PrimType val) { return reinterpret_cast(val); } +}; + +template +struct IntrinsicBase +{ + typedef T ValueType; + typedef PrimitiveIntrinsics Primitives; + typedef typename Primitives::Type PrimType; + static_assert(sizeof(PrimType) == sizeof(T), + "Selection of PrimitiveIntrinsics was wrong"); + typedef CastHelper Cast; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + static ValueType load(const ValueType& ptr) { + Barrier::beforeLoad(); + ValueType val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(ValueType& ptr, ValueType val) { + // For SequentiallyConsistent, Primitives::store() will generate the + // proper memory fence. Everything else just needs a barrier before + // the store. + if (Order == SequentiallyConsistent) { + Primitives::store(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + } else { + Barrier::beforeStore(); + ptr = val; + } + } + static ValueType exchange(ValueType& ptr, ValueType val) { + PrimType oldval = + Primitives::exchange(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + return Cast::fromPrimType(oldval); + } + static bool compareExchange(ValueType& ptr, ValueType oldVal, ValueType newVal) { + return Primitives::compareExchange(reinterpret_cast(&ptr), + Cast::toPrimType(oldVal), + Cast::toPrimType(newVal)); + } +}; + +template +struct IntrinsicApplyHelper : public IntrinsicBase +{ + typedef PrimType (*BinaryOp)(PrimType*, PrimType); + typedef PrimType (*UnaryOp)(PrimType*); + + static ValueType applyBinaryFunction(BinaryOp op, ValueType& ptr, + ValueType val) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + PrimType primTypeVal = Cast::toPrimType(val); + return Cast::fromPrimType(op(primTypePtr, primTypeVal)); + } + + static ValueType applyUnaryFunction(UnaryOp op, ValueType& ptr) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + return Cast::fromPrimType(op(primTypePtr)); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::add, ptr, val); + } + static ValueType sub(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::sub, ptr, val); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::add, ptr, + (ValueType)(amount * sizeof(ValueType))); + } + static ValueType sub(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::sub, ptr, + (ValueType)(amount * sizeof(ValueType))); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static ValueType inc(ValueType& ptr) { return add(ptr, 1); } + static ValueType dec(ValueType& ptr) { return sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static ValueType or_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::or_, ptr, val); + } + static ValueType xor_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::xor_, ptr, val); + } + static ValueType and_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::and_, ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#else +# error "Atomic compiler intrinsics are not supported on your platform" +#endif + +namespace mozilla { + +namespace detail { + +template +class AtomicBase +{ + // We only support 32-bit types on 32-bit Windows, which constrains our + // implementation elsewhere. But we support pointer-sized types everywhere. + static_assert(sizeof(T) == 4 || (sizeof(uintptr_t) == 8 && sizeof(T) == 8), + "mozilla/Atomics.h only supports 32-bit and pointer-sized types"); + + protected: + typedef typename detail::AtomicIntrinsics Intrinsics; + typename Intrinsics::ValueType mValue; + + public: + AtomicBase() : mValue() {} + AtomicBase(T aInit) { Intrinsics::store(mValue, aInit); } + + operator T() const { return Intrinsics::load(mValue); } + + T operator=(T aValue) { + Intrinsics::store(mValue, aValue); + return aValue; + } + + /** + * Performs an atomic swap operation. aValue is stored and the previous + * value of this variable is returned. + */ + T exchange(T aValue) { + return Intrinsics::exchange(mValue, aValue); + } + + /** + * Performs an atomic compare-and-swap operation and returns true if it + * succeeded. This is equivalent to atomically doing + * + * if (mValue == aOldValue) { + * mValue = aNewValue; + * return true; + * } else { + * return false; + * } + */ + bool compareExchange(T aOldValue, T aNewValue) { + return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); + } + + private: + template + AtomicBase(const AtomicBase& aCopy) MOZ_DELETE; +}; + +template +class AtomicBaseIncDec : public AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + AtomicBaseIncDec() : Base() {} + AtomicBaseIncDec(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } + T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } + T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } + T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } + + private: + template + AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) MOZ_DELETE; +}; + +} // namespace detail + +/** + * A wrapper for a type that enforces that all memory accesses are atomic. + * + * In general, where a variable |T foo| exists, |Atomic foo| can be used in + * its place. Implementations for integral and pointer types are provided + * below. + * + * Atomic accesses are sequentially consistent by default. You should + * use the default unless you are tall enough to ride the + * memory-ordering roller coaster (if you're not sure, you aren't) and + * you have a compelling reason to do otherwise. + * + * There is one exception to the case of atomic memory accesses: providing an + * initial value of the atomic value is not guaranteed to be atomic. This is a + * deliberate design choice that enables static atomic variables to be declared + * without introducing extra static constructors. + */ +template +class Atomic; + +/** + * Atomic implementation for integral types. + * + * In addition to atomic store and load operations, compound assignment and + * increment/decrement operators are implemented which perform the + * corresponding read-modify-write operation atomically. Finally, an atomic + * swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator+=(T delta) { return Base::Intrinsics::add(Base::mValue, delta) + delta; } + T operator-=(T delta) { return Base::Intrinsics::sub(Base::mValue, delta) - delta; } + T operator|=(T val) { return Base::Intrinsics::or_(Base::mValue, val) | val; } + T operator^=(T val) { return Base::Intrinsics::xor_(Base::mValue, val) ^ val; } + T operator&=(T val) { return Base::Intrinsics::and_(Base::mValue, val) & val; } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for pointer types. + * + * An atomic compare-and-swap primitive for pointer variables is provided, as + * are atomic increment and decement operators. Also provided are the compound + * assignment operators for addition and subtraction. Atomic swap (via + * exchange()) is included as well. + */ +template +class Atomic : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T* aInit) : Base(aInit) {} + + using Base::operator=; + + T* operator+=(ptrdiff_t delta) { + return Base::Intrinsics::add(Base::mValue, delta) + delta; + } + T* operator-=(ptrdiff_t delta) { + return Base::Intrinsics::sub(Base::mValue, delta) - delta; + } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for enum types. + * + * The atomic store and load operations and the atomic swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_Atomics_h */ diff --git a/external/spidermonkey/include/android/mozilla/Attributes.h b/external/spidermonkey/include/android/mozilla/Attributes.h index 89f3641fc9..6ea9776fbf 100644 --- a/external/spidermonkey/include/android/mozilla/Attributes.h +++ b/external/spidermonkey/include/android/mozilla/Attributes.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of various class and method modifier attributes. */ -#ifndef mozilla_Attributes_h_ -#define mozilla_Attributes_h_ +#ifndef mozilla_Attributes_h +#define mozilla_Attributes_h #include "mozilla/Compiler.h" @@ -117,11 +118,18 @@ * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a * function at compile time. A constexpr function cannot examine any values * except its arguments and can have no side effects except its return value. + * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's + * value may be computed at compile time. It should be prefered to just + * marking variables as MOZ_CONSTEXPR because if the compiler does not support + * constexpr it will fall back to making the variable const, and some compilers + * do not accept variables being marked both const and constexpr. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR # define MOZ_CONSTEXPR constexpr +# define MOZ_CONSTEXPR_VAR constexpr #else # define MOZ_CONSTEXPR /* no support */ +# define MOZ_CONSTEXPR_VAR const #endif /* @@ -382,18 +390,42 @@ * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is * expected to live on the stack, so it is a compile-time error to use it, or * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). It may be a base or - * a member of another class only if both classes are marked with this - * annotation. + * a new expression (unless placement new is being used). If a member of + * another class uses this class, or if another class inherits from this + * class, then it is considered to be a stack class as well, although this + * attribute need not be provided in such cases. + * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is + * expected to live on the stack or in static storage, so it is a compile-time + * error to use it, or an array of such objects, as the type of a new + * expression (unless placement new is being used). If a member of another + * class uses this class, or if another class inherits from this class, then + * it is considered to be a non-heap class as well, although this attribute + * need not be provided in such cases. */ #ifdef MOZ_CLANG_PLUGIN # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) +# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) #else # define MOZ_MUST_OVERRIDE /* nothing */ # define MOZ_STACK_CLASS /* nothing */ +# define MOZ_NONHEAP_CLASS /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ +/* + * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that + * it's safe to use 'this' in an initializer list. + */ +#ifdef _MSC_VER +# define MOZ_THIS_IN_INITIALIZER_LIST() \ + __pragma(warning(push)) \ + __pragma(warning(disable:4355)) \ + this \ + __pragma(warning(pop)) +#else +# define MOZ_THIS_IN_INITIALIZER_LIST() this +#endif + #endif /* __cplusplus */ -#endif /* mozilla_Attributes_h_ */ +#endif /* mozilla_Attributes_h */ diff --git a/external/spidermonkey/include/android/mozilla/BloomFilter.h b/external/spidermonkey/include/android/mozilla/BloomFilter.h index 8680ef2907..afe4b72b80 100644 --- a/external/spidermonkey/include/android/mozilla/BloomFilter.h +++ b/external/spidermonkey/include/android/mozilla/BloomFilter.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * A counting Bloom filter implementation. This allows consumers to @@ -10,14 +11,14 @@ * incorrectly answer "yes" when the correct answer is "no"). */ -#ifndef mozilla_BloomFilter_h_ -#define mozilla_BloomFilter_h_ +#ifndef mozilla_BloomFilter_h +#define mozilla_BloomFilter_h #include "mozilla/Assertions.h" #include "mozilla/Likely.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Util.h" +#include #include namespace mozilla { @@ -105,7 +106,7 @@ class BloomFilter */ public: BloomFilter() { - MOZ_STATIC_ASSERT(KeySize <= keyShift, "KeySize too big"); + static_assert(KeySize <= keyShift, "KeySize too big"); // Should we have a custom operator new using calloc instead and // require that we're allocated via the operator? @@ -231,4 +232,4 @@ BloomFilter::mightContain(const T* t) const } // namespace mozilla -#endif /* mozilla_BloomFilter_h_ */ +#endif /* mozilla_BloomFilter_h */ diff --git a/external/spidermonkey/include/android/mozilla/Casting.h b/external/spidermonkey/include/android/mozilla/Casting.h index b1e81c33fa..76df0ef27e 100644 --- a/external/spidermonkey/include/android/mozilla/Casting.h +++ b/external/spidermonkey/include/android/mozilla/Casting.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cast operations to supplement the built-in casting operations. */ -#ifndef mozilla_Casting_h_ -#define mozilla_Casting_h_ +#ifndef mozilla_Casting_h +#define mozilla_Casting_h #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" @@ -15,6 +16,27 @@ namespace mozilla { +/** + * Return a value of type |To|, containing the underlying bit pattern of |from|. + * + * |To| and |From| must be types of the same size; be careful of cross-platform + * size differences, or this might fail to compile on some but not all + * platforms. + */ +template +inline To +BitwiseCast(const From from) +{ + static_assert(sizeof(From) == sizeof(To), + "To and From must have the same size"); + union { + From from; + To to; + } u; + u.from = from; + return u.to; +} + namespace detail { enum ToSignedness { ToIsSigned, ToIsUnsigned }; @@ -43,7 +65,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return from <= From(To(-1)); } }; @@ -52,7 +74,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -61,8 +83,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedUnsignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedUnsignedCheck::checkBounds(from); } }; @@ -72,7 +94,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (from < 0) return false; if (sizeof(To) >= sizeof(From)) @@ -93,7 +115,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -102,7 +124,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); return from <= From(MaxValue); } @@ -112,8 +134,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedSignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedSignedCheck::checkBounds(from); } }; @@ -123,7 +145,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (sizeof(From) <= sizeof(To)) return true; const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); @@ -141,15 +163,15 @@ template class BoundsChecker { public: - static bool check(const From from) { return true; } + static bool checkBounds(const From from) { return true; } }; template class BoundsChecker { public: - static bool check(const From from) { - return BoundsCheckImpl::check(from); + static bool checkBounds(const From from) { + return BoundsCheckImpl::checkBounds(from); } }; @@ -157,7 +179,7 @@ template inline bool IsInBounds(const From from) { - return BoundsChecker::check(from); + return BoundsChecker::checkBounds(from); } } // namespace detail @@ -177,4 +199,4 @@ SafeCast(const From from) } // namespace mozilla -#endif /* mozilla_Casting_h_ */ +#endif /* mozilla_Casting_h */ diff --git a/external/spidermonkey/include/android/mozilla/Char16.h b/external/spidermonkey/include/android/mozilla/Char16.h index c6f9f87d44..e4b184f950 100644 --- a/external/spidermonkey/include/android/mozilla/Char16.h +++ b/external/spidermonkey/include/android/mozilla/Char16.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implements a UTF-16 character type. */ -#ifndef mozilla_Char16_h_ -#define mozilla_Char16_h_ +#ifndef mozilla_Char16_h +#define mozilla_Char16_h #include "mozilla/Assertions.h" @@ -49,8 +50,8 @@ */ #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s) -MOZ_STATIC_ASSERT(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); +static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); +static_assert(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); +static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); -#endif /* mozilla_Char16_h_ */ +#endif /* mozilla_Char16_h */ diff --git a/external/spidermonkey/include/android/mozilla/CheckedInt.h b/external/spidermonkey/include/android/mozilla/CheckedInt.h index 1dc80b032b..050cef8ed8 100644 --- a/external/spidermonkey/include/android/mozilla/CheckedInt.h +++ b/external/spidermonkey/include/android/mozilla/CheckedInt.h @@ -1,23 +1,23 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Provides checked integers, detecting integer overflow and divide-by-0. */ -#ifndef mozilla_CheckedInt_h_ -#define mozilla_CheckedInt_h_ +#ifndef mozilla_CheckedInt_h +#define mozilla_CheckedInt_h // Enable relying of Mozilla's MFBT for possibly-available C++11 features #define MOZ_CHECKEDINT_USE_MFBT +#include + #ifdef MOZ_CHECKEDINT_USE_MFBT # include "mozilla/Assertions.h" -# include "mozilla/StandardInteger.h" #else # include -# include -# define MOZ_STATIC_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_DELETE #endif @@ -450,6 +450,44 @@ IsDivValid(T x, T y) !(IsSigned::value && x == MinValue::value && y == T(-1)); } +template::value> +struct IsModValidImpl; + +template +inline bool +IsModValid(T x, T y) +{ + return IsModValidImpl::run(x, y); +} + +/* + * Mod is pretty simple. + * For now, let's just use the ANSI C definition: + * If x or y are negative, the results are implementation defined. + * Consider these invalid. + * Undefined for y=0. + * The result will never exceed either x or y. + * + * Checking that x>=0 is a warning when T is unsigned. + */ + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + return y >= 1; + } +}; + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + if (x < 0) + return false; + + return y >= 1; + } +}; + template::value> struct NegateImpl; @@ -528,7 +566,7 @@ struct NegateImpl CheckedInt x(-1); // 1000 is of type int16_t, is found not to be in range for int8_t, // x is invalid - CheckedInt x(int16_t(1000)); + CheckedInt x(int16_t(1000)); // 3123456789 is of type uint32_t, is found not to be in range for int32_t, // x is invalid CheckedInt x(uint32_t(3123456789)); @@ -561,12 +599,12 @@ class CheckedInt template CheckedInt(U value, bool isValid) : mValue(value), mIsValid(isValid) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); } - friend class detail::NegateImpl; + friend struct detail::NegateImpl; public: /** @@ -585,16 +623,27 @@ class CheckedInt : mValue(T(value)), mIsValid(detail::IsInRange(value)) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } + + template + friend class CheckedInt; + + template + CheckedInt toChecked() const + { + CheckedInt ret(mValue); + ret.mIsValid = ret.mIsValid && mIsValid; + return ret; } /** Constructs a valid checked integer with initial value 0 */ CheckedInt() : mValue(0), mIsValid(true) { - MOZ_STATIC_ASSERT(detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value, + "This type is not supported by CheckedInt"); } /** @returns the actual value */ @@ -619,22 +668,31 @@ class CheckedInt const CheckedInt& rhs); template CheckedInt& operator +=(U rhs); + template friend CheckedInt operator -(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator -=(U rhs); + template friend CheckedInt operator *(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator *=(U rhs); + template friend CheckedInt operator /(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator /=(U rhs); + template + friend CheckedInt operator %(const CheckedInt& lhs, + const CheckedInt& rhs); + template + CheckedInt& operator %=(U rhs); + CheckedInt operator -() const { return detail::NegateImpl::negate(*this); @@ -726,6 +784,7 @@ MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) +MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) #undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR @@ -757,9 +816,9 @@ template inline typename detail::CastToCheckedIntImpl::ReturnType castToCheckedInt(U u) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); return detail::CastToCheckedIntImpl::run(u); } @@ -786,6 +845,7 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) +MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) #undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS @@ -815,4 +875,4 @@ typedef CheckedInt CheckedUint64; } // namespace mozilla -#endif /* mozilla_CheckedInt_h_ */ +#endif /* mozilla_CheckedInt_h */ diff --git a/external/spidermonkey/include/android/mozilla/Compiler.h b/external/spidermonkey/include/android/mozilla/Compiler.h index 58239b0e30..d1ef1e79aa 100644 --- a/external/spidermonkey/include/android/mozilla/Compiler.h +++ b/external/spidermonkey/include/android/mozilla/Compiler.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various compiler checks. */ -#ifndef mozilla_Compiler_h_ -#define mozilla_Compiler_h_ +#ifndef mozilla_Compiler_h +#define mozilla_Compiler_h #if !defined(__clang__) && defined(__GNUC__) @@ -28,4 +29,4 @@ #endif -#endif /* mozilla_Compiler_h_ */ +#endif /* mozilla_Compiler_h */ diff --git a/external/spidermonkey/include/android/mozilla/Constants.h b/external/spidermonkey/include/android/mozilla/Constants.h index 904b30145a..86bbb6b354 100644 --- a/external/spidermonkey/include/android/mozilla/Constants.h +++ b/external/spidermonkey/include/android/mozilla/Constants.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt math constants. */ -#ifndef mozilla_Constants_h_ -#define mozilla_Constants_h_ +#ifndef mozilla_Constants_h +#define mozilla_Constants_h #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -#endif /* mozilla_Constants_h_ */ +#endif /* mozilla_Constants_h */ diff --git a/external/spidermonkey/include/android/mozilla/DebugOnly.h b/external/spidermonkey/include/android/mozilla/DebugOnly.h index 1f78ed7989..e5f0d729b5 100644 --- a/external/spidermonkey/include/android/mozilla/DebugOnly.h +++ b/external/spidermonkey/include/android/mozilla/DebugOnly.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * assertions). */ -#ifndef mozilla_DebugOnly_h_ -#define mozilla_DebugOnly_h_ +#ifndef mozilla_DebugOnly_h +#define mozilla_DebugOnly_h namespace mozilla { @@ -74,4 +75,4 @@ class DebugOnly } -#endif /* mozilla_DebugOnly_h_ */ +#endif /* mozilla_DebugOnly_h */ diff --git a/external/spidermonkey/include/android/mozilla/Decimal.h b/external/spidermonkey/include/android/mozilla/Decimal.h index 8032fd6e23..3c67d784c9 100644 --- a/external/spidermonkey/include/android/mozilla/Decimal.h +++ b/external/spidermonkey/include/android/mozilla/Decimal.h @@ -38,7 +38,7 @@ #define Decimal_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" +#include #include "mozilla/Types.h" #include diff --git a/external/spidermonkey/include/android/mozilla/Endian.h b/external/spidermonkey/include/android/mozilla/Endian.h index 5d2f905b41..dc6d11d3ba 100644 --- a/external/spidermonkey/include/android/mozilla/Endian.h +++ b/external/spidermonkey/include/android/mozilla/Endian.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -59,16 +60,16 @@ * }; */ -#ifndef mozilla_Endian_h_ -#define mozilla_Endian_h_ +#ifndef mozilla_Endian_h +#define mozilla_Endian_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/DebugOnly.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" +#include #include #if defined(_MSC_VER) && _MSC_VER >= 1300 @@ -636,4 +637,4 @@ class NativeEndian MOZ_FINAL : public detail::Endian } /* namespace mozilla */ -#endif /* mozilla_Endian_h_ */ +#endif /* mozilla_Endian_h */ diff --git a/external/spidermonkey/include/android/mozilla/EnumSet.h b/external/spidermonkey/include/android/mozilla/EnumSet.h index b18b005669..95c5608cf4 100644 --- a/external/spidermonkey/include/android/mozilla/EnumSet.h +++ b/external/spidermonkey/include/android/mozilla/EnumSet.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,7 +10,8 @@ #define mozilla_EnumSet_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" + +#include namespace mozilla { @@ -172,4 +174,4 @@ class EnumSet } // namespace mozilla -#endif // mozilla_EnumSet_h_ +#endif /* mozilla_EnumSet_h_*/ diff --git a/external/spidermonkey/include/android/mozilla/FloatingPoint.h b/external/spidermonkey/include/android/mozilla/FloatingPoint.h index 30af2217b1..d80f6a7234 100644 --- a/external/spidermonkey/include/android/mozilla/FloatingPoint.h +++ b/external/spidermonkey/include/android/mozilla/FloatingPoint.h @@ -1,16 +1,19 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various predicates and operations on IEEE-754 floating point types. */ -#ifndef mozilla_FloatingPoint_h_ -#define mozilla_FloatingPoint_h_ +#ifndef mozilla_FloatingPoint_h +#define mozilla_FloatingPoint_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" +#include "mozilla/Casting.h" + +#include namespace mozilla { @@ -35,80 +38,58 @@ namespace mozilla { * the case. But we required this in implementations of these algorithms that * preceded this header, so we shouldn't break anything if we continue doing so. */ -MOZ_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); +static_assert(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); const unsigned DoubleExponentBias = 1023; const unsigned DoubleExponentShift = 52; -namespace detail { - const uint64_t DoubleSignBit = 0x8000000000000000ULL; const uint64_t DoubleExponentBits = 0x7ff0000000000000ULL; const uint64_t DoubleSignificandBits = 0x000fffffffffffffULL; -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleExponentBits) == 0, - "sign bit doesn't overlap exponent bits"); -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleSignificandBits) == 0, - "sign bit doesn't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleExponentBits & DoubleSignificandBits) == 0, - "exponent bits don't overlap significand bits"); +static_assert((DoubleSignBit & DoubleExponentBits) == 0, + "sign bit doesn't overlap exponent bits"); +static_assert((DoubleSignBit & DoubleSignificandBits) == 0, + "sign bit doesn't overlap significand bits"); +static_assert((DoubleExponentBits & DoubleSignificandBits) == 0, + "exponent bits don't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == - ~uint64_t(0), - "all bits accounted for"); - -union DoublePun -{ - /* - * Every way to pun the bits of a double introduces an additional layer of - * complexity, across a multitude of platforms, architectures, and ABIs. - * Use *only* uint64_t to reduce complexity. Don't add new punning here - * without discussion! - */ - uint64_t u; - double d; -}; - -} /* namespace detail */ +static_assert((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == + ~uint64_t(0), + "all bits accounted for"); /** Determines whether a double is NaN. */ static MOZ_ALWAYS_INLINE bool IsNaN(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * A double is NaN if all exponent bits are 1 and the significand contains at * least one non-zero bit. */ - return (pun.u & detail::DoubleExponentBits) == detail::DoubleExponentBits && - (pun.u & detail::DoubleSignificandBits) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) == DoubleExponentBits && + (bits & DoubleSignificandBits) != 0; } /** Determines whether a double is +Infinity or -Infinity. */ static MOZ_ALWAYS_INLINE bool IsInfinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - return (pun.u & ~detail::DoubleSignBit) == detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & ~DoubleSignBit) == DoubleExponentBits; } /** Determines whether a double is not NaN or infinite. */ static MOZ_ALWAYS_INLINE bool IsFinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * NaN and Infinities are the only non-finite doubles, and both have all * exponent bits set to 1. */ - return (pun.u & detail::DoubleExponentBits) != detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) != DoubleExponentBits; } /** @@ -120,36 +101,30 @@ IsNegative(double d) { MOZ_ASSERT(!IsNaN(d), "NaN does not have a sign"); - union detail::DoublePun pun; - pun.d = d; - /* The sign bit is set if the double is negative. */ - return (pun.u & detail::DoubleSignBit) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleSignBit) != 0; } /** Determines whether a double represents -0. */ static MOZ_ALWAYS_INLINE bool IsNegativeZero(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Only the sign bit is set if the double is -0. */ - return pun.u == detail::DoubleSignBit; + uint64_t bits = BitwiseCast(d); + return bits == DoubleSignBit; } /** Returns the exponent portion of the double. */ static MOZ_ALWAYS_INLINE int_fast16_t ExponentComponent(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * The exponent component of a double is an unsigned number, biased from its * actual value. Subtract the bias to retrieve the actual exponent. */ - return int_fast16_t((pun.u & detail::DoubleExponentBits) >> DoubleExponentShift) - + uint64_t bits = BitwiseCast(d); + return int_fast16_t((bits & DoubleExponentBits) >> DoubleExponentShift) - int_fast16_t(DoubleExponentBias); } @@ -157,28 +132,22 @@ ExponentComponent(double d) static MOZ_ALWAYS_INLINE double PositiveInfinity() { - union detail::DoublePun pun; - /* * Positive infinity has all exponent bits set, sign bit set to 0, and no * significand. */ - pun.u = detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleExponentBits); } /** Returns -Infinity. */ static MOZ_ALWAYS_INLINE double NegativeInfinity() { - union detail::DoublePun pun; - /* * Negative infinity has all exponent bits set, sign bit set to 1, and no * significand. */ - pun.u = detail::DoubleSignBit | detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleSignBit | DoubleExponentBits); } /** Constructs a NaN value with the specified sign bit and significand bits. */ @@ -186,24 +155,21 @@ static MOZ_ALWAYS_INLINE double SpecificNaN(int signbit, uint64_t significand) { MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~detail::DoubleSignificandBits) == 0); - MOZ_ASSERT(significand & detail::DoubleSignificandBits); + MOZ_ASSERT((significand & ~DoubleSignificandBits) == 0); + MOZ_ASSERT(significand & DoubleSignificandBits); - union detail::DoublePun pun; - pun.u = (signbit ? detail::DoubleSignBit : 0) | - detail::DoubleExponentBits | - significand; - MOZ_ASSERT(IsNaN(pun.d)); - return pun.d; + double d = BitwiseCast((signbit ? DoubleSignBit : 0) | + DoubleExponentBits | + significand); + MOZ_ASSERT(IsNaN(d)); + return d; } /** Computes the smallest non-zero positive double value. */ static MOZ_ALWAYS_INLINE double MinDoubleValue() { - union detail::DoublePun pun; - pun.u = 1; - return pun.d; + return BitwiseCast(uint64_t(1)); } static MOZ_ALWAYS_INLINE bool @@ -224,9 +190,22 @@ DoubleIsInt32(double d, int32_t* i) static MOZ_ALWAYS_INLINE double UnspecifiedNaN() { - return mozilla::SpecificNaN(0, 0xfffffffffffffULL); + return SpecificNaN(0, 0xfffffffffffffULL); +} + +/** + * Compare two doubles for equality, *without* equating -0 to +0, and equating + * any NaN value to any other NaN value. (The normal equality operators equate + * -0 with +0, and they equate NaN to no other value.) + */ +static inline bool +DoublesAreIdentical(double d1, double d2) +{ + if (IsNaN(d1)) + return IsNaN(d2); + return BitwiseCast(d1) == BitwiseCast(d2); } } /* namespace mozilla */ -#endif /* mozilla_FloatingPoint_h_ */ +#endif /* mozilla_FloatingPoint_h */ diff --git a/external/spidermonkey/include/android/mozilla/GuardObjects.h b/external/spidermonkey/include/android/mozilla/GuardObjects.h index 6c2058938c..aeae7dcbc0 100644 --- a/external/spidermonkey/include/android/mozilla/GuardObjects.h +++ b/external/spidermonkey/include/android/mozilla/GuardObjects.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,6 +10,7 @@ #define mozilla_GuardObjects_h #include "mozilla/Assertions.h" +#include "mozilla/NullPtr.h" #include "mozilla/Types.h" #ifdef __cplusplus @@ -72,7 +74,7 @@ class MOZ_EXPORT GuardObjectNotifier bool* statementDone; public: - GuardObjectNotifier() : statementDone(NULL) { } + GuardObjectNotifier() : statementDone(nullptr) { } ~GuardObjectNotifier() { *statementDone = true; diff --git a/external/spidermonkey/include/android/mozilla/HashFunctions.h b/external/spidermonkey/include/android/mozilla/HashFunctions.h index 96242b629a..6d0d24e7b1 100644 --- a/external/spidermonkey/include/android/mozilla/HashFunctions.h +++ b/external/spidermonkey/include/android/mozilla/HashFunctions.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Utilities for hashing. */ @@ -39,17 +40,18 @@ * }; * * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKey.h. + * in nsHashKeys.h. */ -#ifndef mozilla_HashFunctions_h_ -#define mozilla_HashFunctions_h_ +#ifndef mozilla_HashFunctions_h +#define mozilla_HashFunctions_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + #ifdef __cplusplus namespace mozilla { @@ -173,8 +175,8 @@ AddToHash(uint32_t hash, A* a) * catch data pointers and couldn't handle function pointers. */ - MOZ_STATIC_ASSERT(sizeof(a) == sizeof(uintptr_t), - "Strange pointer!"); + static_assert(sizeof(a) == sizeof(uintptr_t), + "Strange pointer!"); return detail::AddUintptrToHash(hash, uintptr_t(a)); } @@ -356,4 +358,5 @@ HashBytes(const void* bytes, size_t length); } /* namespace mozilla */ #endif /* __cplusplus */ -#endif /* mozilla_HashFunctions_h_ */ + +#endif /* mozilla_HashFunctions_h */ diff --git a/external/spidermonkey/include/android/mozilla/Likely.h b/external/spidermonkey/include/android/mozilla/Likely.h index 6412b4943b..4f21609295 100644 --- a/external/spidermonkey/include/android/mozilla/Likely.h +++ b/external/spidermonkey/include/android/mozilla/Likely.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a * boolean predicate should be branch-predicted. */ -#ifndef mozilla_Likely_h_ -#define mozilla_Likely_h_ +#ifndef mozilla_Likely_h +#define mozilla_Likely_h #if defined(__clang__) || defined(__GNUC__) # define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) @@ -19,4 +20,4 @@ # define MOZ_UNLIKELY(x) (!!(x)) #endif -#endif /* mozilla_Likely_h_ */ +#endif /* mozilla_Likely_h */ diff --git a/external/spidermonkey/include/android/mozilla/LinkedList.h b/external/spidermonkey/include/android/mozilla/LinkedList.h index 5cfd60e4ac..c29760b3e7 100644 --- a/external/spidermonkey/include/android/mozilla/LinkedList.h +++ b/external/spidermonkey/include/android/mozilla/LinkedList.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -45,18 +46,19 @@ * } * * void notifyObservers(char* topic) { - * for (Observer* o = list.getFirst(); o != NULL; o = o->getNext()) - * o->Observe(topic); + * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) + * o->observe(topic); * } * }; * */ -#ifndef mozilla_LinkedList_h_ -#define mozilla_LinkedList_h_ +#ifndef mozilla_LinkedList_h +#define mozilla_LinkedList_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #ifdef __cplusplus @@ -69,10 +71,10 @@ template class LinkedListElement { /* - * It's convenient that we return NULL when getNext() or getPrevious() hits - * the end of the list, but doing so costs an extra word of storage in each - * linked list node (to keep track of whether |this| is the sentinel node) - * and a branch on this value in getNext/getPrevious. + * It's convenient that we return nullptr when getNext() or getPrevious() + * hits the end of the list, but doing so costs an extra word of storage in + * each linked list node (to keep track of whether |this| is the sentinel + * node) and a branch on this value in getNext/getPrevious. * * We could get rid of the extra word of storage by shoving the "is * sentinel" bit into one of the pointers, although this would, of course, @@ -107,12 +109,10 @@ class LinkedListElement LinkedListElement* prev; const bool isSentinel; - LinkedListElement* thisDuringConstruction() { return this; } - public: LinkedListElement() - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(false) { } @@ -122,8 +122,8 @@ class LinkedListElement } /* - * Get the next element in the list, or NULL if this is the last element in - * the list. + * Get the next element in the list, or nullptr if this is the last element + * in the list. */ T* getNext() { return next->asT(); @@ -133,8 +133,8 @@ class LinkedListElement } /* - * Get the previous element in the list, or NULL if this is the first element - * in the list. + * Get the previous element in the list, or nullptr if this is the first + * element in the list. */ T* getPrevious() { return prev->asT(); @@ -201,24 +201,24 @@ class LinkedListElement }; LinkedListElement(NodeKind nodeKind) - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(nodeKind == NODE_KIND_SENTINEL) { } /* - * Return |this| cast to T* if we're a normal node, or return NULL if we're - * a sentinel node. + * Return |this| cast to T* if we're a normal node, or return nullptr if + * we're a sentinel node. */ T* asT() { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } const T* asT() const { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } @@ -285,7 +285,7 @@ class LinkedList } /* - * Get the first element of the list, or NULL if the list is empty. + * Get the first element of the list, or nullptr if the list is empty. */ T* getFirst() { return sentinel.getNext(); @@ -295,7 +295,7 @@ class LinkedList } /* - * Get the last element of the list, or NULL if the list is empty. + * Get the last element of the list, or nullptr if the list is empty. */ T* getLast() { return sentinel.getPrevious(); @@ -306,7 +306,7 @@ class LinkedList /* * Get and remove the first element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popFirst() { T* ret = sentinel.getNext(); @@ -317,7 +317,7 @@ class LinkedList /* * Get and remove the last element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popLast() { T* ret = sentinel.getPrevious(); @@ -415,7 +415,7 @@ class LinkedList if (elem == t) return; } - MOZ_NOT_REACHED("element wasn't found in this list!"); + MOZ_CRASH("element wasn't found in this list!"); #endif } @@ -425,5 +425,6 @@ class LinkedList } /* namespace mozilla */ -#endif /* ifdef __cplusplus */ -#endif /* ifdef mozilla_LinkedList_h_ */ +#endif /* __cplusplus */ + +#endif /* mozilla_LinkedList_h */ diff --git a/external/spidermonkey/include/android/mozilla/MSStdInt.h b/external/spidermonkey/include/android/mozilla/MSStdInt.h deleted file mode 100644 index 0447f2f11b..0000000000 --- a/external/spidermonkey/include/android/mozilla/MSStdInt.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// 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. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/external/spidermonkey/include/android/mozilla/MathAlgorithms.h b/external/spidermonkey/include/android/mozilla/MathAlgorithms.h index 0a47810553..6d58691e06 100644 --- a/external/spidermonkey/include/android/mozilla/MathAlgorithms.h +++ b/external/spidermonkey/include/android/mozilla/MathAlgorithms.h @@ -1,19 +1,20 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt maths algorithms. */ -#ifndef mozilla_MathAlgorithms_h_ -#define mozilla_MathAlgorithms_h_ +#ifndef mozilla_MathAlgorithms_h +#define mozilla_MathAlgorithms_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" #include #include +#include namespace mozilla { @@ -142,6 +143,288 @@ Abs(const long double d) return std::fabs(d); } +} // namespace mozilla + +#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define MOZ_BITSCAN_WINDOWS + + extern "C" { + unsigned char _BitScanForward(unsigned long* Index, unsigned long mask); + unsigned char _BitScanReverse(unsigned long* Index, unsigned long mask); +# pragma intrinsic(_BitScanForward, _BitScanReverse) + +# if defined(_M_AMD64) || defined(_M_X64) +# define MOZ_BITSCAN_WINDOWS64 + unsigned char _BitScanForward64(unsigned long* index, unsigned __int64 mask); + unsigned char _BitScanReverse64(unsigned long* index, unsigned __int64 mask); +# pragma intrinsic(_BitScanForward64, _BitScanReverse64) +# endif + } // extern "C" + +#endif + +namespace mozilla { + +namespace detail { + +#if defined(MOZ_BITSCAN_WINDOWS) + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanReverse(&index, static_cast(u)); + return uint_fast8_t(31 - index); + } + + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanForward(&index, static_cast(u)); + return uint_fast8_t(index); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanReverse64(&index, static_cast(u)); + return uint_fast8_t(63 - index); +# else + uint32_t hi = uint32_t(u >> 32); + if (hi != 0) + return CountLeadingZeroes32(hi); + return 32 + CountLeadingZeroes32(uint32_t(u)); +# endif + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanForward64(&index, static_cast(u)); + return uint_fast8_t(index); +# else + uint32_t lo = uint32_t(u); + if (lo != 0) + return CountTrailingZeroes32(lo); + return 32 + CountTrailingZeroes32(uint32_t(u >> 32)); +# endif + } + +# ifdef MOZ_HAVE_BITSCAN64 +# undef MOZ_HAVE_BITSCAN64 +# endif + +#elif defined(__clang__) || defined(__GNUC__) + +# if defined(__clang__) +# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) +# error "A clang providing __builtin_c[lt]z is required to build" +# endif +# else + // gcc has had __builtin_clz and friends since 3.4: no need to check. +# endif + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + return __builtin_clz(u); + } + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + return __builtin_ctz(u); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { + return __builtin_clzll(u); + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { + return __builtin_ctzll(u); + } + +#else +# error "Implement these!" + inline uint_fast8_t CountLeadingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountLeadingZeroes64(uint64_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes64(uint64_t u) MOZ_DELETE; +#endif + +} // namespace detail + +/** + * Compute the number of high-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the highest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountLeadingZeroes32(0xF0FF1000) is 0; + * CountLeadingZeroes32(0x7F8F0001) is 1; + * CountLeadingZeroes32(0x3FFF0100) is 2; + * CountLeadingZeroes32(0x1FF50010) is 3; and so on. + */ +inline uint_fast8_t +CountLeadingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes32(u); +} + +/** + * Compute the number of low-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the lowest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountTrailingZeroes32(0x0100FFFF) is 0; + * CountTrailingZeroes32(0x7000FFFE) is 1; + * CountTrailingZeroes32(0x0080FFFC) is 2; + * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. + */ +inline uint_fast8_t +CountTrailingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes32(u); +} + +/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountLeadingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes64(u); +} + +/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountTrailingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes64(u); +} + +namespace detail { + +template +class CeilingLog2; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 32 - CountLeadingZeroes32(t - 1); + } +}; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 64 - CountLeadingZeroes64(t - 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the least power of 2 greater than or equal to |t|. + * + * CeilingLog2(0..1) is 0; + * CeilingLog2(2) is 1; + * CeilingLog2(3..4) is 2; + * CeilingLog2(5..8) is 3; + * CeilingLog2(9..16) is 4; and so on. + */ +template +inline uint_fast8_t +CeilingLog2(const T t) +{ + return detail::CeilingLog2::compute(t); +} + +/** A CeilingLog2 variant that accepts only size_t. */ +inline uint_fast8_t +CeilingLog2Size(size_t n) +{ + return CeilingLog2(n); +} + +namespace detail { + +template +class FloorLog2; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 31 - CountLeadingZeroes32(t | 1); + } +}; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 63 - CountLeadingZeroes64(t | 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the greatest power of 2 less than or equal to |t|. + * + * FloorLog2(0..1) is 0; + * FloorLog2(2..3) is 1; + * FloorLog2(4..7) is 2; + * FloorLog2(8..15) is 3; and so on. + */ +template +inline uint_fast8_t +FloorLog2(const T t) +{ + return detail::FloorLog2::compute(t); +} + +/** A FloorLog2 variant that accepts only size_t. */ +inline uint_fast8_t +FloorLog2Size(size_t n) +{ + return FloorLog2(n); +} + +/* + * Compute the smallest power of 2 greater than or equal to |x|. |x| must not + * be so great that the computed value would overflow |size_t|. + */ +inline size_t +RoundUpPow2(size_t x) +{ + MOZ_ASSERT(x <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), + "can't round up -- will overflow!"); + return size_t(1) << CeilingLog2(x); +} + } /* namespace mozilla */ -#endif /* mozilla_MathAlgorithms_h_ */ +#endif /* mozilla_MathAlgorithms_h */ diff --git a/external/spidermonkey/include/android/mozilla/MemoryChecking.h b/external/spidermonkey/include/android/mozilla/MemoryChecking.h index 3287e57ba1..2130990c6b 100644 --- a/external/spidermonkey/include/android/mozilla/MemoryChecking.h +++ b/external/spidermonkey/include/android/mozilla/MemoryChecking.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -19,8 +20,8 @@ * With no memory checker available, all macros expand to the empty statement. */ -#ifndef mozilla_MemoryChecking_h_ -#define mozilla_MemoryChecking_h_ +#ifndef mozilla_MemoryChecking_h +#define mozilla_MemoryChecking_h #if defined(MOZ_VALGRIND) #include "valgrind/memcheck.h" @@ -68,4 +69,4 @@ extern "C" { #endif -#endif /* mozilla_MemoryChecking_h_ */ +#endif /* mozilla_MemoryChecking_h */ diff --git a/external/spidermonkey/include/android/mozilla/MemoryReporting.h b/external/spidermonkey/include/android/mozilla/MemoryReporting.h new file mode 100644 index 0000000000..d2340ecf09 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/MemoryReporting.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Memory reporting infrastructure. */ + +#ifndef mozilla_MemoryReporting_h +#define mozilla_MemoryReporting_h + +#include + +#ifdef __cplusplus + +namespace mozilla { + +/* + * This is for functions that are like malloc_usable_size. Such functions are + * used for measuring the size of data structures. + */ +typedef size_t (*MallocSizeOf)(const void* p); + +} /* namespace mozilla */ + +#endif /* __cplusplus */ + +typedef size_t (*MozMallocSizeOf)(const void* p); + +#endif /* mozilla_MemoryReporting_h */ diff --git a/external/spidermonkey/include/android/mozilla/Move.h b/external/spidermonkey/include/android/mozilla/Move.h new file mode 100644 index 0000000000..97178daaa6 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Move.h @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* C++11-style, but C++98-usable, "move references" implementation. */ + +#ifndef mozilla_Move_h +#define mozilla_Move_h + +namespace mozilla { + +/* + * "Move" References + * + * Some types can be copied much more efficiently if we know the original's + * value need not be preserved --- that is, if we are doing a "move", not a + * "copy". For example, if we have: + * + * Vector u; + * Vector v(u); + * + * the constructor for v must apply a copy constructor to each element of u --- + * taking time linear in the length of u. However, if we know we will not need u + * any more once v has been initialized, then we could initialize v very + * efficiently simply by stealing u's dynamically allocated buffer and giving it + * to v --- a constant-time operation, regardless of the size of u. + * + * Moves often appear in container implementations. For example, when we append + * to a vector, we may need to resize its buffer. This entails moving each of + * its extant elements from the old, smaller buffer to the new, larger buffer. + * But once the elements have been migrated, we're just going to throw away the + * old buffer; we don't care if they still have their values. So if the vector's + * element type can implement "move" more efficiently than "copy", the vector + * resizing should by all means use a "move" operation. Hash tables also need to + * be resized. + * + * The details of the optimization, and whether it's worth applying, vary from + * one type to the next. And while some constructor calls are moves, many really + * are copies, and can't be optimized this way. So we need: + * + * 1) a way for a particular invocation of a copy constructor to say that it's + * really a move, and that the value of the original isn't important + * afterwards (although it must still be safe to destroy); and + * + * 2) a way for a type (like Vector) to announce that it can be moved more + * efficiently than it can be copied, and provide an implementation of that + * move operation. + * + * The Move(T&) function takes a reference to a T, and returns a MoveRef + * referring to the same value; that's 1). A MoveRef is simply a reference + * to a T, annotated to say that a copy constructor applied to it may move that + * T, instead of copying it. Finally, a constructor that accepts an MoveRef + * should perform a more efficient move, instead of a copy, providing 2). + * + * So, where we might define a copy constructor for a class C like this: + * + * C(const C& rhs) { ... copy rhs to this ... } + * + * we would declare a move constructor like this: + * + * C(MoveRef rhs) { ... move rhs to this ... } + * + * And where we might perform a copy like this: + * + * C c2(c1); + * + * we would perform a move like this: + * + * C c2(Move(c1)) + * + * Note that MoveRef implicitly converts to T&, so you can pass a MoveRef + * to an ordinary copy constructor for a type that doesn't support a special + * move constructor, and you'll just get a copy. This means that templates can + * use Move whenever they know they won't use the original value any more, even + * if they're not sure whether the type at hand has a specialized move + * constructor. If it doesn't, the MoveRef will just convert to a T&, and + * the ordinary copy constructor will apply. + * + * A class with a move constructor can also provide a move assignment operator, + * which runs this's destructor, and then applies the move constructor to + * *this's memory. A typical definition: + * + * C& operator=(MoveRef rhs) { + * this->~C(); + * new(this) C(rhs); + * return *this; + * } + * + * With that in place, one can write move assignments like this: + * + * c2 = Move(c1); + * + * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but + * destructible state. + * + * This header file defines MoveRef and Move in the mozilla namespace. It's up + * to individual containers to annotate moves as such, by calling Move; and it's + * up to individual types to define move constructors. + * + * One hint: if you're writing a move constructor where the type has members + * that should be moved themselves, it's much nicer to write this: + * + * C(MoveRef c) : x(Move(c->x)), y(Move(c->y)) { } + * + * than the equivalent: + * + * C(MoveRef c) { new(&x) X(Move(c->x)); new(&y) Y(Move(c->y)); } + * + * especially since GNU C++ fails to notice that this does indeed initialize x + * and y, which may matter if they're const. + */ +template +class MoveRef +{ + T* pointer; + + public: + explicit MoveRef(T& t) : pointer(&t) { } + T& operator*() const { return *pointer; } + T* operator->() const { return pointer; } + operator T& () const { return *pointer; } +}; + +template +inline MoveRef +Move(T& t) +{ + return MoveRef(t); +} + +template +inline MoveRef +Move(const T& t) +{ + // With some versions of gcc, for a class C, there's an (incorrect) ambiguity + // between the C(const C&) constructor and the default C(C&&) C++11 move + // constructor, when the constructor is called with a const C& argument. + // + // This ambiguity manifests with the Move implementation above when Move is + // passed const U& for some class U. Calling Move(const U&) returns a + // MoveRef, which is then commonly passed to the U constructor, + // triggering an implicit conversion to const U&. gcc doesn't know whether to + // call U(const U&) or U(U&&), so it wrongly reports a compile error. + // + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50442 has since been fixed, so + // this is no longer an issue for up-to-date compilers. But there's no harm + // in keeping it around for older compilers, so we might as well. See also + // bug 686280. + return MoveRef(const_cast(t)); +} + +/** Swap |t| and |u| using move-construction if possible. */ +template +inline void +Swap(T& t, T& u) +{ + T tmp(Move(t)); + t = Move(u); + u = Move(tmp); +} + +} // namespace mozilla + +#endif /* mozilla_Move_h */ diff --git a/external/spidermonkey/include/android/mozilla/NullPtr.h b/external/spidermonkey/include/android/mozilla/NullPtr.h index 7dcb03d734..14c0f07df2 100644 --- a/external/spidermonkey/include/android/mozilla/NullPtr.h +++ b/external/spidermonkey/include/android/mozilla/NullPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * constant. */ -#ifndef mozilla_NullPtr_h_ -#define mozilla_NullPtr_h_ +#ifndef mozilla_NullPtr_h +#define mozilla_NullPtr_h #include "mozilla/Compiler.h" @@ -45,4 +46,4 @@ # endif #endif -#endif /* mozilla_NullPtr_h_ */ +#endif /* mozilla_NullPtr_h */ diff --git a/external/spidermonkey/include/android/mozilla/PodOperations.h b/external/spidermonkey/include/android/mozilla/PodOperations.h index 6c6af27fc9..bec89fa928 100644 --- a/external/spidermonkey/include/android/mozilla/PodOperations.h +++ b/external/spidermonkey/include/android/mozilla/PodOperations.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -156,4 +157,4 @@ PodEqual(const T* one, const T* two, size_t len) } // namespace mozilla -#endif // mozilla_PodOperations_h_ +#endif /* mozilla_PodOperations_h */ diff --git a/external/spidermonkey/include/android/mozilla/Poison.h b/external/spidermonkey/include/android/mozilla/Poison.h index c4adc23e71..75e0f081cd 100644 --- a/external/spidermonkey/include/android/mozilla/Poison.h +++ b/external/spidermonkey/include/android/mozilla/Poison.h @@ -9,13 +9,14 @@ * an address that leads to a safe crash when dereferenced. */ -#ifndef mozilla_Poison_h_ -#define mozilla_Poison_h_ +#ifndef mozilla_Poison_h +#define mozilla_Poison_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + MOZ_BEGIN_EXTERN_C extern MFBT_DATA uintptr_t gMozillaPoisonValue; @@ -36,11 +37,11 @@ inline uintptr_t mozPoisonValue() */ inline void mozWritePoison(void* aPtr, size_t aSize) { - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); const uintptr_t POISON = mozPoisonValue(); char* p = (char*)aPtr; char* limit = p + aSize; + MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); + MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); for (; p < limit; p += sizeof(uintptr_t)) { *((uintptr_t*)p) = POISON; } @@ -58,4 +59,4 @@ extern MFBT_DATA uintptr_t gMozillaPoisonSize; MOZ_END_EXTERN_C -#endif /* mozilla_Poison_h_ */ +#endif /* mozilla_Poison_h */ diff --git a/external/spidermonkey/include/android/mozilla/Range.h b/external/spidermonkey/include/android/mozilla/Range.h index e14594d09d..4e02d962b5 100644 --- a/external/spidermonkey/include/android/mozilla/Range.h +++ b/external/spidermonkey/include/android/mozilla/Range.h @@ -1,12 +1,11 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef mozilla_Range_h_ -#define mozilla_Range_h_ +#ifndef mozilla_Range_h +#define mozilla_Range_h #include "mozilla/NullPtr.h" #include "mozilla/RangedPtr.h" @@ -40,10 +39,13 @@ class Range return mStart[offset]; } + const T& operator[](size_t offset) const { + return mStart[offset]; + } + operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; } }; } // namespace mozilla -#endif // mozilla_Range_h_ - +#endif /* mozilla_Range_h */ diff --git a/external/spidermonkey/include/android/mozilla/RangedPtr.h b/external/spidermonkey/include/android/mozilla/RangedPtr.h index 7ce19d071f..493fcdbaee 100644 --- a/external/spidermonkey/include/android/mozilla/RangedPtr.h +++ b/external/spidermonkey/include/android/mozilla/RangedPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,11 +9,12 @@ * construction. */ -#ifndef mozilla_RangedPtr_h_ -#define mozilla_RangedPtr_h_ +#ifndef mozilla_RangedPtr_h +#define mozilla_RangedPtr_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #include "mozilla/Util.h" namespace mozilla { @@ -59,7 +61,7 @@ class RangedPtr #ifdef DEBUG return RangedPtr(p, rangeStart, rangeEnd); #else - return RangedPtr(p, NULL, size_t(0)); + return RangedPtr(p, nullptr, size_t(0)); #endif } @@ -251,4 +253,4 @@ class RangedPtr } /* namespace mozilla */ -#endif /* mozilla_RangedPtr_h_ */ +#endif /* mozilla_RangedPtr_h */ diff --git a/external/spidermonkey/include/android/mozilla/ReentrancyGuard.h b/external/spidermonkey/include/android/mozilla/ReentrancyGuard.h new file mode 100644 index 0000000000..d589f368a2 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/ReentrancyGuard.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Small helper class for asserting uses of a class are non-reentrant. */ + +#ifndef mozilla_ReentrancyGuard_h +#define mozilla_ReentrancyGuard_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/GuardObjects.h" + +namespace mozilla { + +/* Useful for implementing containers that assert non-reentrancy */ +class ReentrancyGuard +{ + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER +#ifdef DEBUG + bool& entered; +#endif + + public: + template +#ifdef DEBUG + ReentrancyGuard(T& obj + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : entered(obj.entered) +#else + ReentrancyGuard(T& + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) +#endif + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; +#ifdef DEBUG + MOZ_ASSERT(!entered); + entered = true; +#endif + } + ~ReentrancyGuard() + { +#ifdef DEBUG + entered = false; +#endif + } + + private: + ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE; + void operator=(const ReentrancyGuard&) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_ReentrancyGuard_h */ diff --git a/external/spidermonkey/include/android/mozilla/RefPtr.h b/external/spidermonkey/include/android/mozilla/RefPtr.h index 9f4163a21a..3c275afdc7 100644 --- a/external/spidermonkey/include/android/mozilla/RefPtr.h +++ b/external/spidermonkey/include/android/mozilla/RefPtr.h @@ -1,14 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Helpers for defining and using refcounted objects. */ -#ifndef mozilla_RefPtr_h_ -#define mozilla_RefPtr_h_ +#ifndef mozilla_RefPtr_h +#define mozilla_RefPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/TypeTraits.h" @@ -41,13 +43,19 @@ template OutParamRef byRef(RefPtr&); * state distinguishes use-before-ref (refcount==0) from * use-after-destroy (refcount==0xffffdead). */ -#ifdef DEBUG namespace detail { +#ifdef DEBUG static const int DEAD = 0xffffdead; -} #endif -template +// This is used WeakPtr.h as well as this file. +enum RefCountAtomicity +{ + AtomicRefCount, + NonAtomicRefCount +}; + +template class RefCounted { friend class RefPtr; @@ -56,8 +64,6 @@ class RefCounted RefCounted() : refCnt(0) { } ~RefCounted() { MOZ_ASSERT(refCnt == detail::DEAD); - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from RefCounted"); } public: @@ -87,7 +93,33 @@ class RefCounted } private: - int refCnt; + typename Conditional, int>::Type refCnt; +}; + +} + +template +class RefCounted : public detail::RefCounted +{ + public: + ~RefCounted() { + static_assert(IsBaseOf::value, + "T must derive from RefCounted"); + } +}; + +/** + * AtomicRefCounted is like RefCounted, with an atomically updated + * reference counter. + */ +template +class AtomicRefCounted : public detail::RefCounted +{ + public: + ~AtomicRefCounted() { + static_assert(IsBaseOf::value, + "T must derive from AtomicRefCounted"); + } }; /** @@ -259,9 +291,6 @@ byRef(RefPtr& ptr) } // namespace mozilla -#endif // mozilla_RefPtr_h_ - - #if 0 // Command line that builds these tests @@ -416,3 +445,5 @@ main(int argc, char** argv) } #endif + +#endif /* mozilla_RefPtr_h */ diff --git a/external/spidermonkey/include/android/mozilla/SHA1.h b/external/spidermonkey/include/android/mozilla/SHA1.h index a6604e699f..b167648540 100644 --- a/external/spidermonkey/include/android/mozilla/SHA1.h +++ b/external/spidermonkey/include/android/mozilla/SHA1.h @@ -1,17 +1,18 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Simple class for computing SHA1. */ -#ifndef mozilla_SHA1_h_ -#define mozilla_SHA1_h_ +#ifndef mozilla_SHA1_h +#define mozilla_SHA1_h -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" #include +#include namespace mozilla { @@ -58,4 +59,4 @@ class SHA1Sum } /* namespace mozilla */ -#endif /* mozilla_SHA1_h_ */ +#endif /* mozilla_SHA1_h */ diff --git a/external/spidermonkey/include/android/mozilla/Scoped.h b/external/spidermonkey/include/android/mozilla/Scoped.h index 677a1a3797..fc48584b3e 100644 --- a/external/spidermonkey/include/android/mozilla/Scoped.h +++ b/external/spidermonkey/include/android/mozilla/Scoped.h @@ -1,11 +1,13 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* A number of structures to simplify scope-based RAII management. */ -#ifndef mozilla_Scoped_h_ -#define mozilla_Scoped_h_ +#ifndef mozilla_Scoped_h +#define mozilla_Scoped_h /* * Resource Acquisition Is Initialization is a programming idiom used @@ -52,6 +54,7 @@ #include "mozilla/Attributes.h" #include "mozilla/GuardObjects.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -193,7 +196,7 @@ template struct ScopedFreePtrTraits { typedef T* type; - static T* empty() { return NULL; } + static T* empty() { return nullptr; } static void release(T* ptr) { free(ptr); } }; SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits) @@ -256,7 +259,7 @@ template struct TypeSpecificScopedPointerTraits { typedef T* type; - const static type empty() { return NULL; } + const static type empty() { return nullptr; } const static void release(type value) { if (value) @@ -268,4 +271,4 @@ SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) } /* namespace mozilla */ -#endif // mozilla_Scoped_h_ +#endif /* mozilla_Scoped_h */ diff --git a/external/spidermonkey/include/android/mozilla/SplayTree.h b/external/spidermonkey/include/android/mozilla/SplayTree.h index f9a10d36dd..de0235aec9 100644 --- a/external/spidermonkey/include/android/mozilla/SplayTree.h +++ b/external/spidermonkey/include/android/mozilla/SplayTree.h @@ -1,7 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -10,8 +9,8 @@ * are faster to access again. */ -#ifndef mozilla_SplayTree_h_ -#define mozilla_SplayTree_h_ +#ifndef mozilla_SplayTree_h +#define mozilla_SplayTree_h #include "mozilla/Assertions.h" #include "mozilla/NullPtr.h" @@ -282,4 +281,4 @@ class SplayTree } /* namespace mozilla */ -#endif /* mozilla_SplayTree_h_ */ +#endif /* mozilla_SplayTree_h */ diff --git a/external/spidermonkey/include/android/mozilla/StandardInteger.h b/external/spidermonkey/include/android/mozilla/StandardInteger.h deleted file mode 100644 index 8e4c8578f1..0000000000 --- a/external/spidermonkey/include/android/mozilla/StandardInteger.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implements the C99 interface for C and C++ code. */ - -#ifndef mozilla_StandardInteger_h_ -#define mozilla_StandardInteger_h_ - -/* - * The C99 standard header exposes typedefs for common fixed-width - * integer types. It would be feasible to simply #include , but - * MSVC++ versions prior to 2010 don't provide . We could solve this - * by reimplementing for MSVC++ 2008 and earlier. But then we reach - * a second problem: our custom might conflict with a - * defined by an embedder already looking to work around the MSVC++ - * absence. - * - * We address these issues in this manner: - * - * 1. If the preprocessor macro MOZ_CUSTOM_STDINT_H is defined to a path to a - * custom implementation, we will #include it. Embedders using - * a custom must define this macro to an implementation that - * will work with their embedding. - * 2. Otherwise, if we are compiling with a an MSVC++ version without - * , #include our custom reimplementation. - * 3. Otherwise, #include the standard provided by the compiler. - * - * Note that we can't call this file "stdint.h" or something case-insensitively - * equal to "stdint.h" because then MSVC (and other compilers on - * case-insensitive file systems) will include this file, rather than the system - * stdint.h, when we ask for below. - */ -#if defined(MOZ_CUSTOM_STDINT_H) -# include MOZ_CUSTOM_STDINT_H -#elif defined(_MSC_VER) && _MSC_VER < 1600 -# include "mozilla/MSStdInt.h" -#else -# include -#endif - -#endif /* mozilla_StandardInteger_h_ */ diff --git a/external/spidermonkey/include/android/mozilla/TemplateLib.h b/external/spidermonkey/include/android/mozilla/TemplateLib.h new file mode 100644 index 0000000000..50275fdadb --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/TemplateLib.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Reusable template meta-functions on types and compile-time values. Meta- + * functions are placed inside the 'tl' namespace to avoid conflict with non- + * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. + * mozilla::FloorLog2). + * + * When constexpr support becomes universal, we should probably use that instead + * of some of these templates, for simplicity. + */ + +#ifndef mozilla_TemplateLib_h +#define mozilla_TemplateLib_h + +#include +#include + +namespace mozilla { + +namespace tl { + +/** Compute min/max. */ +template +struct Min +{ + static const size_t value = I < J ? I : J; +}; +template +struct Max +{ + static const size_t value = I > J ? I : J; +}; + +/** Compute floor(log2(i)). */ +template +struct FloorLog2 +{ + static const size_t value = 1 + FloorLog2::value; +}; +template<> struct FloorLog2<0> { /* Error */ }; +template<> struct FloorLog2<1> { static const size_t value = 0; }; + +/** Compute ceiling(log2(i)). */ +template +struct CeilingLog2 +{ + static const size_t value = FloorLog2<2 * I - 1>::value; +}; + +/** Round up to the nearest power of 2. */ +template +struct RoundUpPow2 +{ + static const size_t value = size_t(1) << CeilingLog2::value; +}; +template<> +struct RoundUpPow2<0> +{ + static const size_t value = 1; +}; + +/** Compute the number of bits in the given unsigned type. */ +template +struct BitSize +{ + static const size_t value = sizeof(T) * CHAR_BIT; +}; + +/** + * Produce an N-bit mask, where N <= BitSize::value. Handle the + * language-undefined edge case when N = BitSize::value. + */ +template +struct NBitMask +{ + // Assert the precondition. On success this evaluates to 0. Otherwise it + // triggers divide-by-zero at compile time: a guaranteed compile error in + // C++11, and usually one in C++98. Add this value to |value| to assure + // its computation. + static const size_t checkPrecondition = 0 / size_t(N < BitSize::value); + static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; +}; +template<> +struct NBitMask::value> +{ + static const size_t value = size_t(-1); +}; + +/** + * For the unsigned integral type size_t, compute a mask M for N such that + * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) + */ +template +struct MulOverflowMask +{ + static const size_t value = + ~NBitMask::value - CeilingLog2::value>::value; +}; +template<> struct MulOverflowMask<0> { /* Error */ }; +template<> struct MulOverflowMask<1> { static const size_t value = 0; }; + +} // namespace tl + +} // namespace mozilla + +#endif /* mozilla_TemplateLib_h */ diff --git a/external/spidermonkey/include/android/mozilla/ThreadLocal.h b/external/spidermonkey/include/android/mozilla/ThreadLocal.h index 2b4eb30207..6df109821f 100644 --- a/external/spidermonkey/include/android/mozilla/ThreadLocal.h +++ b/external/spidermonkey/include/android/mozilla/ThreadLocal.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cross-platform lightweight thread local data wrappers. */ -#ifndef mozilla_ThreadLocal_h_ -#define mozilla_ThreadLocal_h_ +#ifndef mozilla_ThreadLocal_h +#define mozilla_ThreadLocal_h #if defined(XP_WIN) // This file will get included in any file that wants to add a profiler mark. @@ -28,6 +29,7 @@ __declspec(dllimport) unsigned long __stdcall TlsAlloc(); #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -98,15 +100,15 @@ template inline bool ThreadLocal::init() { - MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); + static_assert(sizeof(T) <= sizeof(void*), + "mozilla::ThreadLocal can't be used for types larger than " + "a pointer"); MOZ_ASSERT(!initialized()); #ifdef XP_WIN key = TlsAlloc(); inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES #else - inited = !pthread_key_create(&key, NULL); + inited = !pthread_key_create(&key, nullptr); #endif return inited; } @@ -144,4 +146,4 @@ ThreadLocal::set(const T value) } // namespace mozilla -#endif // mozilla_ThreadLocal_h_ +#endif /* mozilla_ThreadLocal_h */ diff --git a/external/spidermonkey/include/android/mozilla/TypeTraits.h b/external/spidermonkey/include/android/mozilla/TypeTraits.h index 656bc775f8..53c0b5c2f6 100644 --- a/external/spidermonkey/include/android/mozilla/TypeTraits.h +++ b/external/spidermonkey/include/android/mozilla/TypeTraits.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Template-based metaprogramming and type-testing facilities. */ -#ifndef mozilla_TypeTraits_h_ -#define mozilla_TypeTraits_h_ +#ifndef mozilla_TypeTraits_h +#define mozilla_TypeTraits_h /* * These traits are approximate copies of the traits and semantics from C++11's @@ -126,6 +127,28 @@ struct IsPointer : FalseType {}; template struct IsPointer : TrueType {}; +namespace detail { + +// __is_enum is a supported extension across all of our supported compilers. +template +struct IsEnumHelper + : IntegralConstant +{}; + +} // namespace detail + +/** + * IsEnum determines whether a type is an enum type. + * + * mozilla::IsEnum::value is true; + * mozilla::IsEnum::value is false; + * mozilla::IsEnum::value is false; + */ +template +struct IsEnum + : detail::IsEnumHelper::Type> +{}; + /* 20.9.4.2 Composite type traits [meta.unary.comp] */ /** @@ -197,8 +220,24 @@ template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; template struct IsPod : TrueType {}; +namespace detail { + +template::value> +struct IsSignedHelper; + +template +struct IsSignedHelper : TrueType {}; + +template +struct IsSignedHelper + : IntegralConstant::value && T(-1) < T(1)> +{}; + +} // namespace detail + /** - * IsSigned determines whether a type is a signed arithmetic type. + * IsSigned determines whether a type is a signed arithmetic type. |char| is + * considered a signed type if it has the same representation as |signed char|. * * Don't use this if the type might be user-defined! You might or might not get * a compile error, depending. @@ -209,10 +248,26 @@ template struct IsPod : TrueType {}; * mozilla::IsSigned::value is true. */ template -struct IsSigned - : IntegralConstant::value && T(-1) < T(0)> +struct IsSigned : detail::IsSignedHelper {}; + +namespace detail { + +template::value> +struct IsUnsignedHelper; + +template +struct IsUnsignedHelper : FalseType {}; + +template +struct IsUnsignedHelper + : IntegralConstant::value && + (IsSame::Type, bool>::value || + T(1) < T(-1))> {}; +} // namespace detail + /** * IsUnsigned determines whether a type is an unsigned arithmetic type. * @@ -225,9 +280,7 @@ struct IsSigned * mozilla::IsUnsigned::value is false. */ template -struct IsUnsigned - : IntegralConstant::value && T(0) < T(-1)> -{}; +struct IsUnsigned : detail::IsUnsignedHelper {}; /* 20.9.5 Type property queries [meta.unary.prop.query] */ @@ -427,6 +480,160 @@ struct RemoveCV /* 20.9.7.3 Sign modifications [meta.trans.sign] */ +template +struct EnableIf; + +template +struct Conditional; + +namespace detail { + +template +struct WithC : Conditional +{}; + +template +struct WithV : Conditional +{}; + + +template +struct WithCV : WithC::Type> +{}; + +template +struct CorrespondingSigned; + +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef short Type; }; +template<> +struct CorrespondingSigned { typedef int Type; }; +template<> +struct CorrespondingSigned { typedef long Type; }; +template<> +struct CorrespondingSigned { typedef long long Type; }; + +template::Type, + bool IsSignedIntegerType = IsSigned::value && + !IsSame::value> +struct MakeSigned; + +template +struct MakeSigned +{ + typedef T Type; +}; + +template +struct MakeSigned + : WithCV::value, IsVolatile::value, + typename CorrespondingSigned::Type> +{}; + +} // namespace detail + +/** + * MakeSigned produces the corresponding signed integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already a signed integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an unsigned integer type, the signed variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the integral type of the same size as T, with the lowest rank, + * with T's const/volatile qualifiers, is produced. (This basically only acts + * to produce signed char when T = char.) + * + * mozilla::MakeSigned::Type is signed long; + * mozilla::MakeSigned::Type is volatile int; + * mozilla::MakeSigned::Type is const signed short; + * mozilla::MakeSigned::Type is const signed char; + * mozilla::MakeSigned is an error; + * mozilla::MakeSigned is an error. + */ +template +struct MakeSigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeSigned + >::Type +{}; + +namespace detail { + +template +struct CorrespondingUnsigned; + +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned short Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned int Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long long Type; }; + + +template::Type, + bool IsUnsignedIntegerType = IsUnsigned::value && + !IsSame::value> +struct MakeUnsigned; + +template +struct MakeUnsigned +{ + typedef T Type; +}; + +template +struct MakeUnsigned + : WithCV::value, IsVolatile::value, + typename CorrespondingUnsigned::Type> +{}; + +} // namespace detail + +/** + * MakeUnsigned produces the corresponding unsigned integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already an unsigned integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an signed integer type, the unsigned variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the unsigned integral type of the same size as T, with the lowest + * rank, with T's const/volatile qualifiers, is produced. (This basically only + * acts to produce unsigned char when T = char.) + * + * mozilla::MakeUnsigned::Type is unsigned long; + * mozilla::MakeUnsigned::Type is volatile unsigned int; + * mozilla::MakeUnsigned::Type is const unsigned short; + * mozilla::MakeUnsigned::Type is const unsigned char; + * mozilla::MakeUnsigned is an error; + * mozilla::MakeUnsigned is an error. + */ +template +struct MakeUnsigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeUnsigned + >::Type +{}; + /* 20.9.7.4 Array modifications [meta.trans.arr] */ /* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ @@ -451,7 +658,7 @@ struct RemoveCV * ... * }; */ -template +template struct EnableIf {}; @@ -481,4 +688,4 @@ struct Conditional } /* namespace mozilla */ -#endif /* mozilla_TypeTraits_h_ */ +#endif /* mozilla_TypeTraits_h */ diff --git a/external/spidermonkey/include/android/mozilla/TypedEnum.h b/external/spidermonkey/include/android/mozilla/TypedEnum.h index 889960a32d..6f595cb4c5 100644 --- a/external/spidermonkey/include/android/mozilla/TypedEnum.h +++ b/external/spidermonkey/include/android/mozilla/TypedEnum.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Macros to emulate C++11 typed enums and enum classes. */ -#ifndef mozilla_TypedEnum_h_ -#define mozilla_TypedEnum_h_ +#ifndef mozilla_TypedEnum_h +#define mozilla_TypedEnum_h #include "mozilla/Attributes.h" @@ -91,16 +92,33 @@ * mandatory. As with MOZ_ENUM_TYPE(), it will do nothing on compilers that do * not support it. * - * Note that the workaround implemented here is not compatible with enums - * nested inside a class. + * MOZ_{BEGIN,END}_ENUM_CLASS doesn't work for defining enum classes nested + * inside classes. To define an enum class nested inside another class, use + * MOZ_{BEGIN,END}_NESTED_ENUM_CLASS, and place a MOZ_FINISH_NESTED_ENUM_CLASS + * in namespace scope to handle bits that can only be implemented with + * namespace-scoped code. For example: + * + * class FooBar { + * + * MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t) + * A, + * B = 6 + * MOZ_END_NESTED_ENUM_CLASS(Enum) + * + * }; + * + * MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum) */ #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) /* * All compilers that support strong enums also support an explicit * underlying type, so no extra check is needed. */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) enum class Name : type { -# define MOZ_END_ENUM_CLASS(Name) }; +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ + enum class Name : type { +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) /* nothing */ #else /** * We need Name to both name a type, and scope the provided enumerator @@ -136,14 +154,14 @@ * { * return Enum::A; * } - */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) \ + */\ +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ class Name \ { \ public: \ enum Enum MOZ_ENUM_TYPE(type) \ { -# define MOZ_END_ENUM_CLASS(Name) \ +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; \ Name() {} \ Name(Enum aEnum) : mEnum(aEnum) {} \ @@ -151,7 +169,8 @@ operator Enum() const { return mEnum; } \ private: \ Enum mEnum; \ - }; \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) \ inline int operator+(const int&, const Name::Enum&) MOZ_DELETE; \ inline int operator+(const Name::Enum&, const int&) MOZ_DELETE; \ inline int operator-(const int&, const Name::Enum&) MOZ_DELETE; \ @@ -207,7 +226,11 @@ inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \ inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE; #endif +# define MOZ_BEGIN_ENUM_CLASS(Name, type) MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) +# define MOZ_END_ENUM_CLASS(Name) \ + MOZ_END_NESTED_ENUM_CLASS(Name) \ + MOZ_FINISH_NESTED_ENUM_CLASS(Name) #endif /* __cplusplus */ -#endif /* mozilla_TypedEnum_h_ */ +#endif /* mozilla_TypedEnum_h */ diff --git a/external/spidermonkey/include/android/mozilla/Types.h b/external/spidermonkey/include/android/mozilla/Types.h index 56e5cb82fb..5340b2b600 100644 --- a/external/spidermonkey/include/android/mozilla/Types.h +++ b/external/spidermonkey/include/android/mozilla/Types.h @@ -1,28 +1,22 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt foundational types and macros. */ -#ifndef mozilla_Types_h_ -#define mozilla_Types_h_ +#ifndef mozilla_Types_h +#define mozilla_Types_h /* * This header must be valid C and C++, includable by code embedding either * SpiderMonkey or Gecko. */ -/* - * Expose all the integer types defined in C99's (and the integer - * limit and constant macros, if compiling C code or if compiling C++ code and - * the right __STDC_*_MACRO has been defined for each). These are all usable - * throughout mfbt code, and throughout Mozilla code more generally. - */ -#include "mozilla/StandardInteger.h" - -/* Also expose size_t. */ +/* Expose all types and size_t. */ #include +#include /* Implement compiler and linker macros needed for APIs. */ @@ -133,4 +127,12 @@ # define MOZ_END_EXTERN_C #endif -#endif /* mozilla_Types_h_ */ +/* + * GCC's typeof is available when decltype is not. + */ +#if defined(__GNUC__) && defined(__cplusplus) && \ + !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +# define decltype __typeof__ +#endif + +#endif /* mozilla_Types_h */ diff --git a/external/spidermonkey/include/android/mozilla/Util.h b/external/spidermonkey/include/android/mozilla/Util.h index 097c5478eb..4f1c634a59 100644 --- a/external/spidermonkey/include/android/mozilla/Util.h +++ b/external/spidermonkey/include/android/mozilla/Util.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * new headers, or to other appropriate existing headers, not here. */ -#ifndef mozilla_Util_h_ -#define mozilla_Util_h_ +#ifndef mozilla_Util_h +#define mozilla_Util_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" @@ -196,6 +197,58 @@ class Maybe constructed = true; } + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); + constructed = true; + } + T* addr() { MOZ_ASSERT(constructed); return &asT(); @@ -271,7 +324,7 @@ ArrayEnd(T (&arr)[N]) /* * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for MOZ_STATIC_ASSERT() calls that + * that can't use C++ template functions and for static_assert() calls that * can't call ArrayLength() when it is not a C++11 constexpr function. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR @@ -280,4 +333,4 @@ ArrayEnd(T (&arr)[N]) # define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) #endif -#endif /* mozilla_Util_h_ */ +#endif /* mozilla_Util_h */ diff --git a/external/spidermonkey/include/android/mozilla/Vector.h b/external/spidermonkey/include/android/mozilla/Vector.h new file mode 100644 index 0000000000..8759df8c06 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Vector.h @@ -0,0 +1,1190 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A type/length-parametrized vector class. */ + +#ifndef mozilla_Vector_h +#define mozilla_Vector_h + +#include "mozilla/AllocPolicy.h" +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" +#include "mozilla/NullPtr.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" +#include "mozilla/TypeTraits.h" +#include "mozilla/Util.h" + +#include // for placement new + +/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4345) +#endif + +namespace mozilla { + +template +class VectorBase; + +namespace detail { + +/* + * Check that the given capacity wastes the minimal amount of space if + * allocated on the heap. This means that cap*sizeof(T) is as close to a + * power-of-two as possible. growStorageBy() is responsible for ensuring + * this. + */ +template +static bool CapacityHasExcessSpace(size_t cap) +{ + size_t size = cap * sizeof(T); + return RoundUpPow2(size) - size >= sizeof(T); +} + +/* + * This template class provides a default implementation for vector operations + * when the element type is not known to be a POD, as judged by IsPod. + */ +template +struct VectorImpl +{ + /* Destroys constructed objects in the range [begin, end). */ + static inline void destroy(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + p->~T(); + } + + /* Constructs objects in the uninitialized range [begin, end). */ + static inline void initialize(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + /* + * Copy-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(*p); + } + + /* + * Move-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(Move(*p)); + } + + /* + * Copy-constructs objects in the uninitialized range [dst, dst+n) from the + * same object u. + */ + template + static inline void copyConstructN(T* dst, size_t n, const U& u) { + for (T* end = dst + n; dst < end; ++dst) + new(dst) T(u); + } + + /* + * Grows the given buffer to have capacity newCap, preserving the objects + * constructed in the range [begin, end) and updating v. Assumes that (1) + * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will + * not overflow. + */ + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + T* newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); + if (!newbuf) + return false; + T* dst = newbuf; + T* src = v.beginNoCheck(); + for (; src < v.endNoCheck(); ++dst, ++src) + new(dst) T(Move(*src)); + VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); + v.free_(v.mBegin); + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +/* + * This partial template specialization provides a default implementation for + * vector operations when the element type is known to be a POD, as judged by + * IsPod. + */ +template +struct VectorImpl +{ + static inline void destroy(T*, T*) {} + + static inline void initialize(T* begin, T* end) { + /* + * You would think that memset would be a big win (or even break even) + * when we know T is a POD. But currently it's not. This is probably + * because |append| tends to be given small ranges and memset requires + * a function call that doesn't get inlined. + * + * memset(begin, 0, sizeof(T) * (end-begin)); + */ + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + /* + * See above memset comment. Also, notice that copyConstruct is + * currently templated (T != U), so memcpy won't work without + * requiring T == U. + * + * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); + */ + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + *dst = *p; + } + + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + copyConstruct(dst, srcbeg, srcend); + } + + static inline void copyConstructN(T* dst, size_t n, const T& t) { + for (T* end = dst + n; dst < end; ++dst) + *dst = t; + } + + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + size_t oldSize = sizeof(T) * v.mCapacity; + size_t newSize = sizeof(T) * newCap; + T* newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); + if (!newbuf) + return false; + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +} // namespace detail + +/* + * A CRTP base class for vector-like classes. Unless you really really want + * your own vector class -- and you almost certainly don't -- you should use + * mozilla::Vector instead! + * + * See mozilla::Vector for interface requirements. + */ +template +class VectorBase : private AllocPolicy +{ + /* utilities */ + + static const bool sElemIsPod = IsPod::value; + typedef detail::VectorImpl Impl; + friend struct detail::VectorImpl; + + bool growStorageBy(size_t incr); + bool convertToHeapStorage(size_t newCap); + + /* magic constants */ + + static const int sMaxInlineBytes = 1024; + + /* compute constants */ + + /* + * Consider element size to be 1 for buffer sizing if there are 0 inline + * elements. This allows us to compile when the definition of the element + * type is not visible here. + * + * Explicit specialization is only allowed at namespace scope, so in order + * to keep everything here, we use a dummy template parameter with partial + * specialization. + */ + template + struct ElemSize + { + static const size_t value = sizeof(T); + }; + template + struct ElemSize<0, Dummy> + { + static const size_t value = 1; + }; + + static const size_t sInlineCapacity = + tl::Min::value>::value; + + /* Calculate inline buffer size; avoid 0-sized array. */ + static const size_t sInlineBytes = + tl::Max<1, sInlineCapacity * ElemSize::value>::value; + + /* member data */ + + /* + * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, + * mBegin + mLength) hold valid constructed T objects. The range [mBegin + + * mLength, mBegin + mCapacity) holds uninitialized memory. The range + * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory + * previously allocated by a call to reserve(). + */ + T* mBegin; + + /* Number of elements in the vector. */ + size_t mLength; + + /* Max number of elements storable in the vector without resizing. */ + size_t mCapacity; + +#ifdef DEBUG + /* Max elements of reserved or used space in this vector. */ + size_t mReserved; +#endif + + /* Memory used for inline storage. */ + AlignedStorage storage; + +#ifdef DEBUG + friend class ReentrancyGuard; + bool entered; +#endif + + /* private accessors */ + + bool usingInlineStorage() const { + return mBegin == const_cast(this)->inlineStorage(); + } + + T* inlineStorage() { + return static_cast(storage.addr()); + } + + T* beginNoCheck() const { + return mBegin; + } + + T* endNoCheck() { + return mBegin + mLength; + } + + const T* endNoCheck() const { + return mBegin + mLength; + } + +#ifdef DEBUG + size_t reserved() const { + MOZ_ASSERT(mReserved <= mCapacity); + MOZ_ASSERT(mLength <= mReserved); + return mReserved; + } +#endif + + /* Append operations guaranteed to succeed due to pre-reserved space. */ + template void internalAppend(const U& u); + template + void internalAppendAll(const VectorBase& u); + void internalAppendN(const T& t, size_t n); + template void internalAppend(const U* begin, size_t length); + + public: + static const size_t sMaxInlineStorage = N; + + typedef T ElementType; + + VectorBase(AllocPolicy = AllocPolicy()); + VectorBase(MoveRef); /* Move constructor. */ + ThisVector& operator=(MoveRef); /* Move assignment. */ + ~VectorBase(); + + /* accessors */ + + const AllocPolicy& allocPolicy() const { + return *this; + } + + AllocPolicy& allocPolicy() { + return *this; + } + + enum { InlineLength = N }; + + size_t length() const { + return mLength; + } + + bool empty() const { + return mLength == 0; + } + + size_t capacity() const { + return mCapacity; + } + + T* begin() { + MOZ_ASSERT(!entered); + return mBegin; + } + + const T* begin() const { + MOZ_ASSERT(!entered); + return mBegin; + } + + T* end() { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + const T* end() const { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + T& operator[](size_t i) { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + T& back() { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + const T& back() const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + class Range + { + friend class VectorBase; + T* cur_; + T* end_; + Range(T* cur, T* end) : cur_(cur), end_(end) {} + + public: + Range() {} + bool empty() const { return cur_ == end_; } + size_t remain() const { return end_ - cur_; } + T& front() const { return *cur_; } + void popFront() { MOZ_ASSERT(!empty()); ++cur_; } + T popCopyFront() { MOZ_ASSERT(!empty()); return *cur_++; } + }; + + Range all() { + return Range(begin(), end()); + } + + /* mutators */ + + /** + * Given that the vector is empty and has no inline storage, grow to + * |capacity|. + */ + bool initCapacity(size_t request); + + /** + * If reserve(length() + N) succeeds, the N next appends are guaranteed to + * succeed. + */ + bool reserve(size_t request); + + /** + * Destroy elements in the range [end() - incr, end()). Does not deallocate + * or unreserve storage for those elements. + */ + void shrinkBy(size_t incr); + + /** Grow the vector by incr elements. */ + bool growBy(size_t incr); + + /** Call shrinkBy or growBy based on whether newSize > length(). */ + bool resize(size_t newLength); + + /** + * Increase the length of the vector, but don't initialize the new elements + * -- leave them as uninitialized memory. + */ + bool growByUninitialized(size_t incr); + bool resizeUninitialized(size_t newLength); + + /** Shorthand for shrinkBy(length()). */ + void clear(); + + /** Clears and releases any heap-allocated storage. */ + void clearAndFree(); + + /** + * If true, appending |needed| elements won't reallocate elements storage. + * This *doesn't* mean that infallibleAppend may be used! You still must + * reserve the extra space, even if this method indicates that appends won't + * need to reallocate elements storage. + */ + bool canAppendWithoutRealloc(size_t needed) const; + + /** + * Potentially fallible append operations. + * + * The function templates that take an unspecified type U require a const T& + * or a MoveRef. The MoveRef variants move their operands into the + * vector, instead of copying them. If they fail, the operand is left + * unmoved. + */ + template bool append(const U& u); + template + bool appendAll(const VectorBase& u); + bool appendN(const T& t, size_t n); + template bool append(const U* begin, const U* end); + template bool append(const U* begin, size_t length); + + /* + * Guaranteed-infallible append operations for use upon vectors whose + * memory has been pre-reserved. Don't use this if you haven't reserved the + * memory! + */ + template void infallibleAppend(const U& u) { + internalAppend(u); + } + void infallibleAppendN(const T& t, size_t n) { + internalAppendN(t, n); + } + template void infallibleAppend(const U* aBegin, const U* aEnd) { + internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); + } + template void infallibleAppend(const U* aBegin, size_t aLength) { + internalAppend(aBegin, aLength); + } + + void popBack(); + + T popCopy(); + + /** + * Transfers ownership of the internal buffer used by this vector to the + * caller. (It's the caller's responsibility to properly deallocate this + * buffer, in accordance with this vector's AllocPolicy.) After this call, + * the vector is empty. Since the returned buffer may need to be allocated + * (if the elements are currently stored in-place), the call can fail, + * returning nullptr. + * + * N.B. Although a T*, only the range [0, length()) is constructed. + */ + T* extractRawBuffer(); + + /** + * Transfer ownership of an array of objects into the vector. The caller + * must have allocated the array in accordance with this vector's + * AllocPolicy. + * + * N.B. This call assumes that there are no uninitialized elements in the + * passed array. + */ + void replaceRawBuffer(T* p, size_t length); + + /** + * Places |val| at position |p|, shifting existing elements from |p| onward + * one position higher. On success, |p| should not be reused because it'll + * be a dangling pointer if reallocation of the vector storage occurred; the + * return value should be used instead. On failure, nullptr is returned. + * + * Example usage: + * + * if (!(p = vec.insert(p, val))) + * + * + * + * This is inherently a linear-time operation. Be careful! + */ + T* insert(T* p, const T& val); + + /** + * Removes the element |t|, which must fall in the bounds [begin, end), + * shifting existing elements from |t + 1| onward one position lower. + */ + void erase(T* t); + + /** + * Measure the size of the vector's heap-allocated storage. + */ + size_t sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const; + + /** + * Like sizeOfExcludingThis, but also measures the size of the vector + * object (which must be heap-allocated) itself. + */ + size_t sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const; + + void swap(ThisVector& other); + + private: + VectorBase(const ThisVector&) MOZ_DELETE; + void operator=(const ThisVector&) MOZ_DELETE; +}; + +/* This does the re-entrancy check plus several other sanity checks. */ +#define MOZ_REENTRANCY_GUARD_ET_AL \ + ReentrancyGuard g(*this); \ + MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ + MOZ_ASSERT(reserved() <= mCapacity); \ + MOZ_ASSERT(mLength <= reserved()); \ + MOZ_ASSERT(mLength <= mCapacity) + +/* Vector Implementation */ + +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(AP ap) + : AP(ap), + mBegin(static_cast(storage.addr())), + mLength(0), + mCapacity(sInlineCapacity) +#ifdef DEBUG + , mReserved(sInlineCapacity), + entered(false) +#endif +{} + +/* Move constructor. */ +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(MoveRef rhs) + : AllocPolicy(rhs) +#ifdef DEBUG + , entered(false) +#endif +{ + mLength = rhs->mLength; + mCapacity = rhs->mCapacity; +#ifdef DEBUG + mReserved = rhs->mReserved; +#endif + + if (rhs->usingInlineStorage()) { + /* We can't move the buffer over in this case, so copy elements. */ + mBegin = static_cast(storage.addr()); + Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); + /* + * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. + * The elements in its in-line storage still need to be destroyed. + */ + } else { + /* + * Take src's buffer, and turn src into an empty vector using + * in-line storage. + */ + mBegin = rhs->mBegin; + rhs->mBegin = static_cast(rhs->storage.addr()); + rhs->mCapacity = sInlineCapacity; + rhs->mLength = 0; +#ifdef DEBUG + rhs->mReserved = sInlineCapacity; +#endif + } +} + +/* Move assignment. */ +template +MOZ_ALWAYS_INLINE +TV& +VectorBase::operator=(MoveRef rhs) +{ + TV* tv = static_cast(this); + tv->~TV(); + new(tv) TV(rhs); + return *tv; +} + +template +MOZ_ALWAYS_INLINE +VectorBase::~VectorBase() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); +} + +/* + * This function will create a new heap buffer with capacity newCap, + * move all elements in the inline buffer to this new buffer, + * and fail on OOM. + */ +template +inline bool +VectorBase::convertToHeapStorage(size_t newCap) +{ + MOZ_ASSERT(usingInlineStorage()); + + /* Allocate buffer. */ + MOZ_ASSERT(!detail::CapacityHasExcessSpace(newCap)); + T* newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); + if (!newBuf) + return false; + + /* Copy inline elements into heap buffer. */ + Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + + /* Switch in heap buffer. */ + mBegin = newBuf; + /* mLength is unchanged. */ + mCapacity = newCap; + return true; +} + +template +MOZ_NEVER_INLINE bool +VectorBase::growStorageBy(size_t incr) +{ + MOZ_ASSERT(mLength + incr > mCapacity); + MOZ_ASSERT_IF(!usingInlineStorage(), + !detail::CapacityHasExcessSpace(mCapacity)); + + /* + * When choosing a new capacity, its size should is as close to 2**N bytes + * as possible. 2**N-sized requests are best because they are unlikely to + * be rounded up by the allocator. Asking for a 2**N number of elements + * isn't as good, because if sizeof(T) is not a power-of-two that would + * result in a non-2**N request size. + */ + + size_t newCap; + + if (incr == 1) { + if (usingInlineStorage()) { + /* This case occurs in ~70--80% of the calls to this function. */ + size_t newSize = + tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::value; + newCap = newSize / sizeof(T); + goto convert; + } + + if (mLength == 0) { + /* This case occurs in ~0--10% of the calls to this function. */ + newCap = 1; + goto grow; + } + + /* This case occurs in ~15--20% of the calls to this function. */ + + /* + * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector + * to 1GB of memory on a 32-bit system, which is a reasonable limit. It + * also ensures that + * + * static_cast(end()) - static_cast(begin()) + * + * doesn't overflow ptrdiff_t (see bug 510319). + */ + if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::value) { + this->reportAllocOverflow(); + return false; + } + + /* + * If we reach here, the existing capacity will have a size that is already + * as close to 2^N as sizeof(T) will allow. Just double the capacity, and + * then there might be space for one more element. + */ + newCap = mLength * 2; + if (detail::CapacityHasExcessSpace(newCap)) + newCap += 1; + } else { + /* This case occurs in ~2% of the calls to this function. */ + size_t newMinCap = mLength + incr; + + /* Did mLength + incr overflow? Will newCap * sizeof(T) overflow? */ + if (newMinCap < mLength || + newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value) + { + this->reportAllocOverflow(); + return false; + } + + size_t newMinSize = newMinCap * sizeof(T); + size_t newSize = RoundUpPow2(newMinSize); + newCap = newSize / sizeof(T); + } + + if (usingInlineStorage()) { + convert: + return convertToHeapStorage(newCap); + } + +grow: + return Impl::growTo(*this, newCap); +} + +template +inline bool +VectorBase::initCapacity(size_t request) +{ + MOZ_ASSERT(empty()); + MOZ_ASSERT(usingInlineStorage()); + if (request == 0) + return true; + T* newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); + if (!newbuf) + return false; + mBegin = newbuf; + mCapacity = request; +#ifdef DEBUG + mReserved = request; +#endif + return true; +} + +template +inline bool +VectorBase::reserve(size_t request) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (request > mCapacity && !growStorageBy(request - mLength)) + return false; + +#ifdef DEBUG + if (request > mReserved) + mReserved = request; + MOZ_ASSERT(mLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); +#endif + return true; +} + +template +inline void +VectorBase::shrinkBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(incr <= mLength); + Impl::destroy(endNoCheck() - incr, endNoCheck()); + mLength -= incr; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + T* newend = endNoCheck() + incr; + Impl::initialize(endNoCheck(), newend); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growByUninitialized(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +inline bool +VectorBase::resize(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growBy(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::resizeUninitialized(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growByUninitialized(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +inline void +VectorBase::clear() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + mLength = 0; +} + +template +inline void +VectorBase::clearAndFree() +{ + clear(); + + if (usingInlineStorage()) + return; + + this->free_(beginNoCheck()); + mBegin = static_cast(storage.addr()); + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif +} + +template +inline bool +VectorBase::canAppendWithoutRealloc(size_t needed) const +{ + return mLength + needed <= mCapacity; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendAll(const VectorBase& other) +{ + internalAppend(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U& u) +{ + MOZ_ASSERT(mLength + 1 <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + new(endNoCheck()) T(u); + ++mLength; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendN(const T& t, size_t needed) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppendN(t, needed); + return true; +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendN(const T& t, size_t needed) +{ + MOZ_ASSERT(mLength + needed <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstructN(endNoCheck(), needed, t); + mLength += needed; +} + +template +inline T* +VectorBase::insert(T* p, const T& val) +{ + MOZ_ASSERT(begin() <= p); + MOZ_ASSERT(p <= end()); + size_t pos = p - begin(); + MOZ_ASSERT(pos <= mLength); + size_t oldLength = mLength; + if (pos == oldLength) { + if (!append(val)) + return nullptr; + } else { + T oldBack = back(); + if (!append(oldBack)) /* Dup the last element. */ + return nullptr; + for (size_t i = oldLength; i > pos; --i) + (*this)[i] = (*this)[i - 1]; + (*this)[pos] = val; + } + return begin() + pos; +} + +template +inline void +VectorBase::erase(T* it) +{ + MOZ_ASSERT(begin() <= it); + MOZ_ASSERT(it < end()); + while (it + 1 < end()) { + *it = *(it + 1); + ++it; + } + popBack(); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U* insBegin, const U* insEnd) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + size_t needed = PointerRangeSize(insBegin, insEnd); + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppend(insBegin, needed); + return true; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U* insBegin, size_t insLength) +{ + MOZ_ASSERT(mLength + insLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); + mLength += insLength; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U& u) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength == mCapacity && !growStorageBy(1)) + return false; + +#ifdef DEBUG + if (mLength + 1 > mReserved) + mReserved = mLength + 1; +#endif + internalAppend(u); + return true; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendAll(const VectorBase& other) +{ + return append(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U *insBegin, size_t insLength) +{ + return append(insBegin, insBegin + insLength); +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::popBack() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(!empty()); + --mLength; + endNoCheck()->~T(); +} + +template +MOZ_ALWAYS_INLINE T +VectorBase::popCopy() +{ + T ret = back(); + popBack(); + return ret; +} + +template +inline T* +VectorBase::extractRawBuffer() +{ + T* ret; + if (usingInlineStorage()) { + ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); + if (!ret) + return nullptr; + Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + /* mBegin, mCapacity are unchanged. */ + mLength = 0; + } else { + ret = mBegin; + mBegin = static_cast(storage.addr()); + mLength = 0; + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif + } + return ret; +} + +template +inline void +VectorBase::replaceRawBuffer(T* p, size_t aLength) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + + /* Destroy what we have. */ + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); + + /* Take in the new buffer. */ + if (aLength <= sInlineCapacity) { + /* + * We convert to inline storage if possible, even though p might + * otherwise be acceptable. Maybe this behaviour should be + * specifiable with an argument to this function. + */ + mBegin = static_cast(storage.addr()); + mLength = aLength; + mCapacity = sInlineCapacity; + Impl::moveConstruct(mBegin, p, p + aLength); + Impl::destroy(p, p + aLength); + this->free_(p); + } else { + mBegin = p; + mLength = aLength; + mCapacity = aLength; + } +#ifdef DEBUG + mReserved = aLength; +#endif +} + +template +inline size_t +VectorBase::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const +{ + return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); +} + +template +inline size_t +VectorBase::sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const +{ + return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); +} + +template +inline void +VectorBase::swap(TV& other) +{ + static_assert(N == 0, + "still need to implement this for N != 0"); + + // This only works when inline storage is always empty. + if (!usingInlineStorage() && other.usingInlineStorage()) { + other.mBegin = mBegin; + mBegin = inlineStorage(); + } else if (usingInlineStorage() && !other.usingInlineStorage()) { + mBegin = other.mBegin; + other.mBegin = other.inlineStorage(); + } else if (!usingInlineStorage() && !other.usingInlineStorage()) { + Swap(mBegin, other.mBegin); + } else { + // This case is a no-op, since we'd set both to use their inline storage. + } + + Swap(mLength, other.mLength); + Swap(mCapacity, other.mCapacity); +#ifdef DEBUG + Swap(mReserved, other.mReserved); +#endif +} + +/* + * STL-like container providing a short-lived, dynamic buffer. Vector calls the + * constructors/destructors of all elements stored in its internal buffer, so + * non-PODs may be safely used. Additionally, Vector will store the first N + * elements in-place before resorting to dynamic allocation. + * + * T requirements: + * - default and copy constructible, assignable, destructible + * - operations do not throw + * N requirements: + * - any value, however, N is clamped to min/max values + * AllocPolicy: + * - see "Allocation policies" in AllocPolicy.h (defaults to + * mozilla::MallocAllocPolicy) + * + * Vector is not reentrant: T member functions called during Vector member + * functions must not call back into the same object! + */ +template +class Vector + : public VectorBase > +{ + typedef VectorBase Base; + + public: + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector& operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); + } +}; + +} // namespace mozilla + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif /* mozilla_Vector_h */ diff --git a/external/spidermonkey/include/android/mozilla/WeakPtr.h b/external/spidermonkey/include/android/mozilla/WeakPtr.h index d61b0b37d3..c714ebf565 100644 --- a/external/spidermonkey/include/android/mozilla/WeakPtr.h +++ b/external/spidermonkey/include/android/mozilla/WeakPtr.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Weak pointer functionality, implemented as a mixin for use with any class. */ @@ -13,6 +14,9 @@ * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime * of 'Foo'. * + * AtomicSupportsWeakPtr can be used for a variant with an atomically updated + * reference counter. + * * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional * dereference, and an additional heap allocated pointer sized object shared * between all of the WeakPtrs. @@ -55,10 +59,11 @@ * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h */ -#ifndef mozilla_WeakPtr_h_ -#define mozilla_WeakPtr_h_ +#ifndef mozilla_WeakPtr_h +#define mozilla_WeakPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/NullPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/TypeTraits.h" @@ -71,8 +76,8 @@ template class SupportsWeakPtrBase; namespace detail { // This can live beyond the lifetime of the class derived from SupportsWeakPtrBase. -template -class WeakReference : public RefCounted > +template +class WeakReference : public RefCounted, Atomicity> { public: explicit WeakReference(T* p) : ptr(p) {} @@ -81,8 +86,8 @@ class WeakReference : public RefCounted > } private: - friend class WeakPtrBase >; - friend class SupportsWeakPtrBase >; + friend class WeakPtrBase; + friend class SupportsWeakPtrBase; void detach() { ptr = nullptr; } @@ -103,8 +108,8 @@ class SupportsWeakPtrBase protected: ~SupportsWeakPtrBase() { - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from SupportsWeakPtrBase"); + static_assert(IsBaseOf, T>::value, + "T must derive from SupportsWeakPtrBase"); if (weakRef) weakRef->detach(); } @@ -116,10 +121,30 @@ class SupportsWeakPtrBase }; template -class SupportsWeakPtr : public SupportsWeakPtrBase > +class SupportsWeakPtr + : public SupportsWeakPtrBase > { }; +template +class AtomicSupportsWeakPtr + : public SupportsWeakPtrBase > +{ +}; + +namespace detail { + +template +struct WeakReferenceCount +{ + static const RefCountAtomicity atomicity = + IsBaseOf, T>::value + ? AtomicRefCount + : NonAtomicRefCount; +}; + +} + template class WeakPtrBase { @@ -152,9 +177,9 @@ class WeakPtrBase }; template -class WeakPtr : public WeakPtrBase > +class WeakPtr : public WeakPtrBase::atomicity> > { - typedef WeakPtrBase > Base; + typedef WeakPtrBase::atomicity> > Base; public: WeakPtr(const WeakPtr& o) : Base(o) {} WeakPtr(const Base& o) : Base(o) {} @@ -163,4 +188,4 @@ class WeakPtr : public WeakPtrBase > } // namespace mozilla -#endif /* ifdef mozilla_WeakPtr_h_ */ +#endif /* mozilla_WeakPtr_h */ diff --git a/external/spidermonkey/include/ios/js-config.h b/external/spidermonkey/include/ios/js-config.h index 7c6c37636a..4b893482f4 100644 --- a/external/spidermonkey/include/ios/js-config.h +++ b/external/spidermonkey/include/ios/js-config.h @@ -38,8 +38,8 @@ JS_HAVE_STDINT_H. */ #define JS_BYTES_PER_WORD 4 -/* Some mozilla code uses JS-friend APIs that depend on JS_METHODJIT being - correct. */ -/* #undef JS_METHODJIT */ +/* MOZILLA JSAPI version number components */ +#define MOZJS_MAJOR_VERSION 25 +#define MOZJS_MINOR_VERSION 0 #endif /* js_config_h___ */ diff --git a/external/spidermonkey/include/ios/js.msg b/external/spidermonkey/include/ios/js.msg index 3e57bdf174..3f665d8d54 100644 --- a/external/spidermonkey/include/ios/js.msg +++ b/external/spidermonkey/include/ios/js.msg @@ -184,7 +184,7 @@ MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} oper MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id") MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error") -MSG_DEF(JSMSG_UNUSED134, 134, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 134, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent") MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory") @@ -193,10 +193,10 @@ MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many paren MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment") MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_UNUSED143, 143, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 143, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_UNUSED146, 146, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 146, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses") @@ -220,7 +220,7 @@ MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot ind MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals") MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_UNUSED170, 170, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 170, 0, JSEXN_RANGEERR, "repeat count must be non-negative") MSG_DEF(JSMSG_UNUSED171, 171, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED172, 172, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED173, 173, 0, JSEXN_NONE, "") @@ -286,7 +286,7 @@ MSG_DEF(JSMSG_DEPRECATED_OCTAL, 232, 0, JSEXN_SYNTAXERR, "octal literals a MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated") +MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "can't assign to {0} in strict mode") MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 238, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 239, 1, JSEXN_TYPEERR, "{0} is not extensible") @@ -313,16 +313,16 @@ MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 259, 0, JSEXN_TYPEERR, "can't change ob MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 260, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 261, 0, JSEXN_TYPEERR, "unsupported type for structured data") MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive object") -MSG_DEF(JSMSG_UNUSED263, 263, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 263, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee") MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version") MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_UNUSED266, 266, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 266, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function") MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer") MSG_DEF(JSMSG_CLEARED_SCOPE, 269, 0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope") MSG_DEF(JSMSG_MALFORMED_ESCAPE, 270, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") MSG_DEF(JSMSG_BAD_GENEXP_BODY, 271, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_UNUSED272, 272, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_YIELD_WITHOUT_OPERAND, 272, 0, JSEXN_SYNTAXERR, "yield without a value is deprecated, and illegal in ES6 (use 'yield undefined' instead)") MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 273, 0, JSEXN_SYNTAXERR, "function statement requires a name") MSG_DEF(JSMSG_CCW_REQUIRED, 274, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 275, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") @@ -391,12 +391,21 @@ MSG_DEF(JSMSG_DATE_NOT_FINITE, 337, 0, JSEXN_RANGEERR, "date value is not MSG_DEF(JSMSG_MODULE_STATEMENT, 338, 0, JSEXN_SYNTAXERR, "module declarations may only appear at the top level of a program or module body") MSG_DEF(JSMSG_CURLY_BEFORE_MODULE, 339, 0, JSEXN_SYNTAXERR, "missing { before module body") MSG_DEF(JSMSG_CURLY_AFTER_MODULE, 340, 0, JSEXN_SYNTAXERR, "missing } after module body") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "'use asm' directive only works on function code") +MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 342, 1, JSEXN_TYPEERR, "asm.js type error: {0}") MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 343, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 0, JSEXN_ERR, "successfully compiled asm.js code") +MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 1, JSEXN_ERR, "successfully compiled asm.js code ({0})") MSG_DEF(JSMSG_BAD_ARROW_ARGS, 345, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") MSG_DEF(JSMSG_YIELD_IN_ARROW, 346, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") MSG_DEF(JSMSG_WRONG_VALUE, 347, 2, JSEXN_ERR, "expected {0} but found {1}") MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, 348, 1, JSEXN_ERR, "target for index {0} is not an integer") MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME,349, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") +MSG_DEF(JSMSG_DEPRECATED_SOURCE_MAP, 350, 0, JSEXN_SYNTAXERR, "Using //@ to indicate source map URL pragmas is deprecated. Use //# instead") +MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN, 351, 1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment") +MSG_DEF(JSMSG_BINARYDATA_ARRAYTYPE_BAD_ARGS, 352, 0, JSEXN_ERR, "Invalid arguments") +MSG_DEF(JSMSG_BINARYDATA_BINARYARRAY_BAD_INDEX, 353, 0, JSEXN_RANGEERR, "invalid or out-of-range index") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_ARGS, 354, 0, JSEXN_RANGEERR, "invalid field descriptor") +MSG_DEF(JSMSG_BINARYDATA_NOT_BINARYSTRUCT, 355, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct") +MSG_DEF(JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor") diff --git a/external/spidermonkey/include/ios/js/Anchor.h b/external/spidermonkey/include/ios/js/Anchor.h index d0c2476cf7..0d458e6fb6 100644 --- a/external/spidermonkey/include/ios/js/Anchor.h +++ b/external/spidermonkey/include/ios/js/Anchor.h @@ -6,8 +6,8 @@ /* JS::Anchor implementation. */ -#ifndef js_Anchor_h___ -#define js_Anchor_h___ +#ifndef js_Anchor_h +#define js_Anchor_h #include "mozilla/Attributes.h" @@ -159,4 +159,4 @@ inline Anchor::~Anchor() } // namespace JS -#endif /* js_Anchor_h___ */ +#endif /* js_Anchor_h */ diff --git a/external/spidermonkey/include/ios/js/CallArgs.h b/external/spidermonkey/include/ios/js/CallArgs.h index af78fde0a0..8027ffc71a 100644 --- a/external/spidermonkey/include/ios/js/CallArgs.h +++ b/external/spidermonkey/include/ios/js/CallArgs.h @@ -26,11 +26,12 @@ * methods' implementations, potentially under time pressure. */ -#ifndef js_CallArgs_h___ -#define js_CallArgs_h___ +#ifndef js_CallArgs_h +#define js_CallArgs_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/TypeTraits.h" #include "jstypes.h" @@ -44,6 +45,29 @@ class JSObject; typedef JSBool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp); +/* Typedef for native functions that may be called in parallel. */ +typedef js::ParallelResult +(* JSParallelNative)(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + +/* + * Typedef for native functions that may be called either in parallel or + * sequential execution. + */ +typedef JSBool +(* JSThreadSafeNative)(js::ThreadSafeContext *cx, unsigned argc, JS::Value *vp); + +/* + * Convenience wrappers for passing in ThreadSafeNative to places that expect + * a JSNative or a JSParallelNative. + */ +template +inline JSBool +JSNativeThreadSafeWrapper(JSContext *cx, unsigned argc, JS::Value *vp); + +template +inline js::ParallelResult +JSParallelNativeThreadSafeWrapper(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + /* * Compute |this| for the |vp| inside a JSNative, either boxing primitives or * replacing with the global object as necessary. @@ -58,6 +82,8 @@ JS_ComputeThis(JSContext *cx, JS::Value *vp); namespace JS { +extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; + /* * JS::CallReceiver encapsulates access to the callee, |this|, and eventual * return value for a function call. The principal way to create a @@ -92,30 +118,55 @@ namespace JS { * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallReceiver + +namespace detail { + +#ifdef DEBUG +extern JS_PUBLIC_API(void) +CheckIsValidConstructible(Value v); +#endif + +enum UsedRval { IncludeUsedRval, NoUsedRval }; + +template +class MOZ_STACK_CLASS UsedRvalBase; + +template<> +class MOZ_STACK_CLASS UsedRvalBase { protected: -#ifdef DEBUG mutable bool usedRval_; void setUsedRval() const { usedRval_ = true; } void clearUsedRval() const { usedRval_ = false; } -#else +}; + +template<> +class MOZ_STACK_CLASS UsedRvalBase +{ + protected: void setUsedRval() const {} void clearUsedRval() const {} +}; + +template +class MOZ_STACK_CLASS CallReceiverBase : public UsedRvalBase< +#ifdef DEBUG + WantUsedRval +#else + NoUsedRval #endif - + > +{ + protected: Value *argv_; - friend CallReceiver CallReceiverFromVp(Value *vp); - friend CallReceiver CallReceiverFromArgv(Value *argv); - public: /* * Returns the function being called, as an object. Must not be called * after rval() has been used! */ JSObject &callee() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return argv_[-2].toObject(); } @@ -124,7 +175,7 @@ class MOZ_STACK_CLASS CallReceiver * rval() has been used! */ HandleValue calleev() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return HandleValue::fromMarkedLocation(&argv_[-2]); } @@ -148,6 +199,14 @@ class MOZ_STACK_CLASS CallReceiver return JS_ComputeThis(cx, base()); } + bool isConstructing() const { +#ifdef DEBUG + if (this->usedRval_) + CheckIsValidConstructible(calleev()); +#endif + return argv_[-1].isMagic(); + } + /* * Returns the currently-set return value. The initial contents of this * value are unspecified. Once this method has been called, callee() and @@ -160,7 +219,7 @@ class MOZ_STACK_CLASS CallReceiver * fails. */ MutableHandleValue rval() const { - setUsedRval(); + this->setUsedRval(); return MutableHandleValue::fromMarkedLocation(&argv_[-2]); } @@ -171,7 +230,7 @@ class MOZ_STACK_CLASS CallReceiver Value *base() const { return argv_ - 2; } Value *spAfterCall() const { - setUsedRval(); + this->setUsedRval(); return argv_ - 1; } @@ -181,7 +240,7 @@ class MOZ_STACK_CLASS CallReceiver // it. You probably don't want to use these! void setCallee(Value aCalleev) const { - clearUsedRval(); + this->clearUsedRval(); argv_[-2] = aCalleev; } @@ -194,6 +253,15 @@ class MOZ_STACK_CLASS CallReceiver } }; +} // namespace detail + +class MOZ_STACK_CLASS CallReceiver : public detail::CallReceiverBase +{ + private: + friend CallReceiver CallReceiverFromVp(Value *vp); + friend CallReceiver CallReceiverFromArgv(Value *argv); +}; + MOZ_ALWAYS_INLINE CallReceiver CallReceiverFromArgv(Value *argv) { @@ -233,11 +301,59 @@ CallReceiverFromVp(Value *vp) * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallArgs : public CallReceiver +namespace detail { + +template +class MOZ_STACK_CLASS CallArgsBase : + public mozilla::Conditional >::Type { protected: unsigned argc_; + public: + /* Returns the number of arguments. */ + unsigned length() const { return argc_; } + + /* Returns the i-th zero-indexed argument. */ + MutableHandleValue operator[](unsigned i) const { + MOZ_ASSERT(i < argc_); + return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); + } + + /* + * Returns the i-th zero-indexed argument, or |undefined| if there's no + * such argument. + */ + HandleValue get(unsigned i) const { + return i < length() + ? HandleValue::fromMarkedLocation(&this->argv_[i]) + : UndefinedHandleValue; + } + + /* + * Returns true if the i-th zero-indexed argument is present and is not + * |undefined|. + */ + bool hasDefined(unsigned i) const { + return i < argc_ && !this->argv_[i].isUndefined(); + } + + public: + // These methods are publicly exposed, but we're less sure of the interface + // here than we'd like (because they're hackish and drop assertions). Try + // to avoid using these if you can. + + Value *array() const { return this->argv_; } + Value *end() const { return this->argv_ + argc_; } +}; + +} // namespace detail + +class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase +{ + private: friend CallArgs CallArgsFromVp(unsigned argc, Value *vp); friend CallArgs CallArgsFromSp(unsigned argc, Value *sp); @@ -249,45 +365,6 @@ class MOZ_STACK_CLASS CallArgs : public CallReceiver return args; } - public: - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - Value &operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return argv_[i]; - } - - /* Returns a mutable handle for the i-th zero-indexed argument. */ - MutableHandleValue handleAt(unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - Value get(unsigned i) const { - return i < length() ? argv_[i] : UndefinedValue(); - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !argv_[i].isUndefined(); - } - - public: - // These methods are publicly exposed, but we're less sure of the interface - // here than we'd like (because they're hackish and drop assertions). Try - // to avoid using these if you can. - - Value *array() const { return argv_; } - Value *end() const { return argv_ + argc_; } }; MOZ_ALWAYS_INLINE CallArgs @@ -345,4 +422,4 @@ JS_THIS(JSContext *cx, JS::Value *vp) */ #define JS_THIS_VALUE(cx,vp) ((vp)[1]) -#endif /* js_CallArgs_h___ */ +#endif /* js_CallArgs_h */ diff --git a/external/spidermonkey/include/ios/js/CharacterEncoding.h b/external/spidermonkey/include/ios/js/CharacterEncoding.h index 63e5cc6650..e88e08e1be 100644 --- a/external/spidermonkey/include/ios/js/CharacterEncoding.h +++ b/external/spidermonkey/include/ios/js/CharacterEncoding.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_CharacterEncoding_h___ -#define js_CharacterEncoding_h___ +#ifndef js_CharacterEncoding_h +#define js_CharacterEncoding_h #include "mozilla/Range.h" @@ -58,6 +58,20 @@ class Latin1CharsZ : public mozilla::RangedPtr char *c_str() { return reinterpret_cast(get()); } }; +class UTF8Chars : public mozilla::Range +{ + typedef mozilla::Range Base; + + public: + UTF8Chars() : Base() {} + UTF8Chars(char *aBytes, size_t aLength) + : Base(reinterpret_cast(aBytes), aLength) + {} + UTF8Chars(const char *aBytes, size_t aLength) + : Base(reinterpret_cast(const_cast(aBytes)), aLength) + {} +}; + /* * SpiderMonkey also deals directly with UTF-8 encoded text in some places. */ @@ -124,10 +138,12 @@ class TwoByteCharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: + TwoByteCharsZ() : Base(NULL, 0) {} + TwoByteCharsZ(jschar *chars, size_t length) : Base(chars, length) { - JS_ASSERT(chars[length] = '\0'); + JS_ASSERT(chars[length] == '\0'); } }; @@ -142,14 +158,34 @@ class TwoByteCharsZ : public mozilla::RangedPtr * This method cannot trigger GC. */ extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars); +LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); extern UTF8CharsZ -TwoByteCharsToNewUTF8CharsZ(JSContext *cx, TwoByteChars tbchars); +TwoByteCharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); + +uint32_t +Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length); + +/* + * Inflate bytes in UTF-8 encoding to jschars. + * - On error, returns an empty TwoByteCharsZ. + * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold + * its length; the length value excludes the trailing null. + */ +extern TwoByteCharsZ +UTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); + +/* + * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters + * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 + * input. + */ +extern TwoByteCharsZ +LossyUTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); } // namespace JS inline void JS_free(JS::Latin1CharsZ &ptr) { js_free((void*)ptr.get()); } inline void JS_free(JS::UTF8CharsZ &ptr) { js_free((void*)ptr.get()); } -#endif // js_CharacterEncoding_h___ +#endif /* js_CharacterEncoding_h */ diff --git a/external/spidermonkey/include/ios/js/Date.h b/external/spidermonkey/include/ios/js/Date.h index 7ca961e30a..6199f9eca5 100644 --- a/external/spidermonkey/include/ios/js/Date.h +++ b/external/spidermonkey/include/ios/js/Date.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_Date_h___ -#define js_Date_h___ +#ifndef js_Date_h +#define js_Date_h #include "jstypes.h" @@ -32,4 +32,4 @@ DayFromTime(double time); } // namespace JS -#endif /* js_Date_h___ */ +#endif /* js_Date_h */ diff --git a/external/spidermonkey/include/ios/js/GCAPI.h b/external/spidermonkey/include/ios/js/GCAPI.h index 1b0036116c..a9bef77c09 100644 --- a/external/spidermonkey/include/ios/js/GCAPI.h +++ b/external/spidermonkey/include/ios/js/GCAPI.h @@ -4,10 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_gc_api_h___ -#define js_gc_api_h___ +#ifndef js_GCAPI_h +#define js_GCAPI_h -#include "HeapAPI.h" +#include "js/HeapAPI.h" namespace JS { @@ -181,6 +181,9 @@ DisableIncrementalGC(JSRuntime *rt); extern JS_FRIEND_API(void) DisableGenerationalGC(JSRuntime *rt); +extern JS_FRIEND_API(void) +EnableGenerationalGC(JSRuntime *rt); + extern JS_FRIEND_API(bool) IsIncrementalBarrierNeeded(JSRuntime *rt); @@ -205,7 +208,7 @@ WasIncrementalGC(JSRuntime *rt); class ObjectPtr { - JSObject *value; + Heap value; public: ObjectPtr() : value(NULL) {} @@ -240,7 +243,7 @@ class ObjectPtr } void trace(JSTracer *trc, const char *name) { - JS_CallObjectTracer(trc, &value, name); + JS_CallHeapObjectTracer(trc, &value, name); } JSObject &operator*() const { return *value; } @@ -291,4 +294,4 @@ ExposeValueToActiveJS(const Value &v) } /* namespace JS */ -#endif /* js_gc_api_h___ */ +#endif /* js_GCAPI_h */ diff --git a/external/spidermonkey/include/ios/js/HashTable.h b/external/spidermonkey/include/ios/js/HashTable.h index 3402bfbff4..aa05b71472 100644 --- a/external/spidermonkey/include/ios/js/HashTable.h +++ b/external/spidermonkey/include/ios/js/HashTable.h @@ -4,17 +4,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_HashTable_h__ -#define js_HashTable_h__ +#ifndef js_HashTable_h +#define js_HashTable_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" #include "mozilla/PodOperations.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" #include "mozilla/Util.h" -#include "js/TemplateLib.h" #include "js/Utility.h" namespace js { @@ -68,15 +72,7 @@ class HashMap // HashMap construction is fallible (due to OOM); thus the user must call // init after constructing a HashMap and check the return value. - HashMap(AllocPolicy a = AllocPolicy()) - : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Key type must be relocatable"); - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Value type must be relocatable"); - } - + HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -142,18 +138,18 @@ class HashMap template bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } bool add(AddPtr &p, const Key &k) { Entry e(k, Value()); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } template bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.relookupOrAdd(p, k, Move(e)); + return impl.relookupOrAdd(p, k, mozilla::Move(e)); } // |all()| returns a Range containing |count()| elements. E.g.: @@ -203,10 +199,10 @@ class HashMap // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -235,7 +231,7 @@ class HashMap template bool putNew(const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.putNew(k, Move(e)); + return impl.putNew(k, mozilla::Move(e)); } // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. @@ -253,9 +249,17 @@ class HashMap remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const Key &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashMap is movable - HashMap(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashMap(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashMap is not copyable or assignable @@ -303,11 +307,7 @@ class HashSet // HashSet construction is fallible (due to OOM); thus the user must call // init after constructing a HashSet and check the return value. - HashSet(AllocPolicy a = AllocPolicy()) : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Set element type must be relocatable"); - } + HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -411,10 +411,10 @@ class HashSet // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -448,9 +448,17 @@ class HashSet remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const T &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashSet is movable - HashSet(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashSet(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashSet is not copyable or assignable @@ -532,7 +540,7 @@ struct DefaultHasher // Specialize hashing policy for pointer types. It assumes that the type is // at least word-aligned. For types with smaller size use PointerHasher. template -struct DefaultHasher : PointerHasher::result> +struct DefaultHasher : PointerHasher::value> {}; // For doubles, we can xor the two uint32s. @@ -542,18 +550,11 @@ struct DefaultHasher typedef double Lookup; static HashNumber hash(double d) { JS_STATIC_ASSERT(sizeof(HashNumber) == 4); - union { - struct { - uint32_t lo; - uint32_t hi; - } s; - double d; - } u; - u.d = d; - return u.s.lo ^ u.s.hi; + uint64_t u = mozilla::BitwiseCast(d); + return HashNumber(u ^ (u >> 32)); } static bool match(double lhs, double rhs) { - return lhs == rhs; + return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); } }; @@ -577,8 +578,8 @@ class HashMapEntry template HashMapEntry(const KeyInput &k, const ValueInput &v) : key(k), value(v) {} - HashMapEntry(MoveRef rhs) - : key(Move(rhs->key)), value(Move(rhs->value)) { } + HashMapEntry(mozilla::MoveRef rhs) + : key(mozilla::Move(rhs->key)), value(mozilla::Move(rhs->value)) { } typedef Key KeyType; typedef Value ValueType; @@ -647,8 +648,8 @@ class HashTableEntry } void swap(HashTableEntry *other) { - Swap(keyHash, other->keyHash); - Swap(mem, other->mem); + mozilla::Swap(keyHash, other->keyHash); + mozilla::Swap(mem, other->mem); } T &get() { JS_ASSERT(isLive()); return *mem.addr(); } @@ -807,10 +808,7 @@ class HashTable : private AllocPolicy // a new key at the new Lookup position. |front()| is invalid after // this operation until the next call to |popFront()|. void rekeyFront(const Lookup &l, const Key &k) { - typename HashTableEntry::NonConstT t(Move(this->cur->get())); - HashPolicy::setKey(t, const_cast(k)); - table.remove(*this->cur); - table.putNewInfallible(l, Move(t)); + table.rekey(*this->cur, l, k); rekeyed = true; this->validEntry = false; } @@ -832,13 +830,13 @@ class HashTable : private AllocPolicy }; // HashTable is movable - HashTable(MoveRef rhs) + HashTable(mozilla::MoveRef rhs) : AllocPolicy(*rhs) { mozilla::PodAssign(this, &*rhs); rhs->table = NULL; } - void operator=(MoveRef rhs) { + void operator=(mozilla::MoveRef rhs) { if (table) destroyTable(*this, table, capacity()); mozilla::PodAssign(this, &*rhs); @@ -882,7 +880,7 @@ class HashTable : private AllocPolicy # define METER(x) #endif - friend class js::ReentrancyGuard; + friend class mozilla::ReentrancyGuard; mutable mozilla::DebugOnly entered; mozilla::DebugOnly mutationCount; @@ -892,7 +890,7 @@ class HashTable : private AllocPolicy static const unsigned sMinCapacity = 1 << sMinCapacityLog2; static const unsigned sMaxInit = JS_BIT(23); static const unsigned sMaxCapacity = JS_BIT(24); - static const unsigned sHashBits = tl::BitSize::result; + static const unsigned sHashBits = mozilla::tl::BitSize::value; static const uint8_t sMinAlphaFrac = 64; // (0x100 * .25) static const uint8_t sMaxAlphaFrac = 192; // (0x100 * .75) static const uint8_t sInvMaxAlpha = 171; // (ceil(0x100 / .75) >> 1) @@ -1165,7 +1163,7 @@ class HashTable : private AllocPolicy for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) { if (src->isLive()) { HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive(hn, Move(src->get())); + findFreeEntry(hn).setLive(hn, mozilla::Move(src->get())); src->destroy(); } } @@ -1346,19 +1344,19 @@ class HashTable : private AllocPolicy return gen; } - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(table); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); } Ptr lookup(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); return Ptr(lookup(l, keyHash, 0)); } @@ -1371,7 +1369,7 @@ class HashTable : private AllocPolicy AddPtr lookupForAdd(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); Entry &entry = lookup(l, keyHash, sCollisionBit); AddPtr p(entry, keyHash); @@ -1382,7 +1380,7 @@ class HashTable : private AllocPolicy template bool add(AddPtr &p, const U &rhs) { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(mutationCount == p.mutationCount); JS_ASSERT(table); JS_ASSERT(!p.found()); @@ -1443,7 +1441,7 @@ class HashTable : private AllocPolicy { p.mutationCount = mutationCount; { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); p.entry_ = &lookup(l, p.keyHash, sCollisionBit); } return p.found() || add(p, u); @@ -1452,17 +1450,27 @@ class HashTable : private AllocPolicy void remove(Ptr p) { JS_ASSERT(table); - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(p.found()); remove(*p.entry_); checkUnderloaded(); } + void rekey(Ptr p, const Lookup &l, const Key &k) + { + JS_ASSERT(table); + mozilla::ReentrancyGuard g(*this); + JS_ASSERT(p.found()); + typename HashTableEntry::NonConstT t(mozilla::Move(*p)); + HashPolicy::setKey(t, const_cast(k)); + remove(*p.entry_); + putNewInfallible(l, mozilla::Move(t)); + } + #undef METER }; } // namespace detail } // namespace js -#endif // js_HashTable_h__ - +#endif /* js_HashTable_h */ diff --git a/external/spidermonkey/include/ios/js/HeapAPI.h b/external/spidermonkey/include/ios/js/HeapAPI.h index f0f4411ac9..4d739304bc 100644 --- a/external/spidermonkey/include/ios/js/HeapAPI.h +++ b/external/spidermonkey/include/ios/js/HeapAPI.h @@ -4,33 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_heap_api_h___ -#define js_heap_api_h___ +#ifndef js_HeapAPI_h +#define js_HeapAPI_h #include "jspubtd.h" +#include "js/Utility.h" + /* These values are private to the JS engine. */ namespace js { namespace gc { -/* - * Page size must be static to support our arena pointer optimizations, so we - * are forced to support each platform with non-4096 pages as a special case. - * Note: The freelist supports a maximum arena shift of 15. - * Note: Do not use JS_CPU_SPARC here, this header is used outside JS. - */ -#if (defined(SOLARIS) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ - (defined(__sparc) || defined(__sparcv9) || defined(__ia64)) -const size_t PageShift = 13; -const size_t ArenaShift = PageShift; -#elif defined(__powerpc64__) -const size_t PageShift = 16; const size_t ArenaShift = 12; -#else -const size_t PageShift = 12; -const size_t ArenaShift = PageShift; -#endif -const size_t PageSize = size_t(1) << PageShift; const size_t ArenaSize = size_t(1) << ArenaShift; const size_t ArenaMask = ArenaSize - 1; @@ -67,7 +52,7 @@ namespace shadow { struct ArenaHeader { - js::Zone *zone; + JS::Zone *zone; }; struct Zone @@ -153,10 +138,10 @@ IsIncrementalBarrierNeededOnGCThing(shadow::Runtime *rt, void *thing, JSGCTraceK { if (!rt->needsBarrier_) return false; - js::Zone *zone = GetGCThingZone(thing); + JS::Zone *zone = GetGCThingZone(thing); return reinterpret_cast(zone)->needsBarrier_; } } /* namespace JS */ -#endif /* js_heap_api_h___ */ +#endif /* js_HeapAPI_h */ diff --git a/external/spidermonkey/include/ios/js/LegacyIntTypes.h b/external/spidermonkey/include/ios/js/LegacyIntTypes.h index 387a68b9e9..2c8498c89e 100644 --- a/external/spidermonkey/include/ios/js/LegacyIntTypes.h +++ b/external/spidermonkey/include/ios/js/LegacyIntTypes.h @@ -17,13 +17,12 @@ * Indeed, if you use this header and third-party code defining these * types, *expect* to encounter either compile errors or link errors, * depending how these types are used and on the order of inclusion. - * It is safest to use only the JSAPI -style types, - * customizing those types using MOZ_CUSTOM_STDINT_H if necessary. + * It is safest to use only the types. */ -#ifndef PROTYPES_H -#define PROTYPES_H +#ifndef js_LegacyIntTypes_h +#define js_LegacyIntTypes_h -#include "mozilla/StandardInteger.h" +#include #include "js-config.h" @@ -57,4 +56,4 @@ typedef int16_t JSInt16; typedef int32_t JSInt32; typedef int64_t JSInt64; -#endif /* !defined(PROTYPES_H) */ +#endif /* js_LegacyIntTypes_h */ diff --git a/external/spidermonkey/include/ios/js/MemoryMetrics.h b/external/spidermonkey/include/ios/js/MemoryMetrics.h index 7e84f2ae11..ed61e1c427 100644 --- a/external/spidermonkey/include/ios/js/MemoryMetrics.h +++ b/external/spidermonkey/include/ios/js/MemoryMetrics.h @@ -10,6 +10,8 @@ // These declarations are not within jsapi.h because they are highly likely to // change in the future. Depend on them at your own risk. +#include "mozilla/MemoryReporting.h" + #include #include "jsalloc.h" @@ -91,7 +93,6 @@ struct TypeInferenceSizes // Data for tracking JIT-code memory usage. struct CodeSizes { - size_t jaeger; size_t ion; size_t asmJS; size_t baseline; @@ -136,7 +137,7 @@ struct RuntimeSizes size_t dtoa; size_t temporary; size_t regexpData; - size_t stack; + size_t interpreterStack; size_t gcMarker; size_t mathCache; size_t scriptData; @@ -153,9 +154,11 @@ struct ZoneStats gcHeapUnusedGcThings(0), gcHeapStringsNormal(0), gcHeapStringsShort(0), + gcHeapLazyScripts(0), gcHeapTypeObjects(0), gcHeapIonCodes(0), stringCharsNonHuge(0), + lazyScripts(0), typeObjects(0), typePool(0), hugeStrings() @@ -167,14 +170,16 @@ struct ZoneStats gcHeapUnusedGcThings(other.gcHeapUnusedGcThings), gcHeapStringsNormal(other.gcHeapStringsNormal), gcHeapStringsShort(other.gcHeapStringsShort), + gcHeapLazyScripts(other.gcHeapLazyScripts), gcHeapTypeObjects(other.gcHeapTypeObjects), gcHeapIonCodes(other.gcHeapIonCodes), stringCharsNonHuge(other.stringCharsNonHuge), + lazyScripts(other.lazyScripts), typeObjects(other.typeObjects), typePool(other.typePool), hugeStrings() { - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // Add other's numbers to this object's numbers. @@ -186,16 +191,18 @@ struct ZoneStats ADD(gcHeapStringsNormal); ADD(gcHeapStringsShort); + ADD(gcHeapLazyScripts); ADD(gcHeapTypeObjects); ADD(gcHeapIonCodes); ADD(stringCharsNonHuge); + ADD(lazyScripts); ADD(typeObjects); ADD(typePool); #undef ADD - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // This field can be used by embedders. @@ -207,10 +214,12 @@ struct ZoneStats size_t gcHeapStringsNormal; size_t gcHeapStringsShort; + size_t gcHeapLazyScripts; size_t gcHeapTypeObjects; size_t gcHeapIonCodes; size_t stringCharsNonHuge; + size_t lazyScripts; size_t typeObjects; size_t typePool; @@ -241,7 +250,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(0), shapesCompartmentTables(0), scriptData(0), - jaegerData(0), baselineData(0), baselineStubsFallback(0), baselineStubsOptimized(0), @@ -271,7 +279,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids), shapesCompartmentTables(other.shapesCompartmentTables), scriptData(other.scriptData), - jaegerData(other.jaegerData), baselineData(other.baselineData), baselineStubsFallback(other.baselineStubsFallback), baselineStubsOptimized(other.baselineStubsOptimized), @@ -306,7 +313,6 @@ struct CompartmentStats size_t shapesExtraTreeShapeKids; size_t shapesCompartmentTables; size_t scriptData; - size_t jaegerData; size_t baselineData; size_t baselineStubsFallback; size_t baselineStubsOptimized; @@ -339,7 +345,6 @@ struct CompartmentStats ADD(shapesExtraTreeShapeKids); ADD(shapesCompartmentTables); ADD(scriptData); - ADD(jaegerData); ADD(baselineData); ADD(baselineStubsFallback); ADD(baselineStubsOptimized); @@ -360,7 +365,7 @@ struct CompartmentStats struct RuntimeStats { - RuntimeStats(JSMallocSizeOfFun mallocSizeOf) + RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) : runtime(), gcHeapChunkTotal(0), gcHeapDecommittedArenas(0), @@ -417,7 +422,7 @@ struct RuntimeStats ZoneStats *currZoneStats; - JSMallocSizeOfFun mallocSizeOf_; + mozilla::MallocSizeOf mallocSizeOf_; virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0; virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0; @@ -454,4 +459,4 @@ PeakSizeOfTemporary(const JSRuntime *rt); } // namespace JS -#endif // js_MemoryMetrics_h +#endif /* js_MemoryMetrics_h */ diff --git a/external/spidermonkey/include/ios/js/PropertyKey.h b/external/spidermonkey/include/ios/js/PropertyKey.h index 53158c26f3..c949db13a5 100644 --- a/external/spidermonkey/include/ios/js/PropertyKey.h +++ b/external/spidermonkey/include/ios/js/PropertyKey.h @@ -6,8 +6,8 @@ /* JS::PropertyKey implementation. */ -#ifndef js_PropertyKey_h___ -#define js_PropertyKey_h___ +#ifndef js_PropertyKey_h +#define js_PropertyKey_h #include "mozilla/Attributes.h" @@ -95,4 +95,4 @@ ToPropertyKey(JSContext *cx, HandleValue v, PropertyKey *key) } // namespace JS -#endif /* js_PropertyKey_h___ */ +#endif /* js_PropertyKey_h */ diff --git a/external/spidermonkey/include/ios/js/RequiredDefines.h b/external/spidermonkey/include/ios/js/RequiredDefines.h index 2be2efbf9a..6af9ca871b 100644 --- a/external/spidermonkey/include/ios/js/RequiredDefines.h +++ b/external/spidermonkey/include/ios/js/RequiredDefines.h @@ -10,8 +10,8 @@ * or SpiderMonkey public headers may not work correctly. */ -#ifndef js_RequiredDefines_h___ -#define js_RequiredDefines_h___ +#ifndef js_RequiredDefines_h +#define js_RequiredDefines_h /* * The c99 defining the limit macros (UINT32_MAX for example), says: @@ -20,4 +20,4 @@ */ #define __STDC_LIMIT_MACROS -#endif /* js_RequiredDefines_h___ */ +#endif /* js_RequiredDefines_h */ diff --git a/external/spidermonkey/include/ios/js/RootingAPI.h b/external/spidermonkey/include/ios/js/RootingAPI.h index 3e2e0d2a7c..99295f1238 100644 --- a/external/spidermonkey/include/ios/js/RootingAPI.h +++ b/external/spidermonkey/include/ios/js/RootingAPI.h @@ -4,14 +4,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsgc_root_h__ -#define jsgc_root_h__ +#ifndef js_RootingAPI_h +#define js_RootingAPI_h #include "mozilla/GuardObjects.h" #include "mozilla/TypeTraits.h" #include "js/Utility.h" -#include "js/TemplateLib.h" #include "jspubtd.h" @@ -99,9 +98,10 @@ namespace js { class Module; +class ScriptSourceObject; template -struct RootMethods {}; +struct GCMethods {}; template class RootedBase {}; @@ -112,6 +112,9 @@ class HandleBase {}; template class MutableHandleBase {}; +template +class HeapBase {}; + /* * js::NullPtr acts like a NULL pointer in contexts that require a Handle. * @@ -130,6 +133,10 @@ struct NullPtr static void * const constNullValue; }; +namespace gc { +struct Cell; +} /* namespace gc */ + } /* namespace js */ namespace JS { @@ -161,6 +168,204 @@ struct JS_PUBLIC_API(NullPtr) static void * const constNullValue; }; +/* + * The Heap class is a C/C++ heap-stored reference to a JS GC thing. All + * members of heap classes that refer to GC thing should use Heap (or + * possibly TenuredHeap, described below). + * + * Heap wraps the complex mechanisms required to ensure GC safety for the + * contained reference into a C++ class that behaves similarly to a normal + * pointer. + * + * GC references stored on the C/C++ stack must use Rooted/Handle/MutableHandle + * instead. + * + * Requirements for type T: + * - Must be one of: Value, jsid, JSObject*, JSString*, JSScript* + */ +template +class Heap : public js::HeapBase +{ + public: + Heap() { + static_assert(sizeof(T) == sizeof(Heap), + "Heap must be binary compatible with T."); + init(js::GCMethods::initial()); + } + explicit Heap(T p) { init(p); } + explicit Heap(const Heap &p) { init(p.ptr); } + + ~Heap() { + if (js::GCMethods::needsPostBarrier(ptr)) + relocate(); + } + + bool operator==(const Heap &other) { return ptr == other.ptr; } + bool operator!=(const Heap &other) { return ptr != other.ptr; } + + bool operator==(const T &other) const { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + + operator T() const { return ptr; } + T operator->() const { return ptr; } + const T *address() const { return &ptr; } + const T &get() const { return ptr; } + + T *unsafeGet() { return &ptr; } + + Heap &operator=(T p) { + set(p); + return *this; + } + + void set(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (js::GCMethods::needsPostBarrier(newPtr)) { + ptr = newPtr; + post(); + } else if (js::GCMethods::needsPostBarrier(ptr)) { + relocate(); /* Called before overwriting ptr. */ + ptr = newPtr; + } else { + ptr = newPtr; + } + } + + private: + void init(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + ptr = newPtr; + if (js::GCMethods::needsPostBarrier(ptr)) + post(); + } + + void post() { +#ifdef JSGC_GENERATIONAL + JS_ASSERT(js::GCMethods::needsPostBarrier(ptr)); + js::GCMethods::postBarrier(&ptr); +#endif + } + + void relocate() { +#ifdef JSGC_GENERATIONAL + js::GCMethods::relocate(&ptr); +#endif + } + + T ptr; +}; + +#ifdef DEBUG +/* + * For generational GC, assert that an object is in the tenured generation as + * opposed to being in the nursery. + */ +extern JS_FRIEND_API(void) +AssertGCThingMustBeTenured(JSObject* obj); +#else +inline void +AssertGCThingMustBeTenured(JSObject *obj) {} +#endif + +/* + * The TenuredHeap class is similar to the Heap class above in that it + * encapsulates the GC concerns of an on-heap reference to a JS object. However, + * it has two important differences: + * + * 1) Pointers which are statically known to only reference "tenured" objects + * can avoid the extra overhead of SpiderMonkey's write barriers. + * + * 2) Objects in the "tenured" heap have stronger alignment restrictions than + * those in the "nursery", so it is possible to store flags in the lower + * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged + * pointer with a nice API for accessing the flag bits and adds various + * assertions to ensure that it is not mis-used. + * + * GC things are said to be "tenured" when they are located in the long-lived + * heap: e.g. they have gained tenure as an object by surviving past at least + * one GC. For performance, SpiderMonkey allocates some things which are known + * to normally be long lived directly into the tenured generation; for example, + * global objects. Additionally, SpiderMonkey does not visit individual objects + * when deleting non-tenured objects, so object with finalizers are also always + * tenured; for instance, this includes most DOM objects. + * + * The considerations to keep in mind when using a TenuredHeap vs a normal + * Heap are: + * + * - It is invalid for a TenuredHeap to refer to a non-tenured thing. + * - It is however valid for a Heap to refer to a tenured thing. + * - It is not possible to store flag bits in a Heap. + */ +template +class TenuredHeap : public js::HeapBase +{ + public: + TenuredHeap() : bits(0) { + static_assert(sizeof(T) == sizeof(TenuredHeap), + "TenuredHeap must be binary compatible with T."); + } + explicit TenuredHeap(T p) : bits(0) { setPtr(p); } + explicit TenuredHeap(const TenuredHeap &p) : bits(0) { setPtr(p.ptr); } + + bool operator==(const TenuredHeap &other) { return bits == other.bits; } + bool operator!=(const TenuredHeap &other) { return bits != other.bits; } + + void setPtr(T newPtr) { + JS_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (newPtr) + AssertGCThingMustBeTenured(newPtr); + bits = (bits & flagsMask) | reinterpret_cast(newPtr); + } + + void setFlags(uintptr_t flagsToSet) { + JS_ASSERT((flagsToSet & ~flagsMask) == 0); + bits |= flagsToSet; + } + + void unsetFlags(uintptr_t flagsToUnset) { + JS_ASSERT((flagsToUnset & ~flagsMask) == 0); + bits &= ~flagsToUnset; + } + + bool hasFlag(uintptr_t flag) const { + JS_ASSERT((flag & ~flagsMask) == 0); + return (bits & flag) != 0; + } + + T getPtr() const { return reinterpret_cast(bits & ~flagsMask); } + uintptr_t getFlags() const { return bits & flagsMask; } + + operator T() const { return getPtr(); } + T operator->() const { return getPtr(); } + + TenuredHeap &operator=(T p) { + setPtr(p); + return *this; + } + + /* + * Set the pointer to a value which will cause a crash if it is + * dereferenced. + */ + void setToCrashOnTouch() { + bits = (bits & flagsMask) | crashOnTouchPointer; + } + + bool isSetToCrashOnTouch() { + return (bits & ~flagsMask) == crashOnTouchPointer; + } + + private: + enum { + maskBits = 3, + flagsMask = (1 << maskBits) - 1, + crashOnTouchPointer = 1 << maskBits + }; + + uintptr_t bits; +}; + /* * Reference to a T that has been rooted elsewhere. This is most useful * as a parameter type, which guarantees that the T lvalue is properly @@ -170,7 +375,7 @@ struct JS_PUBLIC_API(NullPtr) * specialization, define a HandleBase specialization containing them. */ template -class MOZ_STACK_CLASS Handle : public js::HandleBase +class MOZ_NONHEAP_CLASS Handle : public js::HandleBase { friend class MutableHandle; @@ -180,20 +385,22 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase Handle(Handle handle, typename mozilla::EnableIf::value, int>::Type dummy = 0) { + static_assert(sizeof(Handle) == sizeof(T *), + "Handle must be binary compatible with T*."); ptr = reinterpret_cast(handle.address()); } /* Create a handle for a NULL pointer. */ Handle(js::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "js::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "js::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&js::NullPtr::constNullValue); } /* Create a handle for a NULL pointer. */ Handle(JS::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "JS::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "JS::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&JS::NullPtr::constNullValue); } @@ -202,11 +409,19 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase } /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. + * Take care when calling this method! * - * Create a Handle from a raw location of a T. + * This creates a Handle from the raw location of a T. + * + * It should be called only if the following conditions hold: + * + * 1) the location of the T is guaranteed to be marked (for some reason + * other than being a Rooted), e.g., if it is guaranteed to be reachable + * from an implicit root. + * + * 2) the contents of the location are immutable, or at least cannot change + * for the lifetime of the handle, as its users may not expect its value + * to change underneath them. */ static Handle fromMarkedLocation(const T *p) { Handle h; @@ -230,13 +445,17 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase typename mozilla::EnableIf::value, int>::Type dummy = 0); const T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a Handle to something that + * takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } - bool operator!=(const T &other) { return *ptr != other; } - bool operator==(const T &other) { return *ptr == other; } + bool operator!=(const T &other) const { return *ptr != other; } + bool operator==(const T &other) const { return *ptr == other; } private: Handle() {} @@ -247,13 +466,14 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase void operator=(S v) MOZ_DELETE; }; -typedef Handle HandleObject; -typedef Handle HandleModule; -typedef Handle HandleFunction; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleId; -typedef Handle HandleValue; +typedef Handle HandleObject; +typedef Handle HandleModule; +typedef Handle HandleScriptSource; +typedef Handle HandleFunction; +typedef Handle HandleScript; +typedef Handle HandleString; +typedef Handle HandleId; +typedef Handle HandleValue; /* * Similar to a handle, but the underlying storage can be changed. This is @@ -270,7 +490,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase inline MutableHandle(Rooted *root); void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -288,9 +508,13 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase } T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a MutableHandle to something that takes + * a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } private: @@ -298,8 +522,8 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase T *ptr; - template - void operator=(S v) MOZ_DELETE; + template void operator=(S v) MOZ_DELETE; + void operator=(MutableHandle other) MOZ_DELETE; }; typedef MutableHandle MutableHandleObject; @@ -309,6 +533,11 @@ typedef MutableHandle MutableHandleString; typedef MutableHandle MutableHandleId; typedef MutableHandle MutableHandleValue; +#ifdef JSGC_GENERATIONAL +JS_PUBLIC_API(void) HeapCellPostBarrier(js::gc::Cell **cellp); +JS_PUBLIC_API(void) HeapCellRelocate(js::gc::Cell **cellp); +#endif + } /* namespace JS */ namespace js { @@ -383,13 +612,28 @@ struct RootKind }; template -struct RootMethods +struct GCMethods { static T *initial() { return NULL; } static ThingRootKind kind() { return RootKind::rootKind(); } static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); } + static bool needsPostBarrier(T *v) { return v; } +#ifdef JSGC_GENERATIONAL + static void postBarrier(T **vp) { + JS::HeapCellPostBarrier(reinterpret_cast(vp)); + } + static void relocate(T **vp) { + JS::HeapCellRelocate(reinterpret_cast(vp)); + } +#endif }; +#if defined(DEBUG) +/* This helper allows us to assert that Rooted is scoped within a request. */ +extern JS_PUBLIC_API(bool) +IsInRequest(JSContext *cx); +#endif + } /* namespace js */ namespace JS { @@ -405,46 +649,63 @@ namespace JS { template class MOZ_STACK_CLASS Rooted : public js::RootedBase { - void init(JSContext *cxArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ContextFriendFields *cx = js::ContextFriendFields::get(cxArg); - commonInit(cx->thingGCRooters); -#endif - } + /* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */ + template + void init(CX *cx) { +#ifdef JSGC_TRACK_EXACT_ROOTS + js::ThingRootKind kind = js::GCMethods::kind(); + this->stack = &cx->thingGCRooters[kind]; + this->prev = *stack; + *stack = reinterpret_cast*>(this); - void init(js::PerThreadData *ptArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::PerThreadDataFriendFields *pt = js::PerThreadDataFriendFields::get(ptArg); - commonInit(pt->thingGCRooters); + JS_ASSERT(!js::GCMethods::poisoned(ptr)); #endif } public: Rooted(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - init(cx); + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); } Rooted(JSContext *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); + } + + Rooted(js::ContextFriendFields *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(cx); } - Rooted(js::PerThreadData *pt + Rooted(js::ContextFriendFields *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(cx); + } + + Rooted(js::PerThreadDataFriendFields *pt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(pt); } - Rooted(js::PerThreadData *pt, T initial + Rooted(js::PerThreadDataFriendFields *pt, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { @@ -452,18 +713,38 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase init(pt); } + Rooted(JSRuntime *rt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + + Rooted(JSRuntime *rt, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + ~Rooted() { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS JS_ASSERT(*stack == reinterpret_cast*>(this)); *stack = prev; #endif } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted *previous() { return prev; } #endif - operator T() const { return ptr; } + /* + * Important: Return a reference here so passing a Rooted to + * something that takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return ptr; } T operator->() const { return ptr; } T *address() { return &ptr; } const T *address() const { return &ptr; } @@ -471,7 +752,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!js::RootMethods::poisoned(value)); + JS_ASSERT(!js::GCMethods::poisoned(value)); ptr = value; return ptr; } @@ -481,28 +762,25 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } - - private: - void commonInit(Rooted **thingGCRooters) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ThingRootKind kind = js::RootMethods::kind(); - this->stack = &thingGCRooters[kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - - JS_ASSERT(!js::RootMethods::poisoned(ptr)); -#endif + void set(T value) { + JS_ASSERT(!js::GCMethods::poisoned(value)); + ptr = value; } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } + + private: +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted **stack, *prev; #endif #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) /* Has the rooting analysis ever scanned this Rooted's stack location? */ friend void JS::CheckStackRoots(JSContext*); +#endif + +#ifdef JSGC_ROOT_ANALYSIS bool scanned; #endif @@ -523,13 +801,14 @@ template <> class Rooted; #endif -typedef Rooted RootedObject; -typedef Rooted RootedModule; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedId; -typedef Rooted RootedValue; +typedef Rooted RootedObject; +typedef Rooted RootedModule; +typedef Rooted RootedScriptSource; +typedef Rooted RootedFunction; +typedef Rooted RootedScript; +typedef Rooted RootedString; +typedef Rooted RootedId; +typedef Rooted RootedValue; } /* namespace JS */ @@ -549,8 +828,9 @@ class SkipRoot const uint8_t *start; const uint8_t *end; - template - void init(SkipRoot **head, const T *ptr, size_t count) { + template + void init(CX *cx, const T *ptr, size_t count) { + SkipRoot **head = &cx->skipGCRooters; this->stack = head; this->prev = *stack; *stack = this; @@ -559,23 +839,6 @@ class SkipRoot } public: - template - SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(&ContextFriendFields::get(cx)->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - template - SkipRoot(js::PerThreadData *ptd, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - PerThreadDataFriendFields *ptff = PerThreadDataFriendFields::get(ptd); - init(&ptff->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~SkipRoot() { JS_ASSERT(*stack == this); *stack = prev; @@ -589,22 +852,36 @@ class SkipRoot #else /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {} + public: + +#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(ContextFriendFields::get(cx), ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } template - SkipRoot(PerThreadData *ptd, const T *ptr, size_t count = 1 + SkipRoot(ContextFriendFields *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(cx, ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } -#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + SkipRoot(PerThreadData *pt, const T *ptr, size_t count = 1 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + { + init(PerThreadDataFriendFields::get(pt), ptr, count); + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -614,15 +891,17 @@ template class FakeRooted : public RootedBase { public: - FakeRooted(JSContext *cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(RootMethods::initial()) + template + FakeRooted(CX *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } - FakeRooted(JSContext *cx, T initial - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + template + FakeRooted(CX *cx, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; @@ -636,13 +915,13 @@ class FakeRooted : public RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!RootMethods::poisoned(value)); + JS_ASSERT(!GCMethods::poisoned(value)); ptr = value; return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } private: T ptr; @@ -666,7 +945,7 @@ class FakeMutableHandle : public js::MutableHandleBase } void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -727,13 +1006,11 @@ template class MaybeRooted typedef FakeMutableHandle MutableHandleType; static inline JS::Handle toHandle(HandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::Handle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::MutableHandle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } }; @@ -761,6 +1038,8 @@ template inline MutableHandle::MutableHandle(Rooted *root) { + static_assert(sizeof(MutableHandle) == sizeof(T *), + "MutableHandle must be binary compatible with T*."); ptr = root->address(); } @@ -779,10 +1058,6 @@ inline void MaybeCheckStackRoots(JSContext *cx) #endif } -namespace gc { -struct Cell; -} /* namespace gc */ - /* Base class for automatic read-only object rooting during compilation. */ class CompilerRootNode { @@ -801,4 +1076,4 @@ class CompilerRootNode } /* namespace js */ -#endif /* jsgc_root_h___ */ +#endif /* js_RootingAPI_h */ diff --git a/external/spidermonkey/include/ios/js/TemplateLib.h b/external/spidermonkey/include/ios/js/TemplateLib.h deleted file mode 100644 index a4ff682912..0000000000 --- a/external/spidermonkey/include/ios/js/TemplateLib.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_template_lib_h__ -#define js_template_lib_h__ - -#include "jstypes.h" - -/* - * Library of reusable template meta-functions (that is, functions on types and - * compile-time values). Meta-functions are placed inside the 'tl' namespace to - * avoid conflict with non-meta functions that logically have the same name - * (e.g., js::tl::Min vs. js::Min). - */ - -namespace js { -namespace tl { - -/* Compute min/max/clamp. */ -template struct Min { - static const size_t result = i < j ? i : j; -}; -template struct Max { - static const size_t result = i > j ? i : j; -}; -template struct Clamp { - static const size_t result = i < min ? min : (i > max ? max : i); -}; - -/* Compute x^y. */ -template struct Pow { - static const size_t result = x * Pow::result; -}; -template struct Pow { - static const size_t result = 1; -}; - -/* Compute floor(log2(i)). */ -template struct FloorLog2 { - static const size_t result = 1 + FloorLog2::result; -}; -template <> struct FloorLog2<0> { /* Error */ }; -template <> struct FloorLog2<1> { static const size_t result = 0; }; - -/* Compute ceiling(log2(i)). */ -template struct CeilingLog2 { - static const size_t result = FloorLog2<2 * i - 1>::result; -}; - -/* Round up to the nearest power of 2. */ -template struct RoundUpPow2 { - static const size_t result = size_t(1) << CeilingLog2::result; -}; -template <> struct RoundUpPow2<0> { - static const size_t result = 1; -}; - -/* Compute the number of bits in the given unsigned type. */ -template struct BitSize { - static const size_t result = sizeof(T) * JS_BITS_PER_BYTE; -}; - -/* - * Produce an N-bit mask, where N <= BitSize::result. Handle the - * language-undefined edge case when N = BitSize::result. - */ -template struct NBitMask { - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |result| to assure - // its computation. - static const size_t checkPrecondition = 0 / size_t(N < BitSize::result); - static const size_t result = (size_t(1) << N) - 1 + checkPrecondition; -}; -template <> struct NBitMask::result> { - static const size_t result = size_t(-1); -}; - -/* - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template struct MulOverflowMask { - static const size_t result = - ~NBitMask::result - CeilingLog2::result>::result; -}; -template <> struct MulOverflowMask<0> { /* Error */ }; -template <> struct MulOverflowMask<1> { static const size_t result = 0; }; - -/* - * Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized - * array of T's is big enough to cause a ptrdiff_t overflow when subtracting - * a pointer to the end of the array from the beginning. - */ -template struct UnsafeRangeSizeMask { - /* - * The '2' factor means the top bit is clear, sizeof(T) converts from - * units of elements to bytes. - */ - static const size_t result = MulOverflowMask<2 * sizeof(T)>::result; -}; - -template struct If { static const T result = v1; }; -template struct If { static const T result = v2; }; - -/* - * Traits class for identifying types that are implicitly barriered. - */ -template struct IsRelocatableHeapType { static const bool result = true; }; - -} /* namespace tl */ -} /* namespace js */ - -#endif /* js_template_lib_h__ */ diff --git a/external/spidermonkey/include/ios/js/Utility.h b/external/spidermonkey/include/ios/js/Utility.h index c4ebf7ced6..9d391e5c8a 100644 --- a/external/spidermonkey/include/ios/js/Utility.h +++ b/external/spidermonkey/include/ios/js/Utility.h @@ -4,13 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_utility_h__ -#define js_utility_h__ +#ifndef js_Utility_h +#define js_Utility_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" +#include "mozilla/Move.h" #include "mozilla/Scoped.h" +#include "mozilla/TemplateLib.h" #include #include @@ -22,8 +24,6 @@ #include "jstypes.h" -#include "js/TemplateLib.h" - /* The public JS engine namespace. */ namespace JS {} @@ -41,7 +41,6 @@ namespace js {} #define JS_ASSERT(expr) MOZ_ASSERT(expr) #define JS_ASSERT_IF(cond, expr) MOZ_ASSERT_IF(cond, expr) -#define JS_NOT_REACHED(reason) MOZ_NOT_REACHED(reason) #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr) #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr) @@ -63,7 +62,7 @@ namespace js {} # define JS_DIAGNOSTICS_ASSERT(expr) ((void) 0) #endif -#define JS_STATIC_ASSERT(cond) MOZ_STATIC_ASSERT(cond, "JS_STATIC_ASSERT") +#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") #define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") extern MOZ_NORETURN JS_PUBLIC_API(void) @@ -84,10 +83,11 @@ extern JS_PUBLIC_API(void) JS_Abort(void); #else # ifdef DEBUG /* - * In order to test OOM conditions, when the shell command-line option - * |-A NUM| is passed, we fail continuously after the NUM'th allocation. + * In order to test OOM conditions, when the testing function + * oomAfterAllocations COUNT is passed, we fail continuously after the NUM'th + * allocation from now. */ -extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set from shell/js.cpp */ +extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set in builtins/TestingFunctions.cpp */ extern JS_PUBLIC_DATA(uint32_t) OOM_counter; /* data race, who cares. */ #ifdef JS_OOM_DO_BACKTRACES @@ -157,6 +157,12 @@ static JS_INLINE void* js_calloc(size_t bytes) return calloc(bytes, 1); } +static JS_INLINE void* js_calloc(size_t nmemb, size_t size) +{ + JS_OOM_POSSIBLY_FAIL(); + return calloc(nmemb, size); +} + static JS_INLINE void* js_realloc(void* p, size_t bytes) { JS_OOM_POSSIBLY_FAIL(); @@ -169,205 +175,6 @@ static JS_INLINE void js_free(void* p) } #endif/* JS_USE_CUSTOM_ALLOCATOR */ -JS_BEGIN_EXTERN_C - -/* - * Replace bit-scanning code sequences with CPU-specific instructions to - * speedup calculations of ceiling/floor log2. - * - * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129. - * - * SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856. - */ -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) - -unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); -unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward,_BitScanReverse) - -__forceinline static int -__BitScanForward32(unsigned int val) -{ - unsigned long idx; - - _BitScanForward(&idx, (unsigned long)val); - return (int)idx; -} -__forceinline static int -__BitScanReverse32(unsigned int val) -{ - unsigned long idx; - - _BitScanReverse(&idx, (unsigned long)val); - return (int)(31-idx); -} -# define js_bitscan_ctz32(val) __BitScanForward32(val) -# define js_bitscan_clz32(val) __BitScanReverse32(val) -# define JS_HAS_BUILTIN_BITSCAN32 - -#if defined(_M_AMD64) || defined(_M_X64) -unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask); -unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask); -# pragma intrinsic(_BitScanForward64,_BitScanReverse64) - -__forceinline static int -__BitScanForward64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanForward64(&idx, val); - return (int)idx; -} -__forceinline static int -__BitScanReverse64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanReverse64(&idx, val); - return (int)(63-idx); -} -# define js_bitscan_ctz64(val) __BitScanForward64(val) -# define js_bitscan_clz64(val) __BitScanReverse64(val) -# define JS_HAS_BUILTIN_BITSCAN64 -#endif -#elif MOZ_IS_GCC - -#if MOZ_GCC_VERSION_AT_LEAST(3, 4, 0) -# define USE_BUILTIN_CTZ -#endif - -#elif defined(__clang__) - -#if __has_builtin(__builtin_ctz) -# define USE_BUILTIN_CTZ -#endif - -#endif - -#if defined(USE_BUILTIN_CTZ) -# define js_bitscan_ctz32(val) __builtin_ctz(val) -# define js_bitscan_clz32(val) __builtin_clz(val) -# define JS_HAS_BUILTIN_BITSCAN32 -# if (JS_BYTES_PER_WORD == 8) -# define js_bitscan_ctz64(val) __builtin_ctzll(val) -# define js_bitscan_clz64(val) __builtin_clzll(val) -# define JS_HAS_BUILTIN_BITSCAN64 -# endif - -# undef USE_BUILTIN_CTZ - -#endif - -/* -** Macro version of JS_CeilingLog2: Compute the log of the least power of -** 2 greater than or equal to _n. The result is returned in _log2. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)). - * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is - * undefined. - */ -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - unsigned int j_ = (unsigned int)(_n); \ - (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \ - JS_END_MACRO -#else -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) & ((j_)-1)) \ - (_log2) += 1; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -/* -** Macro version of JS_FloorLog2: Compute the log of the greatest power of -** 2 less than or equal to _n. The result is returned in _log2. -** -** This is equivalent to finding the highest set bit in the word. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)). - * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1 - * to ensure 0 result when _n == 0. - */ -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \ - JS_END_MACRO -#else -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -#if JS_BYTES_PER_WORD == 4 -# ifdef JS_HAS_BUILTIN_BITSCAN32 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#elif JS_BYTES_PER_WORD == 8 -# ifdef JS_HAS_BUILTIN_BITSCAN64 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#else -# error "NOT SUPPORTED" -#endif - -JS_END_EXTERN_C - -/* - * Internal function. - * Compute the log of the least power of 2 greater than or equal to n. This is - * a version of JS_CeilingLog2 that operates on unsigned integers with - * CPU-dependant size. - */ -#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) - -/* - * Internal function. - * Compute the log of the greatest power of 2 less than or equal to n. - * This is a version of JS_FloorLog2 that operates on unsigned integers with - * CPU-dependant size and requires that n != 0. - */ -static MOZ_ALWAYS_INLINE size_t -JS_FLOOR_LOG2W(size_t n) -{ - JS_ASSERT(n != 0); - return js_FloorLog2wImpl(n); -} - /* * JS_ROTATE_LEFT32 * @@ -552,7 +359,7 @@ template static JS_ALWAYS_INLINE T * js_pod_malloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_malloc(numElems * sizeof(T)); } @@ -561,7 +368,7 @@ template static JS_ALWAYS_INLINE T * js_pod_calloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_calloc(numElems * sizeof(T)); } @@ -595,175 +402,6 @@ SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) namespace js { -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables also need to - * be resized. - * - * The details of the optimization, and whether it's worth applying, vary from - * one type to the next. And while some constructor calls are moves, many really - * are copies, and can't be optimized this way. So we need: - * - * 1) a way for a particular invocation of a copy constructor to say that it's - * really a move, and that the value of the original isn't important - * afterwards (althought it must still be safe to destroy); and - * - * 2) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation. - * - * The Move(T &) function takes a reference to a T, and returns an MoveRef - * referring to the same value; that's 1). An MoveRef is simply a reference - * to a T, annotated to say that a copy constructor applied to it may move that - * T, instead of copying it. Finally, a constructor that accepts an MoveRef - * should perform a more efficient move, instead of a copy, providing 2). - * - * So, where we might define a copy constructor for a class C like this: - * - * C(const C &rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(MoveRef rhs) { ... move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)) - * - * Note that MoveRef implicitly converts to T &, so you can pass an - * MoveRef to an ordinary copy constructor for a type that doesn't support a - * special move constructor, and you'll just get a copy. This means that - * templates can use Move whenever they know they won't use the original value - * any more, even if they're not sure whether the type at hand has a specialized - * move constructor. If it doesn't, the MoveRef will just convert to a T &, - * and the ordinary copy constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator, - * which runs this's destructor, and then applies the move constructor to - * *this's memory. A typical definition: - * - * C &operator=(MoveRef rhs) { - * this->~C(); - * new(this) C(rhs); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * This header file defines MoveRef and Move in the js namespace. It's up to - * individual containers to annotate moves as such, by calling Move; and it's up - * to individual types to define move constructors. - * - * One hint: if you're writing a move constructor where the type has members - * that should be moved themselves, it's much nicer to write this: - * - * C(MoveRef c) : x(c->x), y(c->y) { } - * - * than the equivalent: - * - * C(MoveRef c) { new(&x) X(c->x); new(&y) Y(c->y); } - * - * especially since GNU C++ fails to notice that this does indeed initialize x - * and y, which may matter if they're const. - */ -template -class MoveRef { - public: - typedef T Referent; - explicit MoveRef(T &t) : pointer(&t) { } - T &operator*() const { return *pointer; } - T *operator->() const { return pointer; } - operator T& () const { return *pointer; } - private: - T *pointer; -}; - -template -MoveRef Move(T &t) { return MoveRef(t); } - -template -MoveRef Move(const T &t) { return MoveRef(const_cast(t)); } - -/* Useful for implementing containers that assert non-reentrancy */ -class ReentrancyGuard -{ - /* ReentrancyGuard is not copyable. */ - ReentrancyGuard(const ReentrancyGuard &); - void operator=(const ReentrancyGuard &); - -#ifdef DEBUG - bool &entered; -#endif - public: - template -#ifdef DEBUG - ReentrancyGuard(T &obj) - : entered(obj.entered) -#else - ReentrancyGuard(T &/*obj*/) -#endif - { -#ifdef DEBUG - JS_ASSERT(!entered); - entered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - entered = false; -#endif - } -}; - -template -JS_ALWAYS_INLINE static void -Swap(T &t, T &u) -{ - T tmp(Move(t)); - t = Move(u); - u = Move(tmp); -} - -/* - * Round x up to the nearest power of 2. This function assumes that the most - * significant bit of x is not set, which would lead to overflow. - */ -JS_ALWAYS_INLINE size_t -RoundUpPow2(size_t x) -{ - return size_t(1) << JS_CEILING_LOG2W(x); -} - /* Integral types for all hash functions. */ typedef uint32_t HashNumber; const unsigned HashNumberSizeBits = 32; @@ -845,11 +483,6 @@ inline bool IsPoisonedPtr(T *v) } -/* - * This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|. - */ -typedef size_t(*JSMallocSizeOfFun)(const void *p); - /* sixgill annotation defines */ #ifndef HAVE_STATIC_ANNOTATIONS # define HAVE_STATIC_ANNOTATIONS @@ -891,4 +524,4 @@ typedef size_t(*JSMallocSizeOfFun)(const void *p); # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) #endif /* HAVE_STATIC_ANNOTATIONS */ -#endif /* js_utility_h__ */ +#endif /* js_Utility_h */ diff --git a/external/spidermonkey/include/ios/js/Value.h b/external/spidermonkey/include/ios/js/Value.h index 2c7fa1a600..9b2c5dd6f9 100644 --- a/external/spidermonkey/include/ios/js/Value.h +++ b/external/spidermonkey/include/ios/js/Value.h @@ -6,8 +6,8 @@ /* JS::Value implementation. */ -#ifndef js_Value_h___ -#define js_Value_h___ +#ifndef js_Value_h +#define js_Value_h #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" @@ -53,7 +53,7 @@ namespace JS { class Value; } * nice symbolic type tags, however we can only do this when we can force the * underlying type of the enum to be the desired size. */ -#if defined(__cplusplus) && !defined(__SUNPRO_CC) && !defined(__xlC__) +#if !defined(__SUNPRO_CC) && !defined(__xlC__) #if defined(_MSC_VER) # define JS_ENUM_HEADER(id, type) enum id : type @@ -132,7 +132,7 @@ JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64_t)); #endif -#else /* defined(__cplusplus) */ +#else /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ typedef uint8_t JSValueType; #define JSVAL_TYPE_DOUBLE ((uint8_t)0x00) @@ -180,7 +180,7 @@ typedef uint64_t JSValueShiftedTag; #define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) #endif /* JS_BITS_PER_WORD */ -#endif /* defined(__cplusplus) && !defined(__SUNPRO_CC) */ +#endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT @@ -265,7 +265,7 @@ typedef union jsval_layout typedef union jsval_layout { uint64_t asBits; -#if (!defined(_WIN64) && defined(__cplusplus)) +#if !defined(_WIN64) /* MSVC does not pack these correctly :-( */ struct { uint64_t payload47 : 47; @@ -321,7 +321,6 @@ typedef union jsval_layout int32_t i32; uint32_t u32; JSWhyMagic why; - uintptr_t word; } payload; } s; double asDouble; @@ -803,22 +802,31 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) #endif /* JS_BITS_PER_WORD */ -static inline double -JS_CANONICALIZE_NAN(double d) -{ - if (MOZ_UNLIKELY(d != d)) { - jsval_layout l; - l.asBits = 0x7FF8000000000000LL; - return l.asDouble; - } - return d; -} - static inline jsval_layout JSVAL_TO_IMPL(JS::Value v); static inline JS::Value IMPL_TO_JSVAL(jsval_layout l); namespace JS { +/** + * Returns a generic quiet NaN value, with all payload bits set to zero. + * + * Among other properties, this NaN's bit pattern conforms to JS::Value's + * bit pattern restrictions. + */ +static MOZ_ALWAYS_INLINE double +GenericNaN() +{ + return mozilla::SpecificNaN(0, 0x8000000000000ULL); +} + +static inline double +CanonicalizeNaN(double d) +{ + if (MOZ_UNLIKELY(mozilla::IsNaN(d))) + return GenericNaN(); + return d; +} + /* * JS::Value is the interface for a single JavaScript Engine value. A few * general notes on JS::Value: @@ -1393,22 +1401,35 @@ SameType(const Value &lhs, const Value &rhs) /************************************************************************/ +#ifdef JSGC_GENERATIONAL +namespace JS { +JS_PUBLIC_API(void) HeapValuePostBarrier(Value *valuep); +JS_PUBLIC_API(void) HeapValueRelocate(Value *valuep); +} +#endif + namespace js { -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } }; -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } + static bool needsPostBarrier(const JS::Value &v) { return v.isMarkable(); } +#ifdef JSGC_GENERATIONAL + static void postBarrier(JS::Value *v) { JS::HeapValuePostBarrier(v); } + static void relocate(JS::Value *v) { JS::HeapValueRelocate(v); } +#endif }; +template class UnbarrieredMutableValueOperations; template class MutableValueOperations; /* @@ -1420,7 +1441,9 @@ template class MutableValueOperations; template class ValueOperations { + friend class UnbarrieredMutableValueOperations; friend class MutableValueOperations; + const JS::Value * value() const { return static_cast(this)->extract(); } public: @@ -1453,19 +1476,22 @@ class ValueOperations void *toGCThing() const { return value()->toGCThing(); } JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); } + uint32_t toPrivateUint32() const { return value()->toPrivateUint32(); } JSWhyMagic whyMagic() const { return value()->whyMagic(); } }; /* - * A class designed for CRTP use in implementing the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible extractMutable() and extract() - * methods returning the const Value* and Value* abstracted by Outer. + * A class designed for CRTP use in implementing the mutating parts of the Value + * interface in Value-like classes that don't need post barriers. Outer must be + * a class inheriting UnbarrieredMutableValueOperations with visible + * extractMutable() and extract() methods returning the const Value* and Value* + * abstracted by Outer. */ template -class MutableValueOperations : public ValueOperations +class UnbarrieredMutableValueOperations : public ValueOperations { + friend class MutableValueOperations; JS::Value * value() { return static_cast(this)->extractMutable(); } public: @@ -1473,14 +1499,66 @@ class MutableValueOperations : public ValueOperations void setUndefined() { value()->setUndefined(); } void setInt32(int32_t i) { value()->setInt32(i); } void setDouble(double d) { value()->setDouble(d); } - void setString(JSString *str) { value()->setString(str); } - void setString(const JS::Anchor &str) { value()->setString(str); } - void setObject(JSObject &obj) { value()->setObject(obj); } void setBoolean(bool b) { value()->setBoolean(b); } void setMagic(JSWhyMagic why) { value()->setMagic(why); } bool setNumber(uint32_t ui) { return value()->setNumber(ui); } bool setNumber(double d) { return value()->setNumber(d); } - void setObjectOrNull(JSObject *arg) { value()->setObjectOrNull(arg); } +}; + +/* + * A class designed for CRTP use in implementing all the mutating parts of the + * Value interface in Value-like classes. Outer must be a class inheriting + * MutableValueOperations with visible extractMutable() and extract() + * methods returning the const Value* and Value* abstracted by Outer. + */ +template +class MutableValueOperations : public UnbarrieredMutableValueOperations +{ + public: + void setString(JSString *str) { this->value()->setString(str); } + void setString(const JS::Anchor &str) { this->value()->setString(str); } + void setObject(JSObject &obj) { this->value()->setObject(obj); } + void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); } +}; + +/* + * Augment the generic Heap interface when T = Value with + * type-querying, value-extracting, and mutating operations. + */ +template <> +class HeapBase : public UnbarrieredMutableValueOperations > +{ + typedef JS::Heap Outer; + + friend class ValueOperations; + friend class UnbarrieredMutableValueOperations; + + const JS::Value * extract() const { return static_cast(this)->address(); } + JS::Value * extractMutable() { return static_cast(this)->unsafeGet(); } + + /* + * Setters that potentially change the value to a GC thing from a non-GC + * thing must call JS::Heap::set() to trigger the post barrier. + * + * Changing from a GC thing to a non-GC thing value will leave the heap + * value in the store buffer, but it will be ingored so this is not a + * problem. + */ + void setBarriered(const JS::Value &v) { + static_cast *>(this)->set(v); + } + + public: + void setString(JSString *str) { setBarriered(JS::StringValue(str)); } + void setString(const JS::Anchor &str) { setBarriered(JS::StringValue(str.get())); } + void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); } + + void setObjectOrNull(JSObject *arg) { + if (arg) + setObject(*arg); + else + setNull(); + } }; /* @@ -1508,6 +1586,7 @@ class MutableHandleBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1526,6 +1605,7 @@ class RootedBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1574,12 +1654,12 @@ inline Anchor::~Anchor() namespace detail { struct ValueAlignmentTester { char c; JS::Value v; }; -MOZ_STATIC_ASSERT(sizeof(ValueAlignmentTester) == 16, - "JS::Value must be 16-byte-aligned"); +static_assert(sizeof(ValueAlignmentTester) == 16, + "JS::Value must be 16-byte-aligned"); struct LayoutAlignmentTester { char c; jsval_layout l; }; -MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, - "jsval_layout must be 16-byte-aligned"); +static_assert(sizeof(LayoutAlignmentTester) == 16, + "jsval_layout must be 16-byte-aligned"); } // namespace detail #endif /* DEBUG */ @@ -1593,8 +1673,8 @@ MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, */ typedef JS::Value jsval; -MOZ_STATIC_ASSERT(sizeof(jsval_layout) == sizeof(JS::Value), - "jsval_layout and JS::Value must have identical layouts"); +static_assert(sizeof(jsval_layout) == sizeof(JS::Value), + "jsval_layout and JS::Value must have identical layouts"); /************************************************************************/ @@ -1762,4 +1842,4 @@ JSVAL_TO_PRIVATE(jsval v) return JSVAL_TO_PRIVATE_PTR_IMPL(JSVAL_TO_IMPL(v)); } -#endif /* js_Value_h___ */ +#endif /* js_Value_h */ diff --git a/external/spidermonkey/include/ios/js/Vector.h b/external/spidermonkey/include/ios/js/Vector.h index 5f40dd634b..b14d75c758 100644 --- a/external/spidermonkey/include/ios/js/Vector.h +++ b/external/spidermonkey/include/ios/js/Vector.h @@ -4,14 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsvector_h_ -#define jsvector_h_ +#ifndef js_Vector_h +#define js_Vector_h -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "TemplateLib.h" -#include "Utility.h" +#include "mozilla/Vector.h" /* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ #ifdef _MSC_VER @@ -23,1085 +19,48 @@ namespace js { class TempAllocPolicy; -template +// using Vector = mozilla::Vector; +// +// ...and get rid of all the CRTP madness in mozilla::Vector(Base). But we +// can't because compiler support's not up to snuff. (Template aliases are in +// gcc 4.7 and clang 3.0 and are expected to be in MSVC 2013.) Instead, have a +// completely separate class inheriting from mozilla::Vector, and throw CRTP at +// the problem til things work. +// +// This workaround presents a couple issues. First, because js::Vector is a +// distinct type from mozilla::Vector, overload resolution, method calls, etc. +// are affected. *Hopefully* this won't be too bad in practice. (A bunch of +// places had to be fixed when mozilla::Vector was introduced, but it wasn't a +// crazy number.) Second, mozilla::Vector's interface has to be made subclass- +// ready via CRTP -- or rather, via mozilla::VectorBase, which basically no one +// should use. :-) Third, we have to redefine the constructors and the non- +// inherited operators. Blech. Happily there aren't too many of these, so it +// isn't the end of the world. + +template -class Vector; - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that cap*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring - * this. - */ -template -static bool CapacityHasExcessSpace(size_t cap) +class Vector + : public mozilla::VectorBase > { - size_t size = cap * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* Destroys constructed objects in the range [begin, end). */ - static inline void destroy(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - p->~T(); - } - - /* Constructs objects in the uninitialized range [begin, end). */ - static inline void initialize(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - /* - * Copy-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(*p); - } - - /* - * Move-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(Move(*p)); - } - - /* - * Copy-constructs objects in the uninitialized range [dst, dst+n) from the - * same object u. - */ - template - static inline void copyConstructN(T *dst, size_t n, const U &u) { - for (T *end = dst + n; dst != end; ++dst) - new(dst) T(u); - } - - /* - * Grows the given buffer to have capacity newCap, preserving the objects - * constructed in the range [begin, end) and updating v. Assumes that (1) - * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will - * not overflow. - */ - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); - if (!newbuf) - return false; - for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src) - new(dst) T(Move(*src)); - VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); - v.free_(v.mBegin); - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - static inline void destroy(T *, T *) {} - - static inline void initialize(T *begin, T *end) { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(begin, 0, sizeof(T) * (end-begin)); - */ - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); - */ - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - *dst = *p; - } - - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - copyConstruct(dst, srcbeg, srcend); - } - - static inline void copyConstructN(T *dst, size_t n, const T &t) { - for (T *p = dst, *end = dst + n; p != end; ++p) - *p = t; - } - - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - size_t oldSize = sizeof(T) * v.mCapacity; - size_t newSize = sizeof(T) * newCap; - T *newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); - if (!newbuf) - return false; - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * JS-friendly, STL-like container providing a short-lived, dynamic buffer. - * Vector calls the constructors/destructors of all elements stored in - * its internal buffer, so non-PODs may be safely used. Additionally, - * Vector will store the first N elements in-place before resorting to - * dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * N requirements: - * - any value, however, N is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in jsalloc.h (default js::TempAllocPolicy) - * - * N.B: Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object. - */ -template -class Vector : private AllocPolicy -{ - // typedef typename tl::StaticAssert::result>::result _; - - /* utilities */ - - static const bool sElemIsPod = mozilla::IsPod::value; - typedef VectorImpl Impl; - friend struct VectorImpl; - - bool growStorageBy(size_t incr); - bool convertToHeapStorage(size_t newCap); - - template inline bool growByImpl(size_t inc); - - /* magic constants */ - - static const int sMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are - * 0 inline elements. This allows us to compile when the definition - * of the element type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so - * in order to keep everything here, we use a dummy template - * parameter with partial specialization. - */ - template - struct ElemSize { - static const size_t result = sizeof(T); - }; - template - struct ElemSize<0, Dummy> { - static const size_t result = 1; - }; - - static const size_t sInlineCapacity = - tl::Min::result>::result; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t sInlineBytes = - tl::Max<1, sInlineCapacity * ElemSize::result>::result; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T *mBegin; - size_t mLength; /* Number of elements in the Vector. */ - size_t mCapacity; /* Max number of elements storable in the Vector without resizing. */ -#ifdef DEBUG - size_t mReserved; /* Max elements of reserved or used space in this vector. */ -#endif - - mozilla::AlignedStorage storage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool entered; -#endif - - Vector(const Vector &) MOZ_DELETE; - Vector &operator=(const Vector &) MOZ_DELETE; - - /* private accessors */ - - bool usingInlineStorage() const { - return mBegin == inlineStorage(); - } - - T *inlineStorage() const { - return (T *)storage.addr(); - } - - T *beginNoCheck() const { - return mBegin; - } - - T *endNoCheck() { - return mBegin + mLength; - } - - const T *endNoCheck() const { - return mBegin + mLength; - } - -#ifdef DEBUG - size_t reserved() const { - JS_ASSERT(mReserved <= mCapacity); - JS_ASSERT(mLength <= mReserved); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U u); - void internalAppendN(const T &t, size_t n); - template void internalAppend(const U *begin, size_t length); - template void internalAppend(const Vector &other); + typedef typename mozilla::VectorBase Base; public: - static const size_t sMaxInlineStorage = N; - - typedef T ElementType; - - Vector(AllocPolicy = AllocPolicy()); - Vector(MoveRef); /* Move constructor. */ - Vector &operator=(MoveRef); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy &allocPolicy() const { - return *this; + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector &operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); } - - AllocPolicy &allocPolicy() { - return *this; - } - - enum { InlineLength = N }; - - size_t length() const { - return mLength; - } - - bool empty() const { - return mLength == 0; - } - - size_t capacity() const { - return mCapacity; - } - - T *begin() { - JS_ASSERT(!entered); - return mBegin; - } - - const T *begin() const { - JS_ASSERT(!entered); - return mBegin; - } - - T *end() { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - const T *end() const { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - T &operator[](size_t i) { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - const T &operator[](size_t i) const { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - T &back() { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - const T &back() const { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - class Range { - friend class Vector; - T *cur_, *end_; - Range(T *cur, T *end) : cur_(cur), end_(end) {} - public: - Range() {} - bool empty() const { return cur_ == end_; } - size_t remain() const { return end_ - cur_; } - T &front() const { return *cur_; } - void popFront() { JS_ASSERT(!empty()); ++cur_; } - T popCopyFront() { JS_ASSERT(!empty()); return *cur_++; } - }; - - Range all() { - return Range(begin(), end()); - } - - /* mutators */ - - /* Given that the Vector is empty and has no inline storage, grow to |capacity|. */ - bool initCapacity(size_t request); - - /* If reserve(length() + N) succeeds, the N next appends are guaranteed to succeed. */ - bool reserve(size_t request); - - /* - * Destroy elements in the range [end() - incr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t incr); - - /* Grow the vector by incr elements. */ - bool growBy(size_t incr); - - /* Call shrinkBy or growBy based on whether newSize > length(). */ - bool resize(size_t newLength); - - /* Leave new elements as uninitialized memory. */ - bool growByUninitialized(size_t incr); - bool resizeUninitialized(size_t newLength); - - /* Shorthand for shrinkBy(length()). */ - void clear(); - - /* Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /* If true, appending |needed| elements will not call realloc(). */ - bool canAppendWithoutRealloc(size_t needed) const; - - /* - * Potentially fallible append operations. - * - * The function templates that take an unspecified type U require a - * const T & or a MoveRef. The MoveRef variants move their - * operands into the vector, instead of copying them. If they fail, the - * operand is left unmoved. - */ - template bool append(U t); - bool appendN(const T &t, size_t n); - template bool append(const U *begin, const U *end); - template bool append(const U *begin, size_t length); - template bool append(const Vector &other); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. - */ - template void infallibleAppend(const U &u) { - internalAppend(u); - } - void infallibleAppendN(const T &t, size_t n) { - internalAppendN(t, n); - } - template void infallibleAppend(const U *aBegin, const U *aEnd) { - internalAppend(aBegin, mozilla::PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U *aBegin, size_t aLength) { - internalAppend(aBegin, aLength); - } - template void infallibleAppend(const Vector &other) { - internalAppend(other); - } - - void popBack(); - - T popCopy(); - - /* - * Transfers ownership of the internal buffer used by Vector to the caller. - * After this call, the Vector is empty. Since the returned buffer may need - * to be allocated (if the elements are currently stored in-place), the - * call can fail, returning NULL. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - T *extractRawBuffer(); - - /* - * Transfer ownership of an array of objects into the Vector. - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T *p, size_t length); - - /* - * Places |val| at position |p|, shifting existing elements from |p| - * onward one position higher. On success, |p| should not be reused - * because it will be a dangling pointer if reallocation of the vector - * storage occurred; the return value should be used instead. On failure, - * NULL is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) - * - * - */ - T *insert(T *p, const T &val); - - /* - * Removes the element |t|, which must fall in the bounds [begin, end), - * shifting existing elements from |t + 1| onward one position lower. - */ - void erase(T *t); - - /* - * Measure the size of the Vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - /* - * Like sizeOfExcludingThis, but also measures the size of the Vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - void swap(Vector &other); }; -/* This does the re-entrancy check plus several other sanity checks. */ -#define REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - JS_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ - JS_ASSERT(reserved() <= mCapacity); \ - JS_ASSERT(mLength <= reserved()); \ - JS_ASSERT(mLength <= mCapacity) +} // namespace js -/* Vector Implementation */ - -template -JS_ALWAYS_INLINE -Vector::Vector(AllocPolicy ap) - : AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0), - mCapacity(sInlineCapacity) -#ifdef DEBUG - , mReserved(sInlineCapacity), entered(false) -#endif -{} - -/* Move constructor. */ -template -JS_ALWAYS_INLINE -Vector::Vector(MoveRef rhs) - : AllocPolicy(rhs) -#ifdef DEBUG - , entered(false) -#endif -{ - mLength = rhs->mLength; - mCapacity = rhs->mCapacity; -#ifdef DEBUG - mReserved = rhs->mReserved; -#endif - - if (rhs->usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = (T *)storage.addr(); - Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); - /* - * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = rhs->mBegin; - rhs->mBegin = (T *) rhs->storage.addr(); - rhs->mCapacity = sInlineCapacity; - rhs->mLength = 0; -#ifdef DEBUG - rhs->mReserved = sInlineCapacity; -#endif - } -} - -/* Move assignment. */ -template -JS_ALWAYS_INLINE -Vector & -Vector::operator=(MoveRef rhs) -{ - this->~Vector(); - new(this) Vector(rhs); - return *this; -} - -template -JS_ALWAYS_INLINE -Vector::~Vector() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); -} - -/* - * This function will create a new heap buffer with capacity newCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t newCap) -{ - JS_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); - if (!newBuf) - return false; - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = newCap; - return true; -} - -template -JS_NEVER_INLINE bool -Vector::growStorageBy(size_t incr) -{ - JS_ASSERT(mLength + incr > mCapacity); - JS_ASSERT_IF(!usingInlineStorage(), !CapacityHasExcessSpace(mCapacity)); - - /* - * When choosing a new capacity, its size should is as close to 2^N bytes - * as possible. 2^N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2^N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2^N request size. - */ - - size_t newCap; - - if (incr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::result; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength*4*sizeof(T) overflow? This condition limits a Vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. - * It also ensures that the ((char *)end() - (char *)begin()) does not - * overflow ptrdiff_t (see Bug 510319). - */ - if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::result) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is - * already as close to 2^N as sizeof(T) will allow. Just double the - * capacity, and then there might be space for one more element. - */ - newCap = mLength * 2; - if (CapacityHasExcessSpace(newCap)) - newCap += 1; - - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + incr; - - /* Did mLength+incr overflow? Will newCap*sizeof(T) overflow? */ - if (newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { - convert: - return convertToHeapStorage(newCap); - } - - grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t request) -{ - JS_ASSERT(empty()); - JS_ASSERT(usingInlineStorage()); - if (request == 0) - return true; - T *newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); - if (!newbuf) - return false; - mBegin = newbuf; - mCapacity = request; -#ifdef DEBUG - mReserved = request; -#endif - return true; -} - -template -inline bool -Vector::reserve(size_t request) -{ - REENTRANCY_GUARD_ET_AL; - if (request > mCapacity && !growStorageBy(request - mLength)) - return false; - -#ifdef DEBUG - if (request > mReserved) - mReserved = request; - JS_ASSERT(mLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(incr <= mLength); - Impl::destroy(endNoCheck() - incr, endNoCheck()); - mLength -= incr; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::growByImpl(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - if (incr > mCapacity - mLength && !growStorageBy(incr)) - return false; - - JS_ASSERT(mLength + incr <= mCapacity); - T *newend = endNoCheck() + incr; - if (InitNewElems) - Impl::initialize(endNoCheck(), newend); - mLength += incr; -#ifdef DEBUG - if (mLength > mReserved) - mReserved = mLength; -#endif - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::growBy(size_t incr) -{ - return growByImpl(incr); -} - -template -JS_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t incr) -{ - return growByImpl(incr); -} - -template -STATIC_POSTCONDITION(!return || ubound(this->begin()) >= newLength) -inline bool -Vector::resize(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growBy(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growByUninitialized(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -inline void -Vector::clear() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) - return; - - this->free_(beginNoCheck()); - mBegin = (T *)storage.addr(); - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t needed) const -{ - return mLength + needed <= mCapacity; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(U t) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity && !growStorageBy(1)) - return false; - -#ifdef DEBUG - if (mLength + 1 > mReserved) - mReserved = mLength + 1; -#endif - internalAppend(t); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(U u) -{ - JS_ASSERT(mLength + 1 <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - new(endNoCheck()) T(u); - ++mLength; -} - -template -JS_ALWAYS_INLINE bool -Vector::appendN(const T &t, size_t needed) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppendN(t, needed); - return true; -} - -template -JS_ALWAYS_INLINE void -Vector::internalAppendN(const T &t, size_t needed) -{ - JS_ASSERT(mLength + needed <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), needed, t); - mLength += needed; -} - -template -inline T * -Vector::insert(T *p, const T &val) -{ - JS_ASSERT(begin() <= p && p <= end()); - size_t pos = p - begin(); - JS_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(val)) - return NULL; - } else { - T oldBack = back(); - if (!append(oldBack)) /* Dup the last element. */ - return NULL; - for (size_t i = oldLength; i > pos; --i) - (*this)[i] = (*this)[i - 1]; - (*this)[pos] = val; - } - return begin() + pos; -} - -template -inline void -Vector::erase(T *it) -{ - JS_ASSERT(begin() <= it && it < end()); - while (it + 1 != end()) { - *it = *(it + 1); - ++it; - } - popBack(); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, const U *insEnd) -{ - REENTRANCY_GUARD_ET_AL; - size_t needed = mozilla::PointerRangeSize(insBegin, insEnd); - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppend(insBegin, needed); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(const U *insBegin, size_t insLength) -{ - JS_ASSERT(mLength + insLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); - mLength += insLength; -} - -template -template -inline bool -Vector::append(const Vector &other) -{ - return append(other.begin(), other.end()); -} - -template -template -inline void -Vector::internalAppend(const Vector &other) -{ - internalAppend(other.begin(), other.length()); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, size_t insLength) -{ - return this->append(insBegin, insBegin + insLength); -} - -template -JS_ALWAYS_INLINE void -Vector::popBack() -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -JS_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T * -Vector::extractRawBuffer() -{ - T *ret; - if (usingInlineStorage()) { - ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); - if (!ret) - return NULL; - Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - /* mBegin, mCapacity are unchanged. */ - mLength = 0; - } else { - ret = mBegin; - mBegin = (T *)storage.addr(); - mLength = 0; - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif - } - return ret; -} - -template -inline void -Vector::replaceRawBuffer(T *p, size_t aLength) -{ - REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); - - /* Take in the new buffer. */ - if (aLength <= sInlineCapacity) { - /* - * We convert to inline storage if possible, even though p might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = (T *)storage.addr(); - mLength = aLength; - mCapacity = sInlineCapacity; - Impl::moveConstruct(mBegin, p, p + aLength); - Impl::destroy(p, p + aLength); - this->free_(p); - } else { - mBegin = p; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); -} - -template -inline void -Vector::swap(Vector &other) -{ - // TODO Implement N != 0 - JS_STATIC_ASSERT(N == 0); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && other.usingInlineStorage()) { - other.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !other.usingInlineStorage()) { - mBegin = other.mBegin; - other.mBegin = other.inlineStorage(); - } else if (!usingInlineStorage() && !other.usingInlineStorage()) { - Swap(mBegin, other.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, other.mLength); - Swap(mCapacity, other.mCapacity); -#ifdef DEBUG - Swap(mReserved, other.mReserved); -#endif -} - -} /* namespace js */ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* jsvector_h_ */ +#endif /* js_Vector_h */ diff --git a/external/spidermonkey/include/ios/jsalloc.h b/external/spidermonkey/include/ios/jsalloc.h index e7e64fc540..3abc4966d1 100644 --- a/external/spidermonkey/include/ios/jsalloc.h +++ b/external/spidermonkey/include/ios/jsalloc.h @@ -4,32 +4,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsalloc_h_ -#define jsalloc_h_ +/* JS allocation policies. */ + +#ifndef jsalloc_h +#define jsalloc_h + +#include "mozilla/AllocPolicy.h" #include "js/Utility.h" -#include "jstypes.h" struct JSContext; namespace js { -/* - * Allocation policies. These model the concept: - * - public copy constructor, assignment, destructor - * - void *malloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *calloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *realloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * The *used* bytes of the previous buffer is passed in - * (rather than the old allocation size), in addition to - * the *new* allocation size requested. - * - void free_(void *) - * - reportAllocOverflow() - * Called on overflow before the container returns NULL. - */ +class ContextFriendFields; /* Policy for using system memory functions and doing no error reporting. */ class SystemAllocPolicy @@ -53,7 +41,7 @@ class SystemAllocPolicy */ class TempAllocPolicy { - JSContext *const cx_; + ContextFriendFields *const cx_; /* * Non-inline helper to call JSRuntime::onOutOfMemory with minimal @@ -62,11 +50,8 @@ class TempAllocPolicy JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes); public: - TempAllocPolicy(JSContext *cx) : cx_(cx) {} - - JSContext *context() const { - return cx_; - } + TempAllocPolicy(JSContext *cx) : cx_((ContextFriendFields *) cx) {} // :( + TempAllocPolicy(ContextFriendFields *cx) : cx_(cx) {} void *malloc_(size_t bytes) { void *p = js_malloc(bytes); @@ -98,4 +83,4 @@ class TempAllocPolicy } /* namespace js */ -#endif /* jsalloc_h_ */ +#endif /* jsalloc_h */ diff --git a/external/spidermonkey/include/ios/jsapi.h.REMOVED.git-id b/external/spidermonkey/include/ios/jsapi.h.REMOVED.git-id index db9dbac6b4..27b6bbed78 100644 --- a/external/spidermonkey/include/ios/jsapi.h.REMOVED.git-id +++ b/external/spidermonkey/include/ios/jsapi.h.REMOVED.git-id @@ -1 +1 @@ -0ec74a6f5f2aa9bbaa6a8cbf6e2ae95ec7c4ee43 \ No newline at end of file +e14ea931f699b1808c06886e55e977c9819f3774 \ No newline at end of file diff --git a/external/spidermonkey/include/ios/jsclass.h b/external/spidermonkey/include/ios/jsclass.h index c9b53c7679..def641715d 100644 --- a/external/spidermonkey/include/ios/jsclass.h +++ b/external/spidermonkey/include/ios/jsclass.h @@ -4,14 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclass_h__ -#define jsclass_h__ +#ifndef jsclass_h +#define jsclass_h /* * A JSClass acts as a vtable for JS objects that allows JSAPI clients to * control various aspects of the behavior of an object like property lookup. * js::Class is an engine-private extension that allows more control over * object behavior and, e.g., allows custom slow layout. */ + #include "jsapi.h" #include "jsprvtd.h" @@ -21,6 +22,10 @@ class PropertyName; class SpecialId; class PropertyId; +// This is equal to JSFunction::class_. Use it in places where you don't want +// to #include jsfun.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionClassPtr; + static JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid); @@ -195,7 +200,7 @@ typedef void const char *name; \ uint32_t flags; \ \ - /* Mandatory non-null function pointer members. */ \ + /* Mandatory function pointer members. */ \ JSPropertyOp addProperty; \ JSDeletePropertyOp delProperty; \ JSPropertyOp getProperty; \ @@ -203,9 +208,9 @@ typedef void JSEnumerateOp enumerate; \ JSResolveOp resolve; \ JSConvertOp convert; \ - FinalizeOp finalize; \ \ - /* Optionally non-null members start here. */ \ + /* Optional members (may be null). */ \ + FinalizeOp finalize; \ JSCheckAccessOp checkAccess; \ JSNative call; \ JSHasInstanceOp hasInstance; \ @@ -214,7 +219,7 @@ typedef void /* * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much - * we have to padd js::Class to match the size of JSClass; + * we have to pad js::Class to match the size of JSClass. */ struct ClassSizeMeasurement { @@ -312,8 +317,9 @@ struct Class return flags & JSCLASS_EMULATES_UNDEFINED; } - /* Defined in jsfuninlines.h */ - inline bool isCallable() const; + bool isCallable() const { + return this == js::FunctionClassPtr || call; + } static size_t offsetOfFlags() { return offsetof(Class, flags); } }; @@ -387,7 +393,7 @@ IsPoisonedSpecialId(js::SpecialId iden) return false; } -template <> struct RootMethods +template <> struct GCMethods { static SpecialId initial() { return SpecialId(); } static ThingRootKind kind() { return THING_ROOT_ID; } @@ -396,4 +402,4 @@ template <> struct RootMethods } /* namespace js */ -#endif /* jsclass_h__ */ +#endif /* jsclass_h */ diff --git a/external/spidermonkey/include/ios/jsclist.h b/external/spidermonkey/include/ios/jsclist.h index 8782307fa4..23da9b8cd5 100644 --- a/external/spidermonkey/include/ios/jsclist.h +++ b/external/spidermonkey/include/ios/jsclist.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclist_h___ -#define jsclist_h___ +#ifndef jsclist_h +#define jsclist_h #include "jstypes.h" @@ -104,4 +104,4 @@ typedef struct JSCListStr { #define JS_INIT_STATIC_CLIST(_l) \ {(_l), (_l)} -#endif /* jsclist_h___ */ +#endif /* jsclist_h */ diff --git a/external/spidermonkey/include/ios/jscpucfg.h b/external/spidermonkey/include/ios/jscpucfg.h index 6bb62b420f..c79bd7ad14 100644 --- a/external/spidermonkey/include/ios/jscpucfg.h +++ b/external/spidermonkey/include/ios/jscpucfg.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_cpucfg___ -#define js_cpucfg___ +#ifndef jscpucfg_h +#define jscpucfg_h #define JS_HAVE_LONG_LONG @@ -114,4 +114,4 @@ # endif #endif -#endif /* js_cpucfg___ */ +#endif /* jscpucfg_h */ diff --git a/external/spidermonkey/include/ios/jsdbgapi.h b/external/spidermonkey/include/ios/jsdbgapi.h index 4907d913a0..0ce7101337 100644 --- a/external/spidermonkey/include/ios/jsdbgapi.h +++ b/external/spidermonkey/include/ios/jsdbgapi.h @@ -4,12 +4,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsdbgapi_h___ -#define jsdbgapi_h___ +#ifndef jsdbgapi_h +#define jsdbgapi_h /* * JS debugger API. */ -#include "jsapi.h" + #include "jsprvtd.h" namespace JS { @@ -111,7 +111,7 @@ JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapHandler *handlerp, jsval *closurep); extern JS_PUBLIC_API(void) -JS_ClearScriptTraps(JSContext *cx, JSScript *script); +JS_ClearScriptTraps(JSRuntime *rt, JSScript *script); extern JS_PUBLIC_API(void) JS_ClearAllTrapsForCompartment(JSContext *cx); @@ -224,12 +224,6 @@ JS_GetScriptLineExtent(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(JSVersion) JS_GetScriptVersion(JSContext *cx, JSScript *script); -extern JS_PUBLIC_API(bool) -JS_GetScriptUserBit(JSScript *script); - -extern JS_PUBLIC_API(void) -JS_SetScriptUserBit(JSScript *script, bool b); - extern JS_PUBLIC_API(bool) JS_GetScriptIsSelfHosted(JSScript *script); @@ -433,9 +427,6 @@ JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); /************************************************************************/ -extern JS_FRIEND_API(void) -js_RevertVersion(JSContext *cx); - extern JS_PUBLIC_API(const JSDebugHooks *) JS_GetGlobalDebugHooks(JSRuntime *rt); @@ -465,4 +456,4 @@ JS_DumpCompartmentPCCounts(JSContext *cx); extern JS_FRIEND_API(JSBool) js_CallContextDebugHandler(JSContext *cx); -#endif /* jsdbgapi_h___ */ +#endif /* jsdbgapi_h */ diff --git a/external/spidermonkey/include/ios/jsdhash.h b/external/spidermonkey/include/ios/jsdhash.h deleted file mode 100644 index 1f7830fd2b..0000000000 --- a/external/spidermonkey/include/ios/jsdhash.h +++ /dev/null @@ -1,612 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef jsdhash_h___ -#define jsdhash_h___ - -/* - * Double hashing, a la Knuth 6. - * - * Try to keep this file in sync with xpcom/glue/pldhash.h. - */ -#include "jstypes.h" -#include "jsutil.h" - -#if defined(__GNUC__) && defined(__i386__) && !defined(XP_OS2) -#define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall)) -#elif defined(XP_WIN) -#define JS_DHASH_FASTCALL __fastcall -#else -#define JS_DHASH_FASTCALL -#endif - -#ifdef DEBUG_XXXbrendan -#define JS_DHASHMETER 1 -#endif - -/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ -#undef JS_DHASH_SIZE_LIMIT -#define JS_DHASH_SIZE_LIMIT JS_BIT(24) - -/* Minimum table size, or gross entry count (net is at most .75 loaded). */ -#ifndef JS_DHASH_MIN_SIZE -#define JS_DHASH_MIN_SIZE 16 -#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0 -#error "JS_DHASH_MIN_SIZE must be a power of two!" -#endif - -/* - * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - * expressed as a fixed-point 32-bit fraction. - */ -#define JS_DHASH_BITS 32 -#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U - -/* Primitive and forward-struct typedefs. */ -typedef uint32_t JSDHashNumber; -typedef struct JSDHashEntryHdr JSDHashEntryHdr; -typedef struct JSDHashEntryStub JSDHashEntryStub; -typedef struct JSDHashTable JSDHashTable; -typedef struct JSDHashTableOps JSDHashTableOps; - -/* - * Table entry header structure. - * - * In order to allow in-line allocation of key and value, we do not declare - * either here. Instead, the API uses const void *key as a formal parameter. - * The key need not be stored in the entry; it may be part of the value, but - * need not be stored at all. - * - * Callback types are defined below and grouped into the JSDHashTableOps - * structure, for single static initialization per hash table sub-type. - * - * Each hash table sub-type should nest the JSDHashEntryHdr structure at the - * front of its particular entry type. The keyHash member contains the result - * of multiplying the hash code returned from the hashKey callback (see below) - * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 - * and 1 values. The stored keyHash value is table size invariant, and it is - * maintained automatically by JS_DHashTableOperate -- users should never set - * it, and its only uses should be via the entry macros below. - * - * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor - * removed. An entry may be either busy or free; if busy, it may be live or - * removed. Consumers of this API should not access members of entries that - * are not live. - * - * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries - * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a - * non-live, busy (i.e., removed) entry pointer to its caller. See below for - * more details on JS_DHashTableOperate's calling rules. - */ -struct JSDHashEntryHdr { - JSDHashNumber keyHash; /* every entry must begin like this */ -}; - -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_FREE(JSDHashEntryHdr* entry) -{ - return entry->keyHash == 0; -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_BUSY(JSDHashEntryHdr* entry) -{ - return !JS_DHASH_ENTRY_IS_FREE(entry); -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_LIVE(JSDHashEntryHdr* entry) -{ - return entry->keyHash >= 2; -} - -/* - * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead) - * on most architectures, and may be allocated on the stack or within another - * structure or class (see below for the Init and Finish functions to use). - * - * To decide whether to use double hashing vs. chaining, we need to develop a - * trade-off relation, as follows: - * - * Let alpha be the load factor, esize the entry size in words, count the - * entry count, and pow2 the power-of-two table size in entries. - * - * (JSDHashTable overhead) > (JSHashTable overhead) - * (unused table entry space) > (malloc and .next overhead per entry) + - * (buckets overhead) - * (1 - alpha) * esize * pow2 > 2 * count + pow2 - * - * Notice that alpha is by definition (count / pow2): - * - * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2 - * (1 - alpha) * esize > 2 * alpha + 1 - * - * esize > (1 + 2 * alpha) / (1 - alpha) - * - * This assumes both tables must keep keyHash, key, and value for each entry, - * where key and value point to separately allocated strings or structures. - * If key and value can be combined into one pointer, then the trade-off is: - * - * esize > (1 + 3 * alpha) / (1 - alpha) - * - * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type - * that must be allocated separately and referenced by an entry.value pointer - * member, and provided key's allocation can be fused with its entry's, then - * k (the words wasted per entry with chaining) is 4. - * - * To see these curves, feed gnuplot input like so: - * - * gnuplot> f(x,k) = (1 + k * x) / (1 - x) - * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4) - * - * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4 - * words for chaining to be more space-efficient than double hashing. - * - * Solving for alpha helps us decide when to shrink an underloaded table: - * - * esize > (1 + k * alpha) / (1 - alpha) - * esize - alpha * esize > 1 + k * alpha - * esize - 1 > (k + esize) * alpha - * (esize - 1) / (k + esize) > alpha - * - * alpha < (esize - 1) / (esize + k) - * - * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k), - * assuming esize is not too large (in which case, chaining should probably be - * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3 - * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5 - * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below. - * - * The current implementation uses a configurable lower bound on alpha, which - * defaults to .25, when deciding to shrink the table (while still respecting - * JS_DHASH_MIN_SIZE). - * - * Note a qualitative difference between chaining and double hashing: under - * chaining, entry addresses are stable across table shrinks and grows. With - * double hashing, you can't safely hold an entry pointer and use it after an - * ADD or REMOVE operation, unless you sample table->generation before adding - * or removing, and compare the sample after, dereferencing the entry pointer - * only if table->generation has not changed. - * - * The moral of this story: there is no one-size-fits-all hash table scheme, - * but for small table entry size, and assuming entry address stability is not - * required, double hashing wins. - */ -struct JSDHashTable { - const JSDHashTableOps *ops; /* virtual operations, see below */ - void *data; /* ops- and instance-specific data */ - int16_t hashShift; /* multiplicative hash shift */ - uint8_t maxAlphaFrac; /* 8-bit fixed point max alpha */ - uint8_t minAlphaFrac; /* 8-bit fixed point min alpha */ - uint32_t entrySize; /* number of bytes in an entry */ - uint32_t entryCount; /* number of entries in table */ - uint32_t removedCount; /* removed entry sentinels in table */ - uint32_t generation; /* entry storage generation number */ - char *entryStore; /* entry storage */ -#ifdef JS_DHASHMETER - struct JSDHashStats { - uint32_t searches; /* total number of table searches */ - uint32_t steps; /* hash chain links traversed */ - uint32_t hits; /* searches that found key */ - uint32_t misses; /* searches that didn't find key */ - uint32_t lookups; /* number of JS_DHASH_LOOKUPs */ - uint32_t addMisses; /* adds that miss, and do work */ - uint32_t addOverRemoved; /* adds that recycled a removed entry */ - uint32_t addHits; /* adds that hit an existing entry */ - uint32_t addFailures; /* out-of-memory during add growth */ - uint32_t removeHits; /* removes that hit, and do work */ - uint32_t removeMisses; /* useless removes that miss */ - uint32_t removeFrees; /* removes that freed entry directly */ - uint32_t removeEnums; /* removes done by Enumerate */ - uint32_t grows; /* table expansions */ - uint32_t shrinks; /* table contractions */ - uint32_t compresses; /* table compressions */ - uint32_t enumShrinks; /* contractions after Enumerate */ - } stats; -#endif -}; - -/* - * Size in entries (gross, not net of free and removed sentinels) for table. - * We store hashShift rather than sizeLog2 to optimize the collision-free case - * in SearchTable. - */ -#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift) - -/* - * Table space at entryStore is allocated and freed using these callbacks. - * The allocator should return null on error only (not if called with nbytes - * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). - */ -typedef void * -(* JSDHashAllocTable)(JSDHashTable *table, uint32_t nbytes); - -typedef void -(* JSDHashFreeTable) (JSDHashTable *table, void *ptr); - -/* - * Compute the hash code for a given key to be looked up, added, or removed - * from table. A hash code may have any JSDHashNumber value. - */ -typedef JSDHashNumber -(* JSDHashHashKey) (JSDHashTable *table, const void *key); - -/* - * Compare the key identifying entry in table with the provided key parameter. - * Return JS_TRUE if keys match, JS_FALSE otherwise. - */ -typedef JSBool -(* JSDHashMatchEntry)(JSDHashTable *table, const JSDHashEntryHdr *entry, - const void *key); - -/* - * Copy the data starting at from to the new entry storage at to. Do not add - * reference counts for any strong references in the entry, however, as this - * is a "move" operation: the old entry storage at from will be freed without - * any reference-decrementing callback shortly. - */ -typedef void -(* JSDHashMoveEntry)(JSDHashTable *table, const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -/* - * Clear the entry and drop any strong references it holds. This callback is - * invoked during a JS_DHASH_REMOVE operation (see below for operation codes), - * but only if the given key is found in the table. - */ -typedef void -(* JSDHashClearEntry)(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Called when a table (whether allocated dynamically by itself, or nested in - * a larger structure, or allocated on the stack) is finished. This callback - * allows table->ops-specific code to finalize table->data. - */ -typedef void -(* JSDHashFinalize) (JSDHashTable *table); - -/* - * Initialize a new entry, apart from keyHash. This function is called when - * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the - * given key, and must add a new one. At that point, entry->keyHash is not - * set yet, to avoid claiming the last free entry in a severely overloaded - * table. - */ -typedef JSBool -(* JSDHashInitEntry)(JSDHashTable *table, JSDHashEntryHdr *entry, - const void *key); - -/* - * Finally, the "vtable" structure for JSDHashTable. The first eight hooks - * must be provided by implementations; they're called unconditionally by the - * generic jsdhash.c code. Hooks after these may be null. - * - * Summary of allocation-related hook usage with C++ placement new emphasis: - * allocTable Allocate raw bytes with malloc, no ctors run. - * freeTable Free raw bytes with free, no dtors run. - * initEntry Call placement new using default key-based ctor. - * Return JS_TRUE on success, JS_FALSE on error. - * moveEntry Call placement new using copy ctor, run dtor on old - * entry storage. - * clearEntry Run dtor on entry. - * finalize Stub unless table->data was initialized and needs to - * be finalized. - * - * Note the reason why initEntry is optional: the default hooks (stubs) clear - * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD), - * the returned entry pointer addresses an entry struct whose keyHash member - * has been set non-zero, but all other entry members are still clear (null). - * JS_DHASH_ADD callers can test such members to see whether the entry was - * newly created by the JS_DHASH_ADD call that just succeeded. If placement - * new or similar initialization is required, define an initEntry hook. Of - * course, the clearEntry hook must zero or null appropriately. - * - * XXX assumes 0 is null for pointer types. - */ -struct JSDHashTableOps { - /* Mandatory hooks. All implementations must provide these. */ - JSDHashAllocTable allocTable; - JSDHashFreeTable freeTable; - JSDHashHashKey hashKey; - JSDHashMatchEntry matchEntry; - JSDHashMoveEntry moveEntry; - JSDHashClearEntry clearEntry; - JSDHashFinalize finalize; - - /* Optional hooks start here. If null, these are not called. */ - JSDHashInitEntry initEntry; -}; - -/* - * Default implementations for the above ops. - */ -extern JS_PUBLIC_API(void *) -JS_DHashAllocTable(JSDHashTable *table, uint32_t nbytes); - -extern JS_PUBLIC_API(void) -JS_DHashFreeTable(JSDHashTable *table, void *ptr); - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashStringKey(JSDHashTable *table, const void *key); - -/* A minimal entry contains a keyHash header and a void key pointer. */ -struct JSDHashEntryStub { - JSDHashEntryHdr hdr; - const void *key; -}; - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchStringKey(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(void) -JS_DHashMoveEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -extern JS_PUBLIC_API(void) -JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFinalizeStub(JSDHashTable *table); - -/* - * If you use JSDHashEntryStub or a subclass of it as your entry struct, and - * if your entries move via memcpy and clear via memset(0), you can use these - * stub operations. - */ -extern JS_PUBLIC_API(const JSDHashTableOps *) -JS_DHashGetStubOps(void); - -/* - * Dynamically allocate a new JSDHashTable using malloc, initialize it using - * JS_DHashTableInit, and return its address. Return null on malloc failure. - * Note that the entry storage at table->entryStore will be allocated using - * the ops->allocTable callback. - */ -extern JS_PUBLIC_API(JSDHashTable *) -JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32_t entrySize, - uint32_t capacity); - -/* - * Finalize table's data, free its entry storage (via table->ops->freeTable), - * and return the memory starting at table to the malloc heap. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableDestroy(JSDHashTable *table); - -/* - * Initialize table with ops, data, entrySize, and capacity. Capacity is a - * guess for the smallest table size at which the table will usually be less - * than 75% loaded (the table will grow or shrink as needed; capacity serves - * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE). - */ -extern JS_PUBLIC_API(JSBool) -JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, - uint32_t entrySize, uint32_t capacity); - -/* - * Set maximum and minimum alpha for table. The defaults are 0.75 and .25. - * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if - * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or - * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that - * we don't shrink on the very next remove after growing a table upon adding - * an entry that brings entryCount past maxAlpha * tableSize. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableSetAlphaBounds(JSDHashTable *table, - float maxAlpha, - float minAlpha); - -/* - * Call this macro with k, the number of pointer-sized words wasted per entry - * under chaining, to compute the minimum alpha at which double hashing still - * beats chaining. - */ -#define JS_DHASH_MIN_ALPHA(table, k) \ - ((float)((table)->entrySize / sizeof(void *) - 1) \ - / ((table)->entrySize / sizeof(void *) + (k))) - -/* - * Default max/min alpha, and macros to compute the value for the |capacity| - * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any - * max alpha, such that adding entryCount entries right after initializing the - * table will not require a reallocation (so JS_DHASH_ADD can't fail for those - * JS_DHashTableOperate calls). - * - * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY. - * Don't use it directly! - */ -#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 -#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 - -#define JS_DHASH_CAP(entryCount, maxAlpha) \ - ((uint32_t)((double)(entryCount) / (maxAlpha))) - -#define JS_DHASH_CAPACITY(entryCount, maxAlpha) \ - (JS_DHASH_CAP(entryCount, maxAlpha) + \ - (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8_t)(0x100 * (maxAlpha))) \ - >> 8) < (entryCount))) - -#define JS_DHASH_DEFAULT_CAPACITY(entryCount) \ - JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) - -/* - * Finalize table's data, free its entry storage using table->ops->freeTable, - * and leave its members unchanged from their last live values (which leaves - * pointers dangling). If you want to burn cycles clearing table, it's up to - * your code to call memset. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableFinish(JSDHashTable *table); - -/* - * To consolidate keyHash computation and table grow/shrink code, we use a - * single entry point for lookup, add, and remove operations. The operation - * codes are declared here, along with codes returned by JSDHashEnumerator - * functions, which control JS_DHashTableEnumerate's behavior. - */ -typedef enum JSDHashOperator { - JS_DHASH_LOOKUP = 0, /* lookup entry */ - JS_DHASH_ADD = 1, /* add entry */ - JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */ - JS_DHASH_NEXT = 0, /* enumerator says continue */ - JS_DHASH_STOP = 1 /* enumerator says stop */ -} JSDHashOperator; - -/* - * To lookup a key in table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); - * - * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies - * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found. - * - * To add an entry identified by key to table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD); - * - * If entry is null upon return, then either the table is severely overloaded, - * and memory can't be allocated for entry storage via table->ops->allocTable; - * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may - * have returned false. - * - * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry) - * is true, and it is up to the caller to initialize the key and value parts - * of the entry sub-type, if they have not been set already (i.e. if entry was - * not already in the table, and if the optional initEntry hook was not used). - * - * To remove an entry identified by key from table, call: - * - * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); - * - * If key's entry is found, it is cleared (via table->ops->clearEntry) and - * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation - * returns null unconditionally; you should ignore its return value. - */ -extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL -JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); - -/* - * Remove an entry already accessed via LOOKUP or ADD. - * - * NB: this is a "raw" or low-level routine, intended to be used only where - * the inefficiency of a full JS_DHashTableOperate (which rehashes in order - * to find the entry given its key) is not tolerable. This function does not - * shrink the table if it is underloaded. It does not update stats #ifdef - * JS_DHASHMETER, either. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Enumerate entries in table using etor: - * - * count = JS_DHashTableEnumerate(table, etor, arg); - * - * JS_DHashTableEnumerate calls etor like so: - * - * op = etor(table, entry, number, arg); - * - * where number is a zero-based ordinal assigned to live entries according to - * their order in table->entryStore. - * - * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT, - * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via - * table->ops->clearEntry) and free entry. Then we check whether op contains - * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries - * that were enumerated so far. Return the total number of live entries when - * enumeration completes normally. - * - * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it - * must return JS_DHASH_STOP; otherwise undefined behavior results. - * - * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk - * or compressed after enumeration, but before JS_DHashTableEnumerate returns. - * Such an enumerator therefore can't safely set aside entry pointers, but an - * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries - * aside, e.g., to avoid copying live entries into an array of the entry type. - * Copying entry pointers is cheaper, and safe so long as the caller of such a - * "stable" Enumerate doesn't use the set-aside pointers after any call either - * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might - * grow or shrink entryStore. - * - * If your enumerator wants to remove certain entries, but set aside pointers - * to other entries that it retains, it can use JS_DHashTableRawRemove on the - * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if - * you want to remove entries, but for some reason you do not want entryStore - * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on - * the entry being enumerated, rather than returning JS_DHASH_REMOVE. - */ -typedef JSDHashOperator -(* JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number, void *arg); - -extern JS_PUBLIC_API(uint32_t) -JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); - -typedef size_t -(* JSDHashSizeOfEntryExcludingThisFun)(JSDHashEntryHdr *hdr, - JSMallocSizeOfFun mallocSizeOf, - void *arg); - -/** - * Measure the size of the table's entry storage, and if - * |sizeOfEntryExcludingThis| is non-NULL, measure the size of things pointed - * to by entries. Doesn't measure |ops| because it's often shared between - * tables, nor |data| because it's opaque. - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfExcludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -/** - * Like JS_DHashTableSizeOfExcludingThis, but includes sizeof(*this). - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfIncludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -#ifdef DEBUG -/** - * Mark a table as immutable for the remainder of its lifetime. This - * changes the implementation from ASSERTing one set of invariants to - * ASSERTing a different set. - * - * When a table is NOT marked as immutable, the table implementation - * asserts that the table is not mutated from its own callbacks. It - * assumes the caller protects the table from being accessed on multiple - * threads simultaneously. - * - * When the table is marked as immutable, the re-entry assertions will - * no longer trigger erroneously due to multi-threaded access. Instead, - * mutations will cause assertions. - */ -extern JS_PUBLIC_API(void) -JS_DHashMarkTableImmutable(JSDHashTable *table); -#endif - -#ifdef JS_DHASHMETER -#include - -extern JS_PUBLIC_API(void) -JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp); -#endif - -#endif /* jsdhash_h___ */ diff --git a/external/spidermonkey/include/ios/jsfriendapi.h b/external/spidermonkey/include/ios/jsfriendapi.h index 848049ffe3..a1c3024fed 100644 --- a/external/spidermonkey/include/ios/jsfriendapi.h +++ b/external/spidermonkey/include/ios/jsfriendapi.h @@ -4,15 +4,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsfriendapi_h___ -#define jsfriendapi_h___ +#ifndef jsfriendapi_h +#define jsfriendapi_h -#include "mozilla/GuardObjects.h" +#include "mozilla/MemoryReporting.h" #include "jsclass.h" -#include "jscpucfg.h" -#include "jspubtd.h" #include "jsprvtd.h" +#include "jspubtd.h" + +#include "js/CallArgs.h" /* * This macro checks if the stack pointer has exceeded a given limit. If @@ -29,6 +30,11 @@ #define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0) +namespace JS { +template +class Heap; +} /* namespace JS */ + extern JS_FRIEND_API(void) JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data); @@ -48,7 +54,7 @@ extern JS_FRIEND_API(JSObject *) JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JSHandleObject obj); +JS_ObjectCountDynamicSlots(JS::HandleObject obj); extern JS_FRIEND_API(size_t) JS_SetProtoCalled(JSContext *cx); @@ -118,14 +124,27 @@ extern JS_FRIEND_API(JSObject *) JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(JSString *) -JS_BasicObjectToString(JSContext *cx, JSHandleObject obj); +JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); extern JS_FRIEND_API(JSBool) -js_GetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp); +js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JSBool strict, + JS::MutableHandleValue vp); JS_FRIEND_API(void) js_ReportOverRecursed(JSContext *maybecx); +JS_FRIEND_API(bool) +js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); + +JS_FRIEND_API(const char *) +js_ObjectClassName(JSContext *cx, JS::HandleObject obj); + +JS_FRIEND_API(bool) +js_AddObjectRoot(JSRuntime *rt, JSObject **objp); + +JS_FRIEND_API(void) +js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp); + #ifdef DEBUG /* @@ -157,7 +176,7 @@ extern JS_FRIEND_API(JSBool) JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props); extern JS_FRIEND_API(JSBool) -JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, +JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op, js::MutableHandleValue statep, js::MutableHandleId idp); struct JSFunctionSpecWithHelp { @@ -177,25 +196,24 @@ struct JSFunctionSpecWithHelp { extern JS_FRIEND_API(bool) JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs); -typedef bool (* JS_SourceHook)(JSContext *cx, JSScript *script, jschar **src, uint32_t *length); +typedef bool (* JS_SourceHook)(JSContext *cx, JS::Handle script, + jschar **src, uint32_t *length); extern JS_FRIEND_API(void) JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook); namespace js { -extern mozilla::ThreadLocal TlsPerThreadData; - inline JSRuntime * GetRuntime(const JSContext *cx) { - return ContextFriendFields::get(cx)->runtime; + return ContextFriendFields::get(cx)->runtime_; } inline JSCompartment * GetContextCompartment(const JSContext *cx) { - return ContextFriendFields::get(cx)->compartment; + return ContextFriendFields::get(cx)->compartment_; } inline JS::Zone * @@ -217,19 +235,6 @@ typedef bool extern JS_FRIEND_API(void) DumpHeapComplete(JSRuntime *rt, FILE *fp); -class JS_FRIEND_API(AutoSwitchCompartment) { - private: - JSContext *cx; - JSCompartment *oldCompartment; - public: - AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - AutoSwitchCompartment(JSContext *cx, JSHandleObject target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoSwitchCompartment(); - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - #ifdef OLD_GETTER_SETTER_METHODS JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, unsigned argc, js::Value *vp); JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, unsigned argc, js::Value *vp); @@ -254,6 +259,15 @@ IsAtomsCompartment(JSCompartment *comp); extern JS_FRIEND_API(bool) ReportIfUndeclaredVarAssignment(JSContext *cx, HandleString propname); +/* + * Returns whether we're in a non-strict property set (in that we're in a + * non-strict script and the bytecode we're on is a property set). The return + * value does NOT indicate any sort of exception was thrown: it's just a + * boolean. + */ +extern JS_FRIEND_API(bool) +IsInNonStrictPropertySet(JSContext *cx); + struct WeakMapTracer; /* @@ -301,7 +315,7 @@ IterateGrayObjects(JS::Zone *zone, GCThingCallback cellCallback, void *data); #ifdef JS_HAS_CTYPES extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(JSMallocSizeOfFun mallocSizeOf, JSObject *obj); +SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject *obj); #endif extern JS_FRIEND_API(JSCompartment *) @@ -321,8 +335,9 @@ struct TypeObject { }; struct BaseShape { - js::Class *clasp; - JSObject *parent; + js::Class *clasp; + JSObject *parent; + JSObject *_1; JSCompartment *compartment; }; @@ -365,19 +380,22 @@ struct Function { }; struct Atom { - size_t _; + static const size_t LENGTH_SHIFT = 4; + size_t lengthAndFlags; const jschar *chars; }; } /* namespace shadow */ -extern JS_FRIEND_DATA(js::Class) CallClass; -extern JS_FRIEND_DATA(js::Class) DeclEnvClass; -extern JS_FRIEND_DATA(js::Class) FunctionClass; -extern JS_FRIEND_DATA(js::Class) FunctionProxyClass; -extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectClass; +// These are equal to |&{Function,Object,OuterWindow}ProxyObject::class_|. Use +// them in places where you don't want to #include vm/ProxyObject.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) ObjectProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr; + +// This is equal to |&JSObject::class_|. Use it in places where you don't want +// to #include jsobj.h. +extern JS_FRIEND_DATA(js::Class* const) ObjectClassPtr; inline js::Class * GetObjectClass(JSObject *obj) @@ -401,9 +419,15 @@ IsOuterObject(JSObject *obj) { return !!GetObjectClass(obj)->ext.innerObject; } +JS_FRIEND_API(bool) +IsFunctionObject(JSObject *obj); + JS_FRIEND_API(bool) IsScopeObject(JSObject *obj); +JS_FRIEND_API(bool) +IsCallObject(JSObject *obj); + inline JSObject * GetObjectParent(JSObject *obj) { @@ -423,6 +447,13 @@ GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +// For legacy consumers only. This whole concept is going away soon. +JS_FRIEND_API(JSObject *) +DefaultObjectForContextOrNull(JSContext *cx); + +JS_FRIEND_API(void) +SetDefaultObjectForContext(JSContext *cx, JSObject *obj); + JS_FRIEND_API(void) NotifyAnimationActivity(JSObject *obj); @@ -469,11 +500,11 @@ inline bool GetObjectProto(JSContext *cx, JS::Handle obj, JS::MutableHandle proto) { js::Class *clasp = GetObjectClass(obj); - if (clasp == &js::ObjectProxyClass || - clasp == &js::OuterWindowProxyClass || - clasp == &js::FunctionProxyClass) + if (clasp == js::ObjectProxyClassPtr || + clasp == js::OuterWindowProxyClassPtr || + clasp == js::FunctionProxyClassPtr) { - return JS_GetPrototype(cx, obj, proto.address()); + return JS_GetPrototype(cx, obj, proto); } proto.set(reinterpret_cast(obj.get())->type->proto); @@ -535,6 +566,13 @@ GetAtomChars(JSAtom *atom) return reinterpret_cast(atom)->chars; } +inline size_t +GetAtomLength(JSAtom *atom) +{ + using shadow::Atom; + return reinterpret_cast(atom)->lengthAndFlags >> Atom::LENGTH_SHIFT; +} + inline JSLinearString * AtomToLinearString(JSAtom *atom) { @@ -589,6 +627,12 @@ GetNativeStackLimit(const JSRuntime *rt) return PerThreadDataFriendFields::getMainThread(rt)->nativeStackLimit; } +inline uintptr_t +GetNativeStackLimit(JSContext *cx) +{ + return GetNativeStackLimit(GetRuntime(cx)); +} + /* * These macros report a stack overflow and run |onerror| if we are close to * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little @@ -598,18 +642,15 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \ js_ReportOverRecursed(cx); \ onerror; \ } \ JS_END_MACRO -#define JS_CHECK_RECURSION_WITH_EXTRA_DONT_REPORT(cx, extra, onerror) \ +#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ JS_BEGIN_MACRO \ - uint8_t stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ - &stackDummy_ - (extra))) \ - { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ onerror; \ } \ JS_END_MACRO @@ -617,7 +658,7 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_CHROME_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ + if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \ &stackDummy_, \ 1024 * sizeof(size_t))) \ { \ @@ -754,13 +795,13 @@ extern JS_FRIEND_API(bool) IsContextRunningJS(JSContext *cx); typedef void -(* AnalysisPurgeCallback)(JSRuntime *rt, JSFlatString *desc); +(* AnalysisPurgeCallback)(JSRuntime *rt, JS::Handle desc); extern JS_FRIEND_API(AnalysisPurgeCallback) SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback); typedef JSBool -(* DOMInstanceClassMatchesProto)(JSHandleObject protoObject, uint32_t protoID, +(* DOMInstanceClassMatchesProto)(JS::HandleObject protoObject, uint32_t protoID, uint32_t depth); struct JSDOMCallbacks { DOMInstanceClassMatchesProto instanceClassMatchesProto; @@ -851,10 +892,10 @@ NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& targetFilter, NukeReferencesToWindow nukeReferencesToWindow); -/* Specify information about ListBase proxies in the DOM, for use by ICs. */ +/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ /* - * The ListBaseShadowsCheck function will be called to check if the property for + * The DOMProxyShadowsCheck function will be called to check if the property for * id should be gotten from the prototype, or if there is an own property that * shadows it. * If DoesntShadow is returned then the slot at listBaseExpandoSlot should @@ -873,25 +914,31 @@ struct ExpandoAndGeneration { generation(0) {} - Value expando; + void Unlink() + { + ++generation; + expando.setUndefined(); + } + + JS::Heap expando; uint32_t generation; }; -typedef enum ListBaseShadowsResult { +typedef enum DOMProxyShadowsResult { ShadowCheckFailed, Shadows, DoesntShadow, DoesntShadowUnique -} ListBaseShadowsResult; -typedef ListBaseShadowsResult -(* ListBaseShadowsCheck)(JSContext* cx, JSHandleObject object, JSHandleId id); +} DOMProxyShadowsResult; +typedef DOMProxyShadowsResult +(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); JS_FRIEND_API(void) -SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot, - ListBaseShadowsCheck listBaseShadowsCheck); +SetDOMProxyInformation(void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, + DOMProxyShadowsCheck domProxyShadowsCheck); -void *GetListBaseHandlerFamily(); -uint32_t GetListBaseExpandoSlot(); -ListBaseShadowsCheck GetListBaseShadowsCheck(); +void *GetDOMProxyHandlerFamily(); +uint32_t GetDOMProxyExpandoSlot(); +DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); } /* namespace js */ @@ -960,6 +1007,137 @@ enum ViewType { }; } /* namespace ArrayBufferView */ + +/* + * A helper for building up an ArrayBuffer object's data + * before creating the ArrayBuffer itself. Will do doubling + * based reallocation, up to an optional maximum growth given. + * + * When all the data has been appended, call getArrayBuffer, + * passing in the JSContext* for which the ArrayBuffer object + * is to be created. This also implicitly resets the builder, + * or it can be reset explicitly at any point by calling reset(). + */ +class ArrayBufferBuilder +{ + void *rawcontents_; + uint8_t *dataptr_; + uint32_t capacity_; + uint32_t length_; + public: + ArrayBufferBuilder() + : rawcontents_(NULL), + dataptr_(NULL), + capacity_(0), + length_(0) + { + } + + ~ArrayBufferBuilder() { + reset(); + } + + void reset() { + if (rawcontents_) + JS_free(NULL, rawcontents_); + rawcontents_ = dataptr_ = NULL; + capacity_ = length_ = 0; + } + + // will truncate if newcap is < length() + bool setCapacity(uint32_t newcap) { + if (!JS_ReallocateArrayBufferContents(NULL, newcap, &rawcontents_, &dataptr_)) + return false; + + capacity_ = newcap; + if (length_ > newcap) + length_ = newcap; + + return true; + } + + // Append datalen bytes from data to the current buffer. If we + // need to grow the buffer, grow by doubling the size up to a + // maximum of maxgrowth (if given). If datalen is greater than + // what the new capacity would end up as, then grow by datalen. + // + // The data parameter must not overlap with anything beyond the + // builder's current valid contents [0..length) + bool append(const uint8_t *newdata, uint32_t datalen, uint32_t maxgrowth = 0) { + if (length_ + datalen > capacity_) { + uint32_t newcap; + // double while under maxgrowth or if not specified + if (!maxgrowth || capacity_ < maxgrowth) + newcap = capacity_ * 2; + else + newcap = capacity_ + maxgrowth; + + // but make sure there's always enough to satisfy our request + if (newcap < length_ + datalen) + newcap = length_ + datalen; + + // did we overflow? + if (newcap < capacity_) + return false; + + if (!setCapacity(newcap)) + return false; + } + + // assert that the region isn't overlapping so we can memcpy; + JS_ASSERT(!areOverlappingRegions(newdata, datalen, dataptr_ + length_, datalen)); + + memcpy(dataptr_ + length_, newdata, datalen); + length_ += datalen; + + return true; + } + + uint8_t *data() { + return dataptr_; + } + + uint32_t length() { + return length_; + } + + uint32_t capacity() { + return capacity_; + } + + JSObject* getArrayBuffer(JSContext *cx) { + // we need to check for length_ == 0, because nothing may have been + // added + if (capacity_ > length_ || length_ == 0) { + if (!setCapacity(length_)) + return NULL; + } + + JSObject* obj = JS_NewArrayBufferWithContents(cx, rawcontents_); + if (!obj) + return NULL; + + rawcontents_ = dataptr_ = NULL; + length_ = capacity_ = 0; + + return obj; + } + +protected: + + static bool areOverlappingRegions(const uint8_t *start1, uint32_t length1, + const uint8_t *start2, uint32_t length2) + { + const uint8_t *end1 = start1 + length1; + const uint8_t *end2 = start2 + length2; + + const uint8_t *max_start = start1 > start2 ? start1 : start2; + const uint8_t *min_end = end1 < end2 ? end1 : end2; + + return max_start < min_end; + } +}; + } /* namespace js */ typedef js::ArrayBufferView::ViewType JSArrayBufferViewType; @@ -1296,26 +1474,116 @@ JS_GetDataViewByteLength(JSObject *obj); JS_FRIEND_API(void *) JS_GetDataViewData(JSObject *obj); +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitGetterOp. + */ +class JSJitGetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitGetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args.rval()) + {} + + explicit JSJitGetterCallArgs(JS::Rooted* rooted) + : JS::MutableHandleValue(rooted) + {} + + JS::MutableHandleValue rval() { + return *this; + } +}; + +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitSetterOp. + */ +class JSJitSetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitSetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args[0]) + {} + + JS::MutableHandleValue operator[](unsigned i) { + MOZ_ASSERT(i == 0); + return *this; + } + + unsigned length() const { return 1; } + + // Add get() or maybe hasDefined() as needed +}; + +struct JSJitMethodCallArgsTraits; + +/* + * A class, expected to be passed by reference, which represents the CallArgs + * for a JSJitMethodOp. + */ +class JSJitMethodCallArgs : protected JS::detail::CallArgsBase +{ + private: + typedef JS::detail::CallArgsBase Base; + friend struct JSJitMethodCallArgsTraits; + + public: + explicit JSJitMethodCallArgs(const JS::CallArgs& args) { + argv_ = args.array(); + argc_ = args.length(); + } + + JS::MutableHandleValue rval() const { + return Base::rval(); + } + + unsigned length() const { return Base::length(); } + + JS::MutableHandleValue operator[](unsigned i) const { + return Base::operator[](i); + } + + bool hasDefined(unsigned i) const { + return Base::hasDefined(i); + } + + // Add get() as needed +}; + +struct JSJitMethodCallArgsTraits +{ + static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); + static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); +}; + /* * This struct contains metadata passed from the DOM to the JS Engine for JIT * optimizations on DOM property accessors. Eventually, this should be made * available to general JSAPI users, but we are not currently ready to do so. */ typedef bool -(* JSJitPropertyOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, JS::Value *vp); +(* JSJitGetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitGetterCallArgs args); typedef bool -(* JSJitMethodOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, unsigned argc, JS::Value *vp); +(* JSJitSetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitSetterCallArgs args); +typedef bool +(* JSJitMethodOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, const JSJitMethodCallArgs& args); struct JSJitInfo { enum OpType { Getter, Setter, - Method + Method, + OpType_None }; - JSJitPropertyOp op; + union { + JSJitGetterOp getter; + JSJitSetterOp setter; + JSJitMethodOp method; + }; uint32_t protoID; uint32_t depth; OpType type; @@ -1325,12 +1593,18 @@ struct JSJitInfo { keep returning the same value for the given "this" object" */ JSValueType returnType; /* The return type tag. Might be JSVAL_TYPE_UNKNOWN */ + + /* An alternative native that's safe to call in parallel mode. */ + JSParallelNative parallelNative; }; +#define JS_JITINFO_NATIVE_PARALLEL(op) \ + {{NULL},0,0,JSJitInfo::OpType_None,false,false,false,JSVAL_TYPE_MISSING,op} + static JS_ALWAYS_INLINE const JSJitInfo * FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) { - JS_ASSERT(js::GetObjectClass(&v.toObject()) == &js::FunctionClass); + JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr); return reinterpret_cast(&v.toObject())->jitinfo; } @@ -1482,9 +1756,46 @@ assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id); inline void assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id) {}; #endif +typedef bool +(* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata); + +/* + * Specify a callback to invoke when creating each JS object in the current + * compartment, which may return a metadata object to associate with the + * object. Objects with different metadata have different shape hierarchies, + * so for efficiency, objects should generally try to share metadata objects. + */ +JS_FRIEND_API(void) +SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback); + +/* Manipulate the metadata associated with an object. */ + +JS_FRIEND_API(bool) +SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata); + +JS_FRIEND_API(JSObject *) +GetObjectMetadata(JSObject *obj); + /* ES5 8.12.8. */ extern JS_FRIEND_API(JSBool) -DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); +DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValue vp); + +/* + * Helper function. To approximate a call to the [[DefineOwnProperty]] internal + * method described in ES5, first call this, then call JS_DefinePropertyById. + * + * JS_DefinePropertyById by itself does not enforce the invariants on + * non-configurable properties when obj->isNative(). This function performs the + * relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11), + * but only if obj is native. + * + * The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as + * a sort of extension point, but there is no hook in js::Class, + * js::ProxyHandler, or the JSAPI with precisely the right semantics for it. + */ +extern JS_FRIEND_API(bool) +CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, + PropertyOp getter, StrictPropertyOp setter, unsigned attrs); } /* namespace js */ @@ -1495,4 +1806,26 @@ js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, extern JS_FRIEND_API(JSBool) js_ReportIsNotFunction(JSContext *cx, const JS::Value& v); -#endif /* jsfriendapi_h___ */ +#ifdef JSGC_GENERATIONAL +extern JS_FRIEND_API(void) +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data); + +extern JS_FRIEND_API(void) +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data); +#else +inline void +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data) {} + +inline void +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data) {} +#endif /* JSGC_GENERATIONAL */ + +#endif /* jsfriendapi_h */ diff --git a/external/spidermonkey/include/ios/jslock.h b/external/spidermonkey/include/ios/jslock.h index b4a28a9fa9..522034ad68 100644 --- a/external/spidermonkey/include/ios/jslock.h +++ b/external/spidermonkey/include/ios/jslock.h @@ -4,18 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jslock_h__ -#define jslock_h__ - -#include "jsapi.h" +#ifndef jslock_h +#define jslock_h #ifdef JS_THREADSAFE +# include "jsapi.h" # include "pratom.h" -# include "prlock.h" # include "prcvar.h" -# include "prthread.h" # include "prinit.h" +# include "prlock.h" +# include "prthread.h" # define JS_ATOMIC_INCREMENT(p) PR_ATOMIC_INCREMENT((int32_t *)(p)) # define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p)) @@ -40,4 +39,4 @@ typedef struct PRLock PRLock; #endif /* JS_THREADSAFE */ -#endif /* jslock_h___ */ +#endif /* jslock_h */ diff --git a/external/spidermonkey/include/ios/json.h b/external/spidermonkey/include/ios/json.h deleted file mode 100644 index 7fa2c117c8..0000000000 --- a/external/spidermonkey/include/ios/json.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef json_h___ -#define json_h___ - -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsapi.h" - -#include "js/Vector.h" - -#define JSON_MAX_DEPTH 2048 -#define JSON_PARSER_BUFSIZE 1024 - -extern JSObject * -js_InitJSONClass(JSContext *cx, js::HandleObject obj); - -extern JSBool -js_Stringify(JSContext *cx, js::MutableHandleValue vp, - JSObject *replacer, js::Value space, - js::StringBuffer &sb); - -// Avoid build errors on certain platforms that define these names as constants -#undef STRICT -#undef LEGACY - -/* - * The type of JSON decoding to perform. Strict decoding is to-the-spec; - * legacy decoding accepts a few non-JSON syntaxes historically accepted by the - * implementation. (Full description of these deviations is deliberately - * omitted.) New users should use strict decoding rather than legacy decoding, - * as legacy decoding might be removed at a future time. - */ -enum DecodingMode { STRICT, LEGACY }; - -namespace js { - -extern JS_FRIEND_API(JSBool) -ParseJSONWithReviver(JSContext *cx, JS::StableCharPtr chars, size_t length, HandleValue filter, - MutableHandleValue vp, DecodingMode decodingMode = STRICT); - -} /* namespace js */ - -#endif /* json_h___ */ diff --git a/external/spidermonkey/include/ios/jsperf.h b/external/spidermonkey/include/ios/jsperf.h index a0287b4a57..468ce8609c 100644 --- a/external/spidermonkey/include/ios/jsperf.h +++ b/external/spidermonkey/include/ios/jsperf.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsperf_h___ -#define jsperf_h___ +#ifndef perf_jsperf_h +#define perf_jsperf_h #include "jsapi.h" @@ -127,4 +127,4 @@ extern JS_FRIEND_API(PerfMeasurement*) } // namespace JS -#endif // jsperf_h___ +#endif /* perf_jsperf_h */ diff --git a/external/spidermonkey/include/ios/jsprf.h b/external/spidermonkey/include/ios/jsprf.h index c0891f0e9e..ce159d8115 100644 --- a/external/spidermonkey/include/ios/jsprf.h +++ b/external/spidermonkey/include/ios/jsprf.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprf_h___ -#define jsprf_h___ +#ifndef jsprf_h +#define jsprf_h /* ** API for PR printf like routines. Supports the following formats @@ -24,9 +24,11 @@ ** %f - float ** %g - float */ -#include "jstypes.h" -#include + #include +#include + +#include "jstypes.h" /* ** sprintf into a fixed size buffer. Guarantees that a NUL is at the end @@ -75,4 +77,4 @@ extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); extern JS_PUBLIC_API(uint32_t) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); -#endif /* jsprf_h___ */ +#endif /* jsprf_h */ diff --git a/external/spidermonkey/include/ios/jsprototypes.h b/external/spidermonkey/include/ios/jsprototypes.h index 007d25d720..f9bacac409 100644 --- a/external/spidermonkey/include/ios/jsprototypes.h +++ b/external/spidermonkey/include/ios/jsprototypes.h @@ -6,8 +6,8 @@ /* A higher-order macro for enumerating all JSProtoKey values. */ -#ifndef jsprototypes_h___ -#define jsprototypes_h___ +#ifndef jsprototypes_h +#define jsprototypes_h #include "jsversion.h" @@ -56,5 +56,20 @@ macro(DataView, 35, js_InitTypedArrayClasses) \ macro(ParallelArray, 36, js_InitParallelArrayClass) \ macro(Intl, 37, js_InitIntlClass) \ + macro(Type, 38, js_InitBinaryDataClasses) \ + macro(Data, 39, js_InitBinaryDataClasses) \ + macro(uint8, 40, js_InitBinaryDataClasses) \ + macro(uint16, 41, js_InitBinaryDataClasses) \ + macro(uint32, 42, js_InitBinaryDataClasses) \ + macro(uint64, 43, js_InitBinaryDataClasses) \ + macro(int8, 44, js_InitBinaryDataClasses) \ + macro(int16, 45, js_InitBinaryDataClasses) \ + macro(int32, 46, js_InitBinaryDataClasses) \ + macro(int64, 47, js_InitBinaryDataClasses) \ + macro(float32, 48, js_InitBinaryDataClasses) \ + macro(float64, 49, js_InitBinaryDataClasses) \ + macro(ArrayType, 50, js_InitBinaryDataClasses) \ + macro(StructType, 51, js_InitBinaryDataClasses) \ + macro(ArrayTypeObject, 52, js_InitBinaryDataClasses) \ -#endif /* jsprototypes_h___ */ +#endif /* jsprototypes_h */ diff --git a/external/spidermonkey/include/ios/jsproxy.h b/external/spidermonkey/include/ios/jsproxy.h index 399490eddc..56868a05c3 100644 --- a/external/spidermonkey/include/ios/jsproxy.h +++ b/external/spidermonkey/include/ios/jsproxy.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsproxy_h___ -#define jsproxy_h___ +#ifndef jsproxy_h +#define jsproxy_h #include "jsapi.h" #include "jsfriendapi.h" @@ -129,7 +129,7 @@ class JS_FRIEND_API(BaseProxyHandler) MutableHandleValue vp); /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) = 0; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) = 0; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -190,7 +190,7 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -242,7 +242,7 @@ class Proxy static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); /* Spidermonkey extensions. */ - static bool isExtensible(JSObject *proxy); + static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -259,12 +259,17 @@ class Proxy inline bool IsObjectProxyClass(const Class *clasp) { - return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass; + return clasp == js::ObjectProxyClassPtr || clasp == js::OuterWindowProxyClassPtr; } inline bool IsFunctionProxyClass(const Class *clasp) { - return clasp == &js::FunctionProxyClass; + return clasp == js::FunctionProxyClassPtr; +} + +inline bool IsProxyClass(const Class *clasp) +{ + return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); } inline bool IsObjectProxy(JSObject *obj) @@ -279,36 +284,33 @@ inline bool IsFunctionProxy(JSObject *obj) inline bool IsProxy(JSObject *obj) { - Class *clasp = GetObjectClass(obj); - return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); + return IsProxyClass(GetObjectClass(obj)); } -/* Shared between object and function proxies. */ /* - * NOTE: JSSLOT_PROXY_PRIVATE is 0, because that way slot 0 is usable by API + * These are part of the API. + * + * NOTE: PROXY_PRIVATE_SLOT is 0 because that way slot 0 is usable by API * clients for both proxy and non-proxy objects. So an API client that only * needs to store one slot's worth of data doesn't need to branch on what sort * of object it has. */ -const uint32_t JSSLOT_PROXY_PRIVATE = 0; -const uint32_t JSSLOT_PROXY_HANDLER = 1; -const uint32_t JSSLOT_PROXY_EXTRA = 2; -/* Function proxies only. */ -const uint32_t JSSLOT_PROXY_CALL = 4; -const uint32_t JSSLOT_PROXY_CONSTRUCT = 5; +const uint32_t PROXY_PRIVATE_SLOT = 0; +const uint32_t PROXY_HANDLER_SLOT = 1; +const uint32_t PROXY_EXTRA_SLOT = 2; inline BaseProxyHandler * GetProxyHandler(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return (BaseProxyHandler *) GetReservedSlot(obj, JSSLOT_PROXY_HANDLER).toPrivate(); + return (BaseProxyHandler *) GetReservedSlot(obj, PROXY_HANDLER_SLOT).toPrivate(); } inline const Value & GetProxyPrivate(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE); + return GetReservedSlot(obj, PROXY_PRIVATE_SLOT); } inline JSObject * @@ -322,14 +324,14 @@ inline const Value & GetProxyExtra(JSObject *obj, size_t n) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n); + return GetReservedSlot(obj, PROXY_EXTRA_SLOT + n); } inline void SetProxyHandler(JSObject *obj, BaseProxyHandler *handler) { JS_ASSERT(IsProxy(obj)); - SetReservedSlot(obj, JSSLOT_PROXY_HANDLER, PrivateValue(handler)); + SetReservedSlot(obj, PROXY_HANDLER_SLOT, PrivateValue(handler)); } inline void @@ -337,7 +339,7 @@ SetProxyExtra(JSObject *obj, size_t n, const Value &extra) { JS_ASSERT(IsProxy(obj)); JS_ASSERT(n <= 1); - SetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n, extra); + SetReservedSlot(obj, PROXY_EXTRA_SLOT + n, extra); } enum ProxyCallable { @@ -346,7 +348,7 @@ enum ProxyCallable { }; JS_FRIEND_API(JSObject *) -NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv, +NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto, JSObject *parent, ProxyCallable callable = ProxyNotCallable); JSObject * @@ -426,6 +428,6 @@ class JS_FRIEND_API(AutoWaivePolicy) { } /* namespace js */ extern JS_FRIEND_API(JSObject *) -js_InitProxyClass(JSContext *cx, JSHandleObject obj); +js_InitProxyClass(JSContext *cx, JS::HandleObject obj); -#endif +#endif /* jsproxy_h */ diff --git a/external/spidermonkey/include/ios/jsprvtd.h b/external/spidermonkey/include/ios/jsprvtd.h index 4db5ed8c36..1fbc086a7c 100644 --- a/external/spidermonkey/include/ios/jsprvtd.h +++ b/external/spidermonkey/include/ios/jsprvtd.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprvtd_h___ -#define jsprvtd_h___ +#ifndef jsprvtd_h +#define jsprvtd_h /* * JS private typename definitions. * @@ -56,13 +56,7 @@ typedef struct JSStackHeader JSStackHeader; typedef struct JSSubString JSSubString; typedef struct JSSpecializedNative JSSpecializedNative; -/* - * Template declarations. - * - * jsprvtd.h can be included in both C and C++ translation units. For C++, it - * may possibly be wrapped in an extern "C" block which does not agree with - * templates. - */ +/* String typedefs. */ class JSDependentString; class JSExtensibleString; class JSExternalString; @@ -76,6 +70,7 @@ namespace js { struct ArgumentsData; struct Class; +class AutoNameVector; class RegExpGuard; class RegExpObject; class RegExpObjectBuilder; @@ -83,6 +78,7 @@ class RegExpShared; class RegExpStatics; class MatchPairs; class PropertyName; +class LazyScript; enum RegExpFlag { @@ -95,19 +91,14 @@ enum RegExpFlag AllFlags = 0x0f }; -class ExecuteArgsGuard; -class InvokeFrameGuard; -class InvokeArgsGuard; class StringBuffer; class FrameRegs; class StackFrame; -class StackSegment; -class StackSpace; -class ContextStack; class ScriptFrameIter; class Proxy; +class JS_FRIEND_API(AutoEnterPolicy); class JS_FRIEND_API(BaseProxyHandler); class JS_FRIEND_API(Wrapper); class JS_FRIEND_API(CrossCompartmentWrapper); @@ -140,24 +131,29 @@ class WatchpointMap; typedef JSObject Env; typedef JSNative Native; +typedef JSParallelNative ParallelNative; +typedef JSThreadSafeNative ThreadSafeNative; typedef JSPropertyOp PropertyOp; typedef JSStrictPropertyOp StrictPropertyOp; typedef JSPropertyDescriptor PropertyDescriptor; +struct SourceCompressionToken; + namespace frontend { struct BytecodeEmitter; struct Definition; +class FullParseHandler; class FunctionBox; class ObjectBox; struct Token; struct TokenPos; class TokenStream; class ParseMapPool; -struct ParseNode; +class ParseNode; template -struct Parser; +class Parser; } /* namespace frontend */ @@ -284,18 +280,18 @@ typedef void * if an error or exception was thrown on cx. */ typedef JSObject * -(* JSObjectOp)(JSContext *cx, JSHandleObject obj); +(* JSObjectOp)(JSContext *cx, JS::Handle obj); /* Signature for class initialization ops. */ typedef JSObject * -(* JSClassInitializerOp)(JSContext *cx, JSHandleObject obj); +(* JSClassInitializerOp)(JSContext *cx, JS::HandleObject obj); /* * Hook that creates an iterator object for a given object. Returns the * iterator object or null if an error or exception was thrown on cx. */ typedef JSObject * -(* JSIteratorOp)(JSContext *cx, JSHandleObject obj, JSBool keysonly); +(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, JSBool keysonly); -#endif /* jsprvtd_h___ */ +#endif /* jsprvtd_h */ diff --git a/external/spidermonkey/include/ios/jspubtd.h b/external/spidermonkey/include/ios/jspubtd.h index 6b7e63e6ba..96f5dd8297 100644 --- a/external/spidermonkey/include/ios/jspubtd.h +++ b/external/spidermonkey/include/ios/jspubtd.h @@ -4,16 +4,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jspubtd_h___ -#define jspubtd_h___ +#ifndef jspubtd_h +#define jspubtd_h /* * JS public API typedefs. */ +#include "mozilla/PodOperations.h" + #include "jsprototypes.h" #include "jstypes.h" +#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) +# define JSGC_TRACK_EXACT_ROOTS +#endif + namespace JS { /* @@ -25,6 +31,8 @@ class Value; template class Rooted; +class JS_PUBLIC_API(AutoGCRooter); + struct Zone; } /* namespace JS */ @@ -44,10 +52,8 @@ struct Zone; * oblivious to the change. This feature can be explicitly disabled in debug * builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. */ - // Needed for cocos2d-js -#define JS_NO_JSVAL_JSID_STRUCT_TYPES - +#define JS_NO_JSVAL_JSID_STRUCT_TYPES # if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) # define JS_USE_JSID_STRUCT_TYPES # endif @@ -154,9 +160,10 @@ typedef enum { JSTRACE_SCRIPT, /* - * Trace kinds internal to the engine. The embedding can only them if it - * implements JSTraceCallback. + * Trace kinds internal to the engine. The embedding can only see them if + * it implements JSTraceCallback. */ + JSTRACE_LAZY_SCRIPT, JSTRACE_IONCODE, JSTRACE_SHAPE, JSTRACE_BASE_SHAPE, @@ -229,6 +236,18 @@ struct Runtime namespace js { +/* + * Parallel operations in general can have one of three states. They may + * succeed, fail, or "bail", where bail indicates that the code encountered an + * unexpected condition and should be re-run sequentially. Different + * subcategories of the "bail" state are encoded as variants of TP_RETRY_*. + */ +enum ParallelResult { TP_SUCCESS, TP_RETRY_SEQUENTIALLY, TP_RETRY_AFTER_GC, TP_FATAL }; + +struct ThreadSafeContext; +struct ForkJoinSlice; +class ExclusiveContext; + class Allocator; class SkipRoot; @@ -273,18 +292,28 @@ template <> struct RootKind : SpecificRootKind struct RootKind : SpecificRootKind {}; template <> struct RootKind : SpecificRootKind {}; -struct ContextFriendFields { - JSRuntime *const runtime; +struct ContextFriendFields +{ + protected: + JSRuntime *const runtime_; /* The current compartment. */ - JSCompartment *compartment; + JSCompartment *compartment_; /* The current zone. */ JS::Zone *zone_; + public: explicit ContextFriendFields(JSRuntime *rt) - : runtime(rt), compartment(NULL), zone_(NULL) - { } + : runtime_(rt), compartment_(NULL), zone_(NULL), autoGCRooters(NULL) + { +#ifdef JSGC_TRACK_EXACT_ROOTS + mozilla::PodArrayZero(thingGCRooters); +#endif +#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) + skipGCRooters = NULL; +#endif + } static const ContextFriendFields *get(const JSContext *cx) { return reinterpret_cast(cx); @@ -294,7 +323,7 @@ struct ContextFriendFields { return reinterpret_cast(cx); } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -313,6 +342,13 @@ struct ContextFriendFields { */ SkipRoot *skipGCRooters; #endif + + /* Stack of thread-stack-allocated GC roots. */ + JS::AutoGCRooter *autoGCRooters; + + friend JSRuntime *GetRuntime(const JSContext *cx); + friend JSCompartment *GetContextCompartment(const JSContext *cx); + friend JS::Zone *GetContextZone(const JSContext *cx); }; class PerThreadData; @@ -338,7 +374,7 @@ struct PerThreadDataFriendFields PerThreadDataFriendFields(); -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -384,4 +420,4 @@ struct PerThreadDataFriendFields } /* namespace js */ -#endif /* jspubtd_h___ */ +#endif /* jspubtd_h */ diff --git a/external/spidermonkey/include/ios/jstypes.h b/external/spidermonkey/include/ios/jstypes.h index e4c02f8d8d..17f67f70e1 100644 --- a/external/spidermonkey/include/ios/jstypes.h +++ b/external/spidermonkey/include/ios/jstypes.h @@ -18,8 +18,8 @@ ** for all C files. **/ -#ifndef jstypes_h___ -#define jstypes_h___ +#ifndef jstypes_h +#define jstypes_h #include "mozilla/Attributes.h" #include "mozilla/Util.h" @@ -279,4 +279,4 @@ typedef int JSBool; # define JS_EXTENSION_(s) s #endif -#endif /* jstypes_h___ */ +#endif /* jstypes_h */ diff --git a/external/spidermonkey/include/ios/jsutil.h b/external/spidermonkey/include/ios/jsutil.h index 49e1641c61..4020822be1 100644 --- a/external/spidermonkey/include/ios/jsutil.h +++ b/external/spidermonkey/include/ios/jsutil.h @@ -8,19 +8,19 @@ * PR assertion checker. */ -#ifndef jsutil_h___ -#define jsutil_h___ +#ifndef jsutil_h +#define jsutil_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/GuardObjects.h" -#include "js/Utility.h" - #ifdef USE_ZLIB -#include "zlib.h" +#include #endif +#include "js/Utility.h" + /* Forward declarations. */ struct JSContext; @@ -204,15 +204,6 @@ UnsignedPtrDiff(const void *bigger, const void *smaller) return size_t(bigger) - size_t(smaller); } -/* - * Ordinarily, a function taking a JSContext* 'cx' parameter reports errors on - * the context. In some cases, functions optionally report and indicate this by - * taking a nullable 'maybecx' parameter. In some cases, though, a function - * always needs a 'cx', but optionally reports. This option is presented by the - * MaybeReportError. - */ -enum MaybeReportError { REPORT_ERROR = true, DONT_REPORT_ERROR = false }; - /*****************************************************************************/ /* A bit array is an array of bits represented by an array of words (size_t). */ @@ -391,4 +382,4 @@ typedef size_t jsbitmap; JS_END_MACRO #endif -#endif /* jsutil_h___ */ +#endif /* jsutil_h */ diff --git a/external/spidermonkey/include/ios/jsversion.h b/external/spidermonkey/include/ios/jsversion.h index f3169fb5d1..1780616a32 100644 --- a/external/spidermonkey/include/ios/jsversion.h +++ b/external/spidermonkey/include/ios/jsversion.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsversion_h___ -#define jsversion_h___ +#ifndef jsversion_h +#define jsversion_h /* * Deprecated JS_VERSION handler. @@ -61,7 +61,7 @@ # define NEW_OBJECT_REPRESENTATION_ONLY() ((void)0) #else # define NEW_OBJECT_REPRESENTATION_ONLY() \ - MOZ_NOT_REACHED("don't call this! to be used in the new object representation") + MOZ_ASSUME_UNREACHABLE("don't call this! to be used in the new object representation") #endif -#endif /* jsversion_h___ */ +#endif /* jsversion_h */ diff --git a/external/spidermonkey/include/ios/jswrapper.h b/external/spidermonkey/include/ios/jswrapper.h index d0c0fc625c..f78df7db60 100644 --- a/external/spidermonkey/include/ios/jswrapper.h +++ b/external/spidermonkey/include/ios/jswrapper.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jswrapper_h___ -#define jswrapper_h___ +#ifndef jswrapper_h +#define jswrapper_h #include "mozilla/Attributes.h" @@ -66,8 +66,6 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler static Wrapper singleton; static Wrapper singletonWithPrototype; - - static void *getWrapperFamily(); }; /* Base class for all cross compartment wrapper handlers. */ @@ -105,7 +103,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -139,7 +137,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base public: SecurityWrapper(unsigned flags); - virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) MOZ_OVERRIDE; @@ -185,7 +183,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -297,4 +295,4 @@ struct JS_FRIEND_API(AutoMaybeTouchDeadZones) } /* namespace js */ -#endif +#endif /* jswrapper_h */ diff --git a/external/spidermonkey/include/ios/mozilla/AllocPolicy.h b/external/spidermonkey/include/ios/mozilla/AllocPolicy.h new file mode 100644 index 0000000000..20087e93bb --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/AllocPolicy.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * An allocation policy concept, usable for structures and algorithms to + * control how memory is allocated and how failures are handled. + */ + +#ifndef mozilla_AllocPolicy_h +#define mozilla_AllocPolicy_h + +#include +#include + +namespace mozilla { + +/* + * Allocation policies are used to implement the standard allocation behaviors + * in a customizable way. Additionally, custom behaviors may be added to these + * behaviors, such as additionally reporting an error through an out-of-band + * mechanism when OOM occurs. The concept modeled here is as follows: + * + * - public copy constructor, assignment, destructor + * - void* malloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* calloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* realloc_(void*, size_t, size_t) + * Responsible for OOM reporting when null is returned. The *used* bytes + * of the previous buffer is passed in (rather than the old allocation + * size), in addition to the *new* allocation size requested. + * - void free_(void*) + * - void reportAllocOverflow() const + * Called on allocation overflow (that is, an allocation implicitly tried + * to allocate more than the available memory space -- think allocating an + * array of large-size objects, where N * size overflows) before null is + * returned. + * + * mfbt provides (and typically uses by default) only MallocAllocPolicy, which + * does nothing more than delegate to the malloc/alloc/free functions. + */ + +/* + * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no + * extra behaviors. + */ +class MallocAllocPolicy +{ + public: + void* malloc_(size_t bytes) { return malloc(bytes); } + void* calloc_(size_t bytes) { return calloc(bytes, 1); } + void* realloc_(void* p, size_t oldBytes, size_t bytes) { return realloc(p, bytes); } + void free_(void* p) { free(p); } + void reportAllocOverflow() const {} +}; + + +} // namespace mozilla + +#endif /* mozilla_AllocPolicy_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Array.h b/external/spidermonkey/include/ios/mozilla/Array.h new file mode 100644 index 0000000000..5af9aaa133 --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/Array.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A compile-time constant-length array with bounds-checking assertions. */ + +#ifndef mozilla_Array_h +#define mozilla_Array_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" + +#include + +namespace mozilla { + +template +class Array +{ + T arr[Length]; + + public: + T& operator[](size_t i) { + MOZ_ASSERT(i < Length); + return arr[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(i < Length); + return arr[i]; + } +}; + +template +class Array +{ + public: + T& operator[](size_t i) { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } + + const T& operator[](size_t i) const { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } +}; + +} /* namespace mozilla */ + +#endif /* mozilla_Array_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Assertions.h b/external/spidermonkey/include/ios/mozilla/Assertions.h index 5ead7f493e..00b7037802 100644 --- a/external/spidermonkey/include/ios/mozilla/Assertions.h +++ b/external/spidermonkey/include/ios/mozilla/Assertions.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of runtime and static assertion macros for C and C++. */ -#ifndef mozilla_Assertions_h_ -#define mozilla_Assertions_h_ +#ifndef mozilla_Assertions_h +#define mozilla_Assertions_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" @@ -39,44 +40,24 @@ #endif /* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time*. This - * can be useful when you make certain assumptions about what must hold for + * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. + * In C++11, static_assert is provided by the compiler to the same effect. + * This can be useful when you make certain assumptions about what must hold for * optimal, or even correct, behavior. For example, you might assert that the * size of a struct is a multiple of the target architecture's word size: * * struct S { ... }; + * // C * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, * "S should be a multiple of word size for efficiency"); + * // C++11 + * static_assert(sizeof(S) % sizeof(size_t) == 0, + * "S should be a multiple of word size for efficiency"); * * This macro can be used in any location where both an extern declaration and a * typedef could be used. - * - * Be aware of the gcc 4.2 concerns noted further down when writing patches that - * use this macro, particularly if a patch only bounces on OS X. */ -#ifdef __cplusplus -# if defined(__clang__) -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_extension(cxx_static_assert) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__GNUC__) -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(_MSC_VER) -# if _MSC_VER >= 1600 /* MSVC 10 */ -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__HP_aCC) -# if __HP_aCC >= 62500 && defined(_HP_CXX0x_SOURCE) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# endif -#endif -#ifndef MOZ_STATIC_ASSERT +#ifndef __cplusplus /* * Some of the definitions below create an otherwise-unused typedef. This * triggers compiler warnings with some versions of gcc, so mark the typedefs @@ -124,78 +105,23 @@ # define MOZ_STATIC_ASSERT(cond, reason) \ extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE # endif -#endif #define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) +#else +#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) +#endif #ifdef __cplusplus extern "C" { #endif -/* - * MOZ_CRASH crashes the program, plain and simple, in a Breakpad-compatible - * way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. We use TerminateProcess - * with the exit code aborting would generate because we don't want to invoke - * atexit handlers, destructors, library unload handlers, and so on when our - * process might be in a compromised state. We don't use abort() because - * it'd cause Windows to annoyingly pop up the process error dialog multiple - * times. See bug 345118 and bug 426163. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - TerminateProcess(GetCurrentProcess(), 3); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - ::abort(); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - abort(); \ - } while (0) -# endif -#endif - /* * Prints |s| as an assertion failure (using file and ln as the location of the * assertion) to the standard debug-output channel. * - * Usually you should use MOZ_ASSERT instead of this method. This method is - * primarily for internal use in this header, and only secondarily for use in - * implementing release-build assertions. + * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This + * method is primarily for internal use in this header, and only secondarily + * for use in implementing release-build assertions. */ static MOZ_ALWAYS_INLINE void MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) @@ -209,6 +135,112 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif } +static MOZ_ALWAYS_INLINE void +MOZ_ReportCrash(const char* s, const char* file, int ln) +{ +#ifdef ANDROID + __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", + "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); + fflush(stderr); +#endif +} + +/** + * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should + * call MOZ_CRASH instead. + */ +#if defined(_MSC_VER) + /* + * On MSVC use the __debugbreak compiler intrinsic, which produces an inline + * (not nested in a system function) breakpoint. This distinctively invokes + * Breakpad without requiring system library symbols on all stack-processing + * machines, as a nested breakpoint would require. + * + * We use TerminateProcess with the exit code aborting would generate + * because we don't want to invoke atexit handlers, destructors, library + * unload handlers, and so on when our process might be in a compromised + * state. + * + * We don't use abort() because it'd cause Windows to annoyingly pop up the + * process error dialog multiple times. See bug 345118 and bug 426163. + * + * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the + * compiler doesn't hassle us to provide a return statement after a + * MOZ_REALLY_CRASH() call. + * + * (Technically these are Windows requirements, not MSVC requirements. But + * practically you need MSVC for debugging, and we only ship builds created + * by MSVC, so doing it this way reduces complexity.) + */ + +__declspec(noreturn) __inline void MOZ_NoReturn() {} + +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + ::TerminateProcess(::GetCurrentProcess(), 3); \ + ::MOZ_NoReturn(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + TerminateProcess(GetCurrentProcess(), 3); \ + MOZ_NoReturn(); \ + } while (0) +# endif +#else +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + ::abort(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + abort(); \ + } while (0) +# endif +#endif + +/* + * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a + * Breakpad-compatible way, in both debug and release builds. + * + * MOZ_CRASH is a good solution for "handling" failure cases when you're + * unwilling or unable to handle them more cleanly -- for OOM, for likely memory + * corruption, and so on. It's also a good solution if you need safe behavior + * in release builds as well as debug builds. But if the failure is one that + * should be debugged and fixed, MOZ_ASSERT is generally preferable. + * + * The optional explanation-string, if provided, must be a string literal + * explaining why we're crashing. This argument is intended for use with + * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's + * obvious why we're crashing. + * + * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an + * explanation-string, we print the string to stderr. Otherwise, we don't + * print anything; this is because we want MOZ_CRASH to be 100% safe in release + * builds, and it's hard to print to stderr safely when memory might have been + * corrupted. + */ +#ifndef DEBUG +# define MOZ_CRASH(...) MOZ_REALLY_CRASH() +#else +# define MOZ_CRASH(...) \ + do { \ + MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ + MOZ_REALLY_CRASH(); \ + } while(0) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif @@ -251,7 +283,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* Now the two-argument form. */ @@ -259,7 +291,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* And now, helper macrology up the wazoo. */ @@ -310,14 +342,14 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif /* - * MOZ_NOT_REACHED_MARKER() expands to an expression which states that it is + * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that it is * undefined behavior for execution to reach this point. No guarantees are made * about what will happen if this is reached at runtime. Most code should - * probably use the higher level MOZ_NOT_REACHED, which uses this when + * probably use the higher level MOZ_ASSUME_UNREACHABLE, which uses this when * appropriate. */ #if defined(__clang__) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() #elif defined(__GNUC__) /* * __builtin_unreachable() was implemented in gcc 4.5. If we don't have @@ -325,49 +357,71 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) * in C++ in case there's another abort() visible in local scope. */ # if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() # else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif # endif #elif defined(_MSC_VER) -# define MOZ_NOT_REACHED_MARKER() __assume(0) +# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) #else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif #endif /* - * MOZ_NOT_REACHED(reason) indicates that the given point can't be reached - * during execution: simply reaching that point in execution is a bug. It takes - * as an argument an error message indicating the reason why that point should - * not have been reachable. + * MOZ_ASSUME_UNREACHABLE([reason]) tells the compiler that it can assume that + * the macro call cannot be reached during execution. This lets the compiler + * generate better-optimized code under some circumstances, at the expense of + * the program's behavior being undefined if control reaches the + * MOZ_ASSUME_UNREACHABLE. * - * // ...in a language parser... - * void handle(BooleanLiteralNode node) + * In Gecko, you probably should not use this macro outside of performance- or + * size-critical code, because it's unsafe. If you don't care about code size + * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. + * + * SpiderMonkey is a different beast, and there it's acceptable to use + * MOZ_ASSUME_UNREACHABLE more widely. + * + * Note that MOZ_ASSUME_UNREACHABLE is noreturn, so it's valid not to return a + * value following a MOZ_ASSUME_UNREACHABLE call. + * + * Example usage: + * + * enum ValueType { + * VALUE_STRING, + * VALUE_INT, + * VALUE_FLOAT + * }; + * + * int ptrToInt(ValueType type, void* value) { * { - * if (node.isTrue()) - * handleTrueLiteral(); - * else if (node.isFalse()) - * handleFalseLiteral(); - * else - * MOZ_NOT_REACHED("boolean literal that's not true or false?"); + * // We know for sure that type is either INT or FLOAT, and we want this + * // code to run as quickly as possible. + * switch (type) { + * case VALUE_INT: + * return *(int*) value; + * case VALUE_FLOAT: + * return (int) *(float*) value; + * default: + * MOZ_ASSUME_UNREACHABLE("can only handle VALUE_INT and VALUE_FLOAT"); + * } * } */ #if defined(DEBUG) -# define MOZ_NOT_REACHED(reason) \ +# define MOZ_ASSUME_UNREACHABLE(...) \ do { \ - MOZ_ASSERT(false, reason); \ - MOZ_NOT_REACHED_MARKER(); \ + MOZ_ASSERT(false, "MOZ_ASSUME_UNREACHABLE(" __VA_ARGS__ ")"); \ + MOZ_ASSUME_UNREACHABLE_MARKER(); \ } while (0) #else -# define MOZ_NOT_REACHED(reason) MOZ_NOT_REACHED_MARKER() +# define MOZ_ASSUME_UNREACHABLE(reason) MOZ_ASSUME_UNREACHABLE_MARKER() #endif /* @@ -384,4 +438,4 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) # define MOZ_ALWAYS_FALSE(expr) ((void)(expr)) #endif -#endif /* mozilla_Assertions_h_ */ +#endif /* mozilla_Assertions_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Atomics.h b/external/spidermonkey/include/ios/mozilla/Atomics.h new file mode 100644 index 0000000000..f876683c3e --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/Atomics.h @@ -0,0 +1,1014 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Implements (almost always) lock-free atomic operations. The operations here + * are a subset of that which can be found in C++11's header, with a + * different API to enforce consistent memory ordering constraints. + * + * Anyone caught using |volatile| for inter-thread memory safety needs to be + * sent a copy of this header and the C++11 standard. + */ + +#ifndef mozilla_Atomics_h +#define mozilla_Atomics_h + +#include "mozilla/Assertions.h" +#include "mozilla/TypeTraits.h" + +#include + +/* + * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK + * does not have . So be sure to check for support + * along with C++0x support. + */ +#if defined(__clang__) + /* + * clang doesn't like libstdc++'s version of before GCC 4.7, + * due to the loose typing of the __sync_* family of functions done by + * GCC. We do not have a particularly good way to detect this sort of + * case at this point, so just assume that if we're on a Linux system, + * we can't use the system's . + * + * OpenBSD uses an old libstdc++ 4.2.1 and thus doesnt have . + */ +# if !defined(__linux__) && !defined(__OpenBSD__) && \ + (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && \ + __has_include() +# define MOZ_HAVE_CXX11_ATOMICS +# endif +/* + * Android uses a different C++ standard library that does not provide + * support for . + * + * GCC 4.5.x and 4.6.x's unspecialized std::atomic template doesn't include + * inline definitions for the functions declared therein. This oversight + * leads to linking errors when using atomic enums. We therefore require + * GCC 4.7 or higher. + */ +#elif defined(__GNUC__) && !defined(__ANDROID__) +# include "mozilla/Compiler.h" +# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && \ + MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) +# define MOZ_HAVE_CXX11_ATOMICS +# endif +#elif defined(_MSC_VER) && _MSC_VER >= 1700 +# define MOZ_HAVE_CXX11_ATOMICS +#endif + +namespace mozilla { + +/** + * An enum of memory ordering possibilities for atomics. + * + * Memory ordering is the observable state of distinct values in memory. + * (It's a separate concept from atomicity, which concerns whether an + * operation can ever be observed in an intermediate state. Don't + * conflate the two!) Given a sequence of operations in source code on + * memory, it is *not* always the case that, at all times and on all + * cores, those operations will appear to have occurred in that exact + * sequence. First, the compiler might reorder that sequence, if it + * thinks another ordering will be more efficient. Second, the CPU may + * not expose so consistent a view of memory. CPUs will often perform + * their own instruction reordering, above and beyond that performed by + * the compiler. And each core has its own memory caches, and accesses + * (reads and writes both) to "memory" may only resolve to out-of-date + * cache entries -- not to the "most recently" performed operation in + * some global sense. Any access to a value that may be used by + * multiple threads, potentially across multiple cores, must therefore + * have a memory ordering imposed on it, for all code on all + * threads/cores to have a sufficiently coherent worldview. + * + * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and + * http://en.cppreference.com/w/cpp/atomic/memory_order go into more + * detail on all this, including examples of how each mode works. + * + * Note that for simplicity and practicality, not all of the modes in + * C++11 are supported. The missing C++11 modes are either subsumed by + * the modes we provide below, or not relevant for the CPUs we support + * in Gecko. These three modes are confusing enough as it is! + */ +enum MemoryOrdering { + /* + * Relaxed ordering is the simplest memory ordering: none at all. + * When the result of a write is observed, nothing may be inferred + * about other memory. Writes ostensibly performed "before" on the + * writing thread may not yet be visible. Writes performed "after" on + * the writing thread may already be visible, if the compiler or CPU + * reordered them. (The latter can happen if reads and/or writes get + * held up in per-processor caches.) Relaxed ordering means + * operations can always use cached values (as long as the actual + * updates to atomic values actually occur, correctly, eventually), so + * it's usually the fastest sort of atomic access. For this reason, + * *it's also the most dangerous kind of access*. + * + * Relaxed ordering is good for things like process-wide statistics + * counters that don't need to be consistent with anything else, so + * long as updates themselves are atomic. (And so long as any + * observations of that value can tolerate being out-of-date -- if you + * need some sort of up-to-date value, you need some sort of other + * synchronizing operation.) It's *not* good for locks, mutexes, + * reference counts, etc. that mediate access to other memory, or must + * be observably consistent with other memory. + * + * x86 architectures don't take advantage of the optimization + * opportunities that relaxed ordering permits. Thus it's possible + * that using relaxed ordering will "work" on x86 but fail elsewhere + * (ARM, say, which *does* implement non-sequentially-consistent + * relaxed ordering semantics). Be extra-careful using relaxed + * ordering if you can't easily test non-x86 architectures! + */ + Relaxed, + /* + * When an atomic value is updated with ReleaseAcquire ordering, and + * that new value is observed with ReleaseAcquire ordering, prior + * writes (atomic or not) are also observable. What ReleaseAcquire + * *doesn't* give you is any observable ordering guarantees for + * ReleaseAcquire-ordered operations on different objects. For + * example, if there are two cores that each perform ReleaseAcquire + * operations on separate objects, each core may or may not observe + * the operations made by the other core. The only way the cores can + * be synchronized with ReleaseAcquire is if they both + * ReleaseAcquire-access the same object. This implies that you can't + * necessarily describe some global total ordering of ReleaseAcquire + * operations. + * + * ReleaseAcquire ordering is good for (as the name implies) atomic + * operations on values controlling ownership of things: reference + * counts, mutexes, and the like. However, if you are thinking about + * using these to implement your own locks or mutexes, you should take + * a good, hard look at actual lock or mutex primitives first. + */ + ReleaseAcquire, + /* + * When an atomic value is updated with SequentiallyConsistent + * ordering, all writes observable when the update is observed, just + * as with ReleaseAcquire ordering. But, furthermore, a global total + * ordering of SequentiallyConsistent operations *can* be described. + * For example, if two cores perform SequentiallyConsistent operations + * on separate objects, one core will observably perform its update + * (and all previous operations will have completed), then the other + * core will observably perform its update (and all previous + * operations will have completed). (Although those previous + * operations aren't themselves ordered -- they could be intermixed, + * or ordered if they occur on atomic values with ordering + * requirements.) SequentiallyConsistent is the *simplest and safest* + * ordering of atomic operations -- it's always as if one operation + * happens, then another, then another, in some order -- and every + * core observes updates to happen in that single order. Because it + * has the most synchronization requirements, operations ordered this + * way also tend to be slowest. + * + * SequentiallyConsistent ordering can be desirable when multiple + * threads observe objects, and they all have to agree on the + * observable order of changes to them. People expect + * SequentiallyConsistent ordering, even if they shouldn't, when + * writing code, atomic or otherwise. SequentiallyConsistent is also + * the ordering of choice when designing lockless data structures. If + * you don't know what order to use, use this one. + */ + SequentiallyConsistent, +}; + +} // namespace mozilla + +// Build up the underlying intrinsics. +#ifdef MOZ_HAVE_CXX11_ATOMICS + +# include + +namespace mozilla { +namespace detail { + +/* + * We provide CompareExchangeFailureOrder to work around a bug in some + * versions of GCC's header. See bug 898491. + */ +template struct AtomicOrderConstraints; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; + static const std::memory_order LoadOrder = std::memory_order_relaxed; + static const std::memory_order StoreOrder = std::memory_order_relaxed; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_relaxed; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; + static const std::memory_order LoadOrder = std::memory_order_acquire; + static const std::memory_order StoreOrder = std::memory_order_release; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_acquire; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; + static const std::memory_order LoadOrder = std::memory_order_seq_cst; + static const std::memory_order StoreOrder = std::memory_order_seq_cst; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_seq_cst; +}; + +template +struct IntrinsicBase +{ + typedef std::atomic ValueType; + typedef AtomicOrderConstraints OrderedOp; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T load(const typename Base::ValueType& ptr) { + return ptr.load(Base::OrderedOp::LoadOrder); + } + static void store(typename Base::ValueType& ptr, T val) { + ptr.store(val, Base::OrderedOp::StoreOrder); + } + static T exchange(typename Base::ValueType& ptr, T val) { + return ptr.exchange(val, Base::OrderedOp::AtomicRMWOrder); + } + static bool compareExchange(typename Base::ValueType& ptr, T oldVal, T newVal) { + return ptr.compare_exchange_strong(oldVal, newVal, + Base::OrderedOp::AtomicRMWOrder, + Base::OrderedOp::CompareExchangeFailureOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T add(typename Base::ValueType& ptr, T val) { + return ptr.fetch_add(val, Base::OrderedOp::AtomicRMWOrder); + } + static T sub(typename Base::ValueType& ptr, T val) { + return ptr.fetch_sub(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T* add(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_add(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + static T* sub(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_sub(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + private: + /* + * GCC 4.6's header has a bug where adding X to an + * atomic is not the same as adding X to a T*. Hence the need + * for this function to provide the correct addend. + */ + static ptrdiff_t fixupAddend(ptrdiff_t val) { +#if defined(__clang__) || defined(_MSC_VER) + return val; +#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \ + !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) + return val * sizeof(T); +#else + return val; +#endif + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + typedef IntrinsicBase Base; + static T inc(typename Base::ValueType& ptr) { + return IntrinsicAddSub::add(ptr, 1); + } + static T dec(typename Base::ValueType& ptr) { + return IntrinsicAddSub::sub(ptr, 1); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + typedef IntrinsicBase Base; + static T or_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_or(val, Base::OrderedOp::AtomicRMWOrder); + } + static T xor_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_xor(val, Base::OrderedOp::AtomicRMWOrder); + } + static T and_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_and(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct AtomicIntrinsics + : public IntrinsicMemoryOps, public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(__GNUC__) + +namespace mozilla { +namespace detail { + +/* + * The __sync_* family of intrinsics is documented here: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html + * + * While these intrinsics are deprecated in favor of the newer __atomic_* + * family of intrincs: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html + * + * any GCC version that supports the __atomic_* intrinsics will also support + * the header and so will be handled above. We provide a version of + * atomics using the __sync_* intrinsics to support older versions of GCC. + * + * All __sync_* intrinsics that we use below act as full memory barriers, for + * both compiler and hardware reordering, except for __sync_lock_test_and_set, + * which is a only an acquire barrier. When we call __sync_lock_test_and_set, + * we add a barrier above it as appropriate. + */ + +template struct Barrier; + +/* + * Some processors (in particular, x86) don't require quite so many calls to + * __sync_sychronize as our specializations of Barrier produce. If + * performance turns out to be an issue, defining these specializations + * on a per-processor basis would be a good first tuning step. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() { __sync_synchronize(); } + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() { __sync_synchronize(); } +}; + +template +struct IntrinsicMemoryOps +{ + static T load(const T& ptr) { + Barrier::beforeLoad(); + T val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(T& ptr, T val) { + Barrier::beforeStore(); + ptr = val; + Barrier::afterStore(); + } + static T exchange(T& ptr, T val) { + // __sync_lock_test_and_set is only an acquire barrier; loads and stores + // can't be moved up from after to before it, but they can be moved down + // from before to after it. We may want a stricter ordering, so we need + // an explicit barrier. + + Barrier::beforeStore(); + return __sync_lock_test_and_set(&ptr, val); + } + static bool compareExchange(T& ptr, T oldVal, T newVal) { + return __sync_bool_compare_and_swap(&ptr, oldVal, newVal); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T ValueType; + static T add(T& ptr, T val) { + return __sync_fetch_and_add(&ptr, val); + } + static T sub(T& ptr, T val) { + return __sync_fetch_and_sub(&ptr, val); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T* ValueType; + /* + * The reinterpret_casts are needed so that + * __sync_fetch_and_{add,sub} will properly type-check. + * + * Also, these functions do not provide standard semantics for + * pointer types, so we need to adjust the addend. + */ + static ValueType add(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_add(&ptr, amount); + } + static ValueType sub(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_sub(&ptr, amount); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static T inc(T& ptr) { return IntrinsicAddSub::add(ptr, 1); } + static T dec(T& ptr) { return IntrinsicAddSub::sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static T or_(T& ptr, T val) { + return __sync_fetch_and_or(&ptr, val); + } + static T xor_(T& ptr, T val) { + return __sync_fetch_and_xor(&ptr, val); + } + static T and_(T& ptr, T val) { + return __sync_fetch_and_and(&ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(_MSC_VER) + +/* + * Windows comes with a full complement of atomic operations. + * Unfortunately, most of those aren't available for Windows XP (even if + * the compiler supports intrinsics for them), which is the oldest + * version of Windows we support. Therefore, we only provide operations + * on 32-bit datatypes for 32-bit Windows versions; for 64-bit Windows + * versions, we support 64-bit datatypes as well. + * + * To avoid namespace pollution issues, we declare whatever functions we + * need ourselves. + */ + +extern "C" { +long __cdecl _InterlockedExchangeAdd(long volatile* dst, long value); +long __cdecl _InterlockedOr(long volatile* dst, long value); +long __cdecl _InterlockedXor(long volatile* dst, long value); +long __cdecl _InterlockedAnd(long volatile* dst, long value); +long __cdecl _InterlockedExchange(long volatile *dst, long value); +long __cdecl _InterlockedCompareExchange(long volatile *dst, long newVal, long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd) +# pragma intrinsic(_InterlockedOr) +# pragma intrinsic(_InterlockedXor) +# pragma intrinsic(_InterlockedAnd) +# pragma intrinsic(_InterlockedExchange) +# pragma intrinsic(_InterlockedCompareExchange) + +namespace mozilla { +namespace detail { + +# if !defined(_M_IX86) && !defined(_M_X64) + /* + * The implementations below are optimized for x86ish systems. You + * will have to modify them if you are porting to Windows on a + * different architecture. + */ +# error "Unknown CPU type" +# endif + +/* + * The PrimitiveIntrinsics template should define |Type|, the datatype of size + * DataSize upon which we operate, and the following eight functions. + * + * static Type add(Type* ptr, Type val); + * static Type sub(Type* ptr, Type val); + * static Type or_(Type* ptr, Type val); + * static Type xor_(Type* ptr, Type val); + * static Type and_(Type* ptr, Type val); + * + * These functions perform the obvious operation on the value contained in + * |*ptr| combined with |val| and return the value previously stored in + * |*ptr|. + * + * static void store(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and must provide a full + * memory fence after the store to prevent compiler and hardware instruction + * reordering. It should also act as a compiler barrier to prevent reads and + * writes from moving to after the store. + * + * static Type exchange(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and returns the previous + * contents of *ptr; + * + * static bool compareExchange(Type* ptr, Type oldVal, Type newVal); + * + * This function atomically performs the following operation: + * + * if (*ptr == oldVal) { + * *ptr = newVal; + * return true; + * } else { + * return false; + * } + * + */ +template struct PrimitiveIntrinsics; + +template<> +struct PrimitiveIntrinsics<4> +{ + typedef long Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * _InterlockedExchangeSubtract isn't available before Windows 7, + * and we must support Windows XP. + */ + return _InterlockedExchangeAdd(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange(ptr, newVal, oldVal) == oldVal; + } +}; + +# if defined(_M_X64) + +extern "C" { +long long __cdecl _InterlockedExchangeAdd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedOr64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedXor64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedAnd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedExchange64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedCompareExchange64(long long volatile* dst, + long long newVal, + long long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd64) +# pragma intrinsic(_InterlockedOr64) +# pragma intrinsic(_InterlockedXor64) +# pragma intrinsic(_InterlockedAnd64) +# pragma intrinsic(_InterlockedExchange64) +# pragma intrinsic(_InterlockedCompareExchange64) + +template <> +struct PrimitiveIntrinsics<8> +{ + typedef __int64 Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd64(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * There is no _InterlockedExchangeSubtract64. + */ + return _InterlockedExchangeAdd64(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr64(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor64(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd64(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange64(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange64(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange64(ptr, newVal, oldVal) == oldVal; + } +}; + +# endif + +extern "C" { void _ReadWriteBarrier(); } + +# pragma intrinsic(_ReadWriteBarrier) + +template struct Barrier; + +/* + * We do not provide an afterStore method in Barrier, as Relaxed and + * ReleaseAcquire orderings do not require one, and the required barrier + * for SequentiallyConsistent is handled by PrimitiveIntrinsics. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template<> +struct Barrier +{ + static void beforeLoad() { _ReadWriteBarrier(); } + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T val) { return static_cast(val); } + static T fromPrimType(PrimType val) { return static_cast(val); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T* val) { return reinterpret_cast(val); } + static T* fromPrimType(PrimType val) { return reinterpret_cast(val); } +}; + +template +struct IntrinsicBase +{ + typedef T ValueType; + typedef PrimitiveIntrinsics Primitives; + typedef typename Primitives::Type PrimType; + static_assert(sizeof(PrimType) == sizeof(T), + "Selection of PrimitiveIntrinsics was wrong"); + typedef CastHelper Cast; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + static ValueType load(const ValueType& ptr) { + Barrier::beforeLoad(); + ValueType val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(ValueType& ptr, ValueType val) { + // For SequentiallyConsistent, Primitives::store() will generate the + // proper memory fence. Everything else just needs a barrier before + // the store. + if (Order == SequentiallyConsistent) { + Primitives::store(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + } else { + Barrier::beforeStore(); + ptr = val; + } + } + static ValueType exchange(ValueType& ptr, ValueType val) { + PrimType oldval = + Primitives::exchange(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + return Cast::fromPrimType(oldval); + } + static bool compareExchange(ValueType& ptr, ValueType oldVal, ValueType newVal) { + return Primitives::compareExchange(reinterpret_cast(&ptr), + Cast::toPrimType(oldVal), + Cast::toPrimType(newVal)); + } +}; + +template +struct IntrinsicApplyHelper : public IntrinsicBase +{ + typedef PrimType (*BinaryOp)(PrimType*, PrimType); + typedef PrimType (*UnaryOp)(PrimType*); + + static ValueType applyBinaryFunction(BinaryOp op, ValueType& ptr, + ValueType val) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + PrimType primTypeVal = Cast::toPrimType(val); + return Cast::fromPrimType(op(primTypePtr, primTypeVal)); + } + + static ValueType applyUnaryFunction(UnaryOp op, ValueType& ptr) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + return Cast::fromPrimType(op(primTypePtr)); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::add, ptr, val); + } + static ValueType sub(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::sub, ptr, val); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::add, ptr, + (ValueType)(amount * sizeof(ValueType))); + } + static ValueType sub(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::sub, ptr, + (ValueType)(amount * sizeof(ValueType))); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static ValueType inc(ValueType& ptr) { return add(ptr, 1); } + static ValueType dec(ValueType& ptr) { return sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static ValueType or_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::or_, ptr, val); + } + static ValueType xor_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::xor_, ptr, val); + } + static ValueType and_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::and_, ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#else +# error "Atomic compiler intrinsics are not supported on your platform" +#endif + +namespace mozilla { + +namespace detail { + +template +class AtomicBase +{ + // We only support 32-bit types on 32-bit Windows, which constrains our + // implementation elsewhere. But we support pointer-sized types everywhere. + static_assert(sizeof(T) == 4 || (sizeof(uintptr_t) == 8 && sizeof(T) == 8), + "mozilla/Atomics.h only supports 32-bit and pointer-sized types"); + + protected: + typedef typename detail::AtomicIntrinsics Intrinsics; + typename Intrinsics::ValueType mValue; + + public: + AtomicBase() : mValue() {} + AtomicBase(T aInit) { Intrinsics::store(mValue, aInit); } + + operator T() const { return Intrinsics::load(mValue); } + + T operator=(T aValue) { + Intrinsics::store(mValue, aValue); + return aValue; + } + + /** + * Performs an atomic swap operation. aValue is stored and the previous + * value of this variable is returned. + */ + T exchange(T aValue) { + return Intrinsics::exchange(mValue, aValue); + } + + /** + * Performs an atomic compare-and-swap operation and returns true if it + * succeeded. This is equivalent to atomically doing + * + * if (mValue == aOldValue) { + * mValue = aNewValue; + * return true; + * } else { + * return false; + * } + */ + bool compareExchange(T aOldValue, T aNewValue) { + return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); + } + + private: + template + AtomicBase(const AtomicBase& aCopy) MOZ_DELETE; +}; + +template +class AtomicBaseIncDec : public AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + AtomicBaseIncDec() : Base() {} + AtomicBaseIncDec(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } + T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } + T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } + T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } + + private: + template + AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) MOZ_DELETE; +}; + +} // namespace detail + +/** + * A wrapper for a type that enforces that all memory accesses are atomic. + * + * In general, where a variable |T foo| exists, |Atomic foo| can be used in + * its place. Implementations for integral and pointer types are provided + * below. + * + * Atomic accesses are sequentially consistent by default. You should + * use the default unless you are tall enough to ride the + * memory-ordering roller coaster (if you're not sure, you aren't) and + * you have a compelling reason to do otherwise. + * + * There is one exception to the case of atomic memory accesses: providing an + * initial value of the atomic value is not guaranteed to be atomic. This is a + * deliberate design choice that enables static atomic variables to be declared + * without introducing extra static constructors. + */ +template +class Atomic; + +/** + * Atomic implementation for integral types. + * + * In addition to atomic store and load operations, compound assignment and + * increment/decrement operators are implemented which perform the + * corresponding read-modify-write operation atomically. Finally, an atomic + * swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator+=(T delta) { return Base::Intrinsics::add(Base::mValue, delta) + delta; } + T operator-=(T delta) { return Base::Intrinsics::sub(Base::mValue, delta) - delta; } + T operator|=(T val) { return Base::Intrinsics::or_(Base::mValue, val) | val; } + T operator^=(T val) { return Base::Intrinsics::xor_(Base::mValue, val) ^ val; } + T operator&=(T val) { return Base::Intrinsics::and_(Base::mValue, val) & val; } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for pointer types. + * + * An atomic compare-and-swap primitive for pointer variables is provided, as + * are atomic increment and decement operators. Also provided are the compound + * assignment operators for addition and subtraction. Atomic swap (via + * exchange()) is included as well. + */ +template +class Atomic : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T* aInit) : Base(aInit) {} + + using Base::operator=; + + T* operator+=(ptrdiff_t delta) { + return Base::Intrinsics::add(Base::mValue, delta) + delta; + } + T* operator-=(ptrdiff_t delta) { + return Base::Intrinsics::sub(Base::mValue, delta) - delta; + } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for enum types. + * + * The atomic store and load operations and the atomic swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_Atomics_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Attributes.h b/external/spidermonkey/include/ios/mozilla/Attributes.h index 89f3641fc9..6ea9776fbf 100644 --- a/external/spidermonkey/include/ios/mozilla/Attributes.h +++ b/external/spidermonkey/include/ios/mozilla/Attributes.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of various class and method modifier attributes. */ -#ifndef mozilla_Attributes_h_ -#define mozilla_Attributes_h_ +#ifndef mozilla_Attributes_h +#define mozilla_Attributes_h #include "mozilla/Compiler.h" @@ -117,11 +118,18 @@ * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a * function at compile time. A constexpr function cannot examine any values * except its arguments and can have no side effects except its return value. + * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's + * value may be computed at compile time. It should be prefered to just + * marking variables as MOZ_CONSTEXPR because if the compiler does not support + * constexpr it will fall back to making the variable const, and some compilers + * do not accept variables being marked both const and constexpr. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR # define MOZ_CONSTEXPR constexpr +# define MOZ_CONSTEXPR_VAR constexpr #else # define MOZ_CONSTEXPR /* no support */ +# define MOZ_CONSTEXPR_VAR const #endif /* @@ -382,18 +390,42 @@ * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is * expected to live on the stack, so it is a compile-time error to use it, or * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). It may be a base or - * a member of another class only if both classes are marked with this - * annotation. + * a new expression (unless placement new is being used). If a member of + * another class uses this class, or if another class inherits from this + * class, then it is considered to be a stack class as well, although this + * attribute need not be provided in such cases. + * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is + * expected to live on the stack or in static storage, so it is a compile-time + * error to use it, or an array of such objects, as the type of a new + * expression (unless placement new is being used). If a member of another + * class uses this class, or if another class inherits from this class, then + * it is considered to be a non-heap class as well, although this attribute + * need not be provided in such cases. */ #ifdef MOZ_CLANG_PLUGIN # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) +# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) #else # define MOZ_MUST_OVERRIDE /* nothing */ # define MOZ_STACK_CLASS /* nothing */ +# define MOZ_NONHEAP_CLASS /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ +/* + * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that + * it's safe to use 'this' in an initializer list. + */ +#ifdef _MSC_VER +# define MOZ_THIS_IN_INITIALIZER_LIST() \ + __pragma(warning(push)) \ + __pragma(warning(disable:4355)) \ + this \ + __pragma(warning(pop)) +#else +# define MOZ_THIS_IN_INITIALIZER_LIST() this +#endif + #endif /* __cplusplus */ -#endif /* mozilla_Attributes_h_ */ +#endif /* mozilla_Attributes_h */ diff --git a/external/spidermonkey/include/ios/mozilla/BloomFilter.h b/external/spidermonkey/include/ios/mozilla/BloomFilter.h index 8680ef2907..afe4b72b80 100644 --- a/external/spidermonkey/include/ios/mozilla/BloomFilter.h +++ b/external/spidermonkey/include/ios/mozilla/BloomFilter.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * A counting Bloom filter implementation. This allows consumers to @@ -10,14 +11,14 @@ * incorrectly answer "yes" when the correct answer is "no"). */ -#ifndef mozilla_BloomFilter_h_ -#define mozilla_BloomFilter_h_ +#ifndef mozilla_BloomFilter_h +#define mozilla_BloomFilter_h #include "mozilla/Assertions.h" #include "mozilla/Likely.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Util.h" +#include #include namespace mozilla { @@ -105,7 +106,7 @@ class BloomFilter */ public: BloomFilter() { - MOZ_STATIC_ASSERT(KeySize <= keyShift, "KeySize too big"); + static_assert(KeySize <= keyShift, "KeySize too big"); // Should we have a custom operator new using calloc instead and // require that we're allocated via the operator? @@ -231,4 +232,4 @@ BloomFilter::mightContain(const T* t) const } // namespace mozilla -#endif /* mozilla_BloomFilter_h_ */ +#endif /* mozilla_BloomFilter_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Casting.h b/external/spidermonkey/include/ios/mozilla/Casting.h index b1e81c33fa..76df0ef27e 100644 --- a/external/spidermonkey/include/ios/mozilla/Casting.h +++ b/external/spidermonkey/include/ios/mozilla/Casting.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cast operations to supplement the built-in casting operations. */ -#ifndef mozilla_Casting_h_ -#define mozilla_Casting_h_ +#ifndef mozilla_Casting_h +#define mozilla_Casting_h #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" @@ -15,6 +16,27 @@ namespace mozilla { +/** + * Return a value of type |To|, containing the underlying bit pattern of |from|. + * + * |To| and |From| must be types of the same size; be careful of cross-platform + * size differences, or this might fail to compile on some but not all + * platforms. + */ +template +inline To +BitwiseCast(const From from) +{ + static_assert(sizeof(From) == sizeof(To), + "To and From must have the same size"); + union { + From from; + To to; + } u; + u.from = from; + return u.to; +} + namespace detail { enum ToSignedness { ToIsSigned, ToIsUnsigned }; @@ -43,7 +65,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return from <= From(To(-1)); } }; @@ -52,7 +74,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -61,8 +83,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedUnsignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedUnsignedCheck::checkBounds(from); } }; @@ -72,7 +94,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (from < 0) return false; if (sizeof(To) >= sizeof(From)) @@ -93,7 +115,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -102,7 +124,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); return from <= From(MaxValue); } @@ -112,8 +134,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedSignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedSignedCheck::checkBounds(from); } }; @@ -123,7 +145,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (sizeof(From) <= sizeof(To)) return true; const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); @@ -141,15 +163,15 @@ template class BoundsChecker { public: - static bool check(const From from) { return true; } + static bool checkBounds(const From from) { return true; } }; template class BoundsChecker { public: - static bool check(const From from) { - return BoundsCheckImpl::check(from); + static bool checkBounds(const From from) { + return BoundsCheckImpl::checkBounds(from); } }; @@ -157,7 +179,7 @@ template inline bool IsInBounds(const From from) { - return BoundsChecker::check(from); + return BoundsChecker::checkBounds(from); } } // namespace detail @@ -177,4 +199,4 @@ SafeCast(const From from) } // namespace mozilla -#endif /* mozilla_Casting_h_ */ +#endif /* mozilla_Casting_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Char16.h b/external/spidermonkey/include/ios/mozilla/Char16.h index c6f9f87d44..e4b184f950 100644 --- a/external/spidermonkey/include/ios/mozilla/Char16.h +++ b/external/spidermonkey/include/ios/mozilla/Char16.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implements a UTF-16 character type. */ -#ifndef mozilla_Char16_h_ -#define mozilla_Char16_h_ +#ifndef mozilla_Char16_h +#define mozilla_Char16_h #include "mozilla/Assertions.h" @@ -49,8 +50,8 @@ */ #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s) -MOZ_STATIC_ASSERT(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); +static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); +static_assert(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); +static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); -#endif /* mozilla_Char16_h_ */ +#endif /* mozilla_Char16_h */ diff --git a/external/spidermonkey/include/ios/mozilla/CheckedInt.h b/external/spidermonkey/include/ios/mozilla/CheckedInt.h index 1dc80b032b..050cef8ed8 100644 --- a/external/spidermonkey/include/ios/mozilla/CheckedInt.h +++ b/external/spidermonkey/include/ios/mozilla/CheckedInt.h @@ -1,23 +1,23 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Provides checked integers, detecting integer overflow and divide-by-0. */ -#ifndef mozilla_CheckedInt_h_ -#define mozilla_CheckedInt_h_ +#ifndef mozilla_CheckedInt_h +#define mozilla_CheckedInt_h // Enable relying of Mozilla's MFBT for possibly-available C++11 features #define MOZ_CHECKEDINT_USE_MFBT +#include + #ifdef MOZ_CHECKEDINT_USE_MFBT # include "mozilla/Assertions.h" -# include "mozilla/StandardInteger.h" #else # include -# include -# define MOZ_STATIC_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_DELETE #endif @@ -450,6 +450,44 @@ IsDivValid(T x, T y) !(IsSigned::value && x == MinValue::value && y == T(-1)); } +template::value> +struct IsModValidImpl; + +template +inline bool +IsModValid(T x, T y) +{ + return IsModValidImpl::run(x, y); +} + +/* + * Mod is pretty simple. + * For now, let's just use the ANSI C definition: + * If x or y are negative, the results are implementation defined. + * Consider these invalid. + * Undefined for y=0. + * The result will never exceed either x or y. + * + * Checking that x>=0 is a warning when T is unsigned. + */ + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + return y >= 1; + } +}; + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + if (x < 0) + return false; + + return y >= 1; + } +}; + template::value> struct NegateImpl; @@ -528,7 +566,7 @@ struct NegateImpl CheckedInt x(-1); // 1000 is of type int16_t, is found not to be in range for int8_t, // x is invalid - CheckedInt x(int16_t(1000)); + CheckedInt x(int16_t(1000)); // 3123456789 is of type uint32_t, is found not to be in range for int32_t, // x is invalid CheckedInt x(uint32_t(3123456789)); @@ -561,12 +599,12 @@ class CheckedInt template CheckedInt(U value, bool isValid) : mValue(value), mIsValid(isValid) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); } - friend class detail::NegateImpl; + friend struct detail::NegateImpl; public: /** @@ -585,16 +623,27 @@ class CheckedInt : mValue(T(value)), mIsValid(detail::IsInRange(value)) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } + + template + friend class CheckedInt; + + template + CheckedInt toChecked() const + { + CheckedInt ret(mValue); + ret.mIsValid = ret.mIsValid && mIsValid; + return ret; } /** Constructs a valid checked integer with initial value 0 */ CheckedInt() : mValue(0), mIsValid(true) { - MOZ_STATIC_ASSERT(detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value, + "This type is not supported by CheckedInt"); } /** @returns the actual value */ @@ -619,22 +668,31 @@ class CheckedInt const CheckedInt& rhs); template CheckedInt& operator +=(U rhs); + template friend CheckedInt operator -(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator -=(U rhs); + template friend CheckedInt operator *(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator *=(U rhs); + template friend CheckedInt operator /(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator /=(U rhs); + template + friend CheckedInt operator %(const CheckedInt& lhs, + const CheckedInt& rhs); + template + CheckedInt& operator %=(U rhs); + CheckedInt operator -() const { return detail::NegateImpl::negate(*this); @@ -726,6 +784,7 @@ MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) +MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) #undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR @@ -757,9 +816,9 @@ template inline typename detail::CastToCheckedIntImpl::ReturnType castToCheckedInt(U u) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); return detail::CastToCheckedIntImpl::run(u); } @@ -786,6 +845,7 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) +MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) #undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS @@ -815,4 +875,4 @@ typedef CheckedInt CheckedUint64; } // namespace mozilla -#endif /* mozilla_CheckedInt_h_ */ +#endif /* mozilla_CheckedInt_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Compiler.h b/external/spidermonkey/include/ios/mozilla/Compiler.h index 58239b0e30..d1ef1e79aa 100644 --- a/external/spidermonkey/include/ios/mozilla/Compiler.h +++ b/external/spidermonkey/include/ios/mozilla/Compiler.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various compiler checks. */ -#ifndef mozilla_Compiler_h_ -#define mozilla_Compiler_h_ +#ifndef mozilla_Compiler_h +#define mozilla_Compiler_h #if !defined(__clang__) && defined(__GNUC__) @@ -28,4 +29,4 @@ #endif -#endif /* mozilla_Compiler_h_ */ +#endif /* mozilla_Compiler_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Constants.h b/external/spidermonkey/include/ios/mozilla/Constants.h index 904b30145a..86bbb6b354 100644 --- a/external/spidermonkey/include/ios/mozilla/Constants.h +++ b/external/spidermonkey/include/ios/mozilla/Constants.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt math constants. */ -#ifndef mozilla_Constants_h_ -#define mozilla_Constants_h_ +#ifndef mozilla_Constants_h +#define mozilla_Constants_h #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -#endif /* mozilla_Constants_h_ */ +#endif /* mozilla_Constants_h */ diff --git a/external/spidermonkey/include/ios/mozilla/DebugOnly.h b/external/spidermonkey/include/ios/mozilla/DebugOnly.h index 1f78ed7989..e5f0d729b5 100644 --- a/external/spidermonkey/include/ios/mozilla/DebugOnly.h +++ b/external/spidermonkey/include/ios/mozilla/DebugOnly.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * assertions). */ -#ifndef mozilla_DebugOnly_h_ -#define mozilla_DebugOnly_h_ +#ifndef mozilla_DebugOnly_h +#define mozilla_DebugOnly_h namespace mozilla { @@ -74,4 +75,4 @@ class DebugOnly } -#endif /* mozilla_DebugOnly_h_ */ +#endif /* mozilla_DebugOnly_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Decimal.h b/external/spidermonkey/include/ios/mozilla/Decimal.h index 8032fd6e23..3c67d784c9 100644 --- a/external/spidermonkey/include/ios/mozilla/Decimal.h +++ b/external/spidermonkey/include/ios/mozilla/Decimal.h @@ -38,7 +38,7 @@ #define Decimal_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" +#include #include "mozilla/Types.h" #include diff --git a/external/spidermonkey/include/ios/mozilla/Endian.h b/external/spidermonkey/include/ios/mozilla/Endian.h index 5d2f905b41..dc6d11d3ba 100644 --- a/external/spidermonkey/include/ios/mozilla/Endian.h +++ b/external/spidermonkey/include/ios/mozilla/Endian.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -59,16 +60,16 @@ * }; */ -#ifndef mozilla_Endian_h_ -#define mozilla_Endian_h_ +#ifndef mozilla_Endian_h +#define mozilla_Endian_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/DebugOnly.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" +#include #include #if defined(_MSC_VER) && _MSC_VER >= 1300 @@ -636,4 +637,4 @@ class NativeEndian MOZ_FINAL : public detail::Endian } /* namespace mozilla */ -#endif /* mozilla_Endian_h_ */ +#endif /* mozilla_Endian_h */ diff --git a/external/spidermonkey/include/ios/mozilla/EnumSet.h b/external/spidermonkey/include/ios/mozilla/EnumSet.h index b18b005669..95c5608cf4 100644 --- a/external/spidermonkey/include/ios/mozilla/EnumSet.h +++ b/external/spidermonkey/include/ios/mozilla/EnumSet.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,7 +10,8 @@ #define mozilla_EnumSet_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" + +#include namespace mozilla { @@ -172,4 +174,4 @@ class EnumSet } // namespace mozilla -#endif // mozilla_EnumSet_h_ +#endif /* mozilla_EnumSet_h_*/ diff --git a/external/spidermonkey/include/ios/mozilla/FloatingPoint.h b/external/spidermonkey/include/ios/mozilla/FloatingPoint.h index 30af2217b1..d80f6a7234 100644 --- a/external/spidermonkey/include/ios/mozilla/FloatingPoint.h +++ b/external/spidermonkey/include/ios/mozilla/FloatingPoint.h @@ -1,16 +1,19 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various predicates and operations on IEEE-754 floating point types. */ -#ifndef mozilla_FloatingPoint_h_ -#define mozilla_FloatingPoint_h_ +#ifndef mozilla_FloatingPoint_h +#define mozilla_FloatingPoint_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" +#include "mozilla/Casting.h" + +#include namespace mozilla { @@ -35,80 +38,58 @@ namespace mozilla { * the case. But we required this in implementations of these algorithms that * preceded this header, so we shouldn't break anything if we continue doing so. */ -MOZ_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); +static_assert(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); const unsigned DoubleExponentBias = 1023; const unsigned DoubleExponentShift = 52; -namespace detail { - const uint64_t DoubleSignBit = 0x8000000000000000ULL; const uint64_t DoubleExponentBits = 0x7ff0000000000000ULL; const uint64_t DoubleSignificandBits = 0x000fffffffffffffULL; -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleExponentBits) == 0, - "sign bit doesn't overlap exponent bits"); -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleSignificandBits) == 0, - "sign bit doesn't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleExponentBits & DoubleSignificandBits) == 0, - "exponent bits don't overlap significand bits"); +static_assert((DoubleSignBit & DoubleExponentBits) == 0, + "sign bit doesn't overlap exponent bits"); +static_assert((DoubleSignBit & DoubleSignificandBits) == 0, + "sign bit doesn't overlap significand bits"); +static_assert((DoubleExponentBits & DoubleSignificandBits) == 0, + "exponent bits don't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == - ~uint64_t(0), - "all bits accounted for"); - -union DoublePun -{ - /* - * Every way to pun the bits of a double introduces an additional layer of - * complexity, across a multitude of platforms, architectures, and ABIs. - * Use *only* uint64_t to reduce complexity. Don't add new punning here - * without discussion! - */ - uint64_t u; - double d; -}; - -} /* namespace detail */ +static_assert((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == + ~uint64_t(0), + "all bits accounted for"); /** Determines whether a double is NaN. */ static MOZ_ALWAYS_INLINE bool IsNaN(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * A double is NaN if all exponent bits are 1 and the significand contains at * least one non-zero bit. */ - return (pun.u & detail::DoubleExponentBits) == detail::DoubleExponentBits && - (pun.u & detail::DoubleSignificandBits) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) == DoubleExponentBits && + (bits & DoubleSignificandBits) != 0; } /** Determines whether a double is +Infinity or -Infinity. */ static MOZ_ALWAYS_INLINE bool IsInfinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - return (pun.u & ~detail::DoubleSignBit) == detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & ~DoubleSignBit) == DoubleExponentBits; } /** Determines whether a double is not NaN or infinite. */ static MOZ_ALWAYS_INLINE bool IsFinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * NaN and Infinities are the only non-finite doubles, and both have all * exponent bits set to 1. */ - return (pun.u & detail::DoubleExponentBits) != detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) != DoubleExponentBits; } /** @@ -120,36 +101,30 @@ IsNegative(double d) { MOZ_ASSERT(!IsNaN(d), "NaN does not have a sign"); - union detail::DoublePun pun; - pun.d = d; - /* The sign bit is set if the double is negative. */ - return (pun.u & detail::DoubleSignBit) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleSignBit) != 0; } /** Determines whether a double represents -0. */ static MOZ_ALWAYS_INLINE bool IsNegativeZero(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Only the sign bit is set if the double is -0. */ - return pun.u == detail::DoubleSignBit; + uint64_t bits = BitwiseCast(d); + return bits == DoubleSignBit; } /** Returns the exponent portion of the double. */ static MOZ_ALWAYS_INLINE int_fast16_t ExponentComponent(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * The exponent component of a double is an unsigned number, biased from its * actual value. Subtract the bias to retrieve the actual exponent. */ - return int_fast16_t((pun.u & detail::DoubleExponentBits) >> DoubleExponentShift) - + uint64_t bits = BitwiseCast(d); + return int_fast16_t((bits & DoubleExponentBits) >> DoubleExponentShift) - int_fast16_t(DoubleExponentBias); } @@ -157,28 +132,22 @@ ExponentComponent(double d) static MOZ_ALWAYS_INLINE double PositiveInfinity() { - union detail::DoublePun pun; - /* * Positive infinity has all exponent bits set, sign bit set to 0, and no * significand. */ - pun.u = detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleExponentBits); } /** Returns -Infinity. */ static MOZ_ALWAYS_INLINE double NegativeInfinity() { - union detail::DoublePun pun; - /* * Negative infinity has all exponent bits set, sign bit set to 1, and no * significand. */ - pun.u = detail::DoubleSignBit | detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleSignBit | DoubleExponentBits); } /** Constructs a NaN value with the specified sign bit and significand bits. */ @@ -186,24 +155,21 @@ static MOZ_ALWAYS_INLINE double SpecificNaN(int signbit, uint64_t significand) { MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~detail::DoubleSignificandBits) == 0); - MOZ_ASSERT(significand & detail::DoubleSignificandBits); + MOZ_ASSERT((significand & ~DoubleSignificandBits) == 0); + MOZ_ASSERT(significand & DoubleSignificandBits); - union detail::DoublePun pun; - pun.u = (signbit ? detail::DoubleSignBit : 0) | - detail::DoubleExponentBits | - significand; - MOZ_ASSERT(IsNaN(pun.d)); - return pun.d; + double d = BitwiseCast((signbit ? DoubleSignBit : 0) | + DoubleExponentBits | + significand); + MOZ_ASSERT(IsNaN(d)); + return d; } /** Computes the smallest non-zero positive double value. */ static MOZ_ALWAYS_INLINE double MinDoubleValue() { - union detail::DoublePun pun; - pun.u = 1; - return pun.d; + return BitwiseCast(uint64_t(1)); } static MOZ_ALWAYS_INLINE bool @@ -224,9 +190,22 @@ DoubleIsInt32(double d, int32_t* i) static MOZ_ALWAYS_INLINE double UnspecifiedNaN() { - return mozilla::SpecificNaN(0, 0xfffffffffffffULL); + return SpecificNaN(0, 0xfffffffffffffULL); +} + +/** + * Compare two doubles for equality, *without* equating -0 to +0, and equating + * any NaN value to any other NaN value. (The normal equality operators equate + * -0 with +0, and they equate NaN to no other value.) + */ +static inline bool +DoublesAreIdentical(double d1, double d2) +{ + if (IsNaN(d1)) + return IsNaN(d2); + return BitwiseCast(d1) == BitwiseCast(d2); } } /* namespace mozilla */ -#endif /* mozilla_FloatingPoint_h_ */ +#endif /* mozilla_FloatingPoint_h */ diff --git a/external/spidermonkey/include/ios/mozilla/GuardObjects.h b/external/spidermonkey/include/ios/mozilla/GuardObjects.h index 6c2058938c..aeae7dcbc0 100644 --- a/external/spidermonkey/include/ios/mozilla/GuardObjects.h +++ b/external/spidermonkey/include/ios/mozilla/GuardObjects.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,6 +10,7 @@ #define mozilla_GuardObjects_h #include "mozilla/Assertions.h" +#include "mozilla/NullPtr.h" #include "mozilla/Types.h" #ifdef __cplusplus @@ -72,7 +74,7 @@ class MOZ_EXPORT GuardObjectNotifier bool* statementDone; public: - GuardObjectNotifier() : statementDone(NULL) { } + GuardObjectNotifier() : statementDone(nullptr) { } ~GuardObjectNotifier() { *statementDone = true; diff --git a/external/spidermonkey/include/ios/mozilla/HashFunctions.h b/external/spidermonkey/include/ios/mozilla/HashFunctions.h index 96242b629a..6d0d24e7b1 100644 --- a/external/spidermonkey/include/ios/mozilla/HashFunctions.h +++ b/external/spidermonkey/include/ios/mozilla/HashFunctions.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Utilities for hashing. */ @@ -39,17 +40,18 @@ * }; * * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKey.h. + * in nsHashKeys.h. */ -#ifndef mozilla_HashFunctions_h_ -#define mozilla_HashFunctions_h_ +#ifndef mozilla_HashFunctions_h +#define mozilla_HashFunctions_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + #ifdef __cplusplus namespace mozilla { @@ -173,8 +175,8 @@ AddToHash(uint32_t hash, A* a) * catch data pointers and couldn't handle function pointers. */ - MOZ_STATIC_ASSERT(sizeof(a) == sizeof(uintptr_t), - "Strange pointer!"); + static_assert(sizeof(a) == sizeof(uintptr_t), + "Strange pointer!"); return detail::AddUintptrToHash(hash, uintptr_t(a)); } @@ -356,4 +358,5 @@ HashBytes(const void* bytes, size_t length); } /* namespace mozilla */ #endif /* __cplusplus */ -#endif /* mozilla_HashFunctions_h_ */ + +#endif /* mozilla_HashFunctions_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Likely.h b/external/spidermonkey/include/ios/mozilla/Likely.h index 6412b4943b..4f21609295 100644 --- a/external/spidermonkey/include/ios/mozilla/Likely.h +++ b/external/spidermonkey/include/ios/mozilla/Likely.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a * boolean predicate should be branch-predicted. */ -#ifndef mozilla_Likely_h_ -#define mozilla_Likely_h_ +#ifndef mozilla_Likely_h +#define mozilla_Likely_h #if defined(__clang__) || defined(__GNUC__) # define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) @@ -19,4 +20,4 @@ # define MOZ_UNLIKELY(x) (!!(x)) #endif -#endif /* mozilla_Likely_h_ */ +#endif /* mozilla_Likely_h */ diff --git a/external/spidermonkey/include/ios/mozilla/LinkedList.h b/external/spidermonkey/include/ios/mozilla/LinkedList.h index 5cfd60e4ac..c29760b3e7 100644 --- a/external/spidermonkey/include/ios/mozilla/LinkedList.h +++ b/external/spidermonkey/include/ios/mozilla/LinkedList.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -45,18 +46,19 @@ * } * * void notifyObservers(char* topic) { - * for (Observer* o = list.getFirst(); o != NULL; o = o->getNext()) - * o->Observe(topic); + * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) + * o->observe(topic); * } * }; * */ -#ifndef mozilla_LinkedList_h_ -#define mozilla_LinkedList_h_ +#ifndef mozilla_LinkedList_h +#define mozilla_LinkedList_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #ifdef __cplusplus @@ -69,10 +71,10 @@ template class LinkedListElement { /* - * It's convenient that we return NULL when getNext() or getPrevious() hits - * the end of the list, but doing so costs an extra word of storage in each - * linked list node (to keep track of whether |this| is the sentinel node) - * and a branch on this value in getNext/getPrevious. + * It's convenient that we return nullptr when getNext() or getPrevious() + * hits the end of the list, but doing so costs an extra word of storage in + * each linked list node (to keep track of whether |this| is the sentinel + * node) and a branch on this value in getNext/getPrevious. * * We could get rid of the extra word of storage by shoving the "is * sentinel" bit into one of the pointers, although this would, of course, @@ -107,12 +109,10 @@ class LinkedListElement LinkedListElement* prev; const bool isSentinel; - LinkedListElement* thisDuringConstruction() { return this; } - public: LinkedListElement() - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(false) { } @@ -122,8 +122,8 @@ class LinkedListElement } /* - * Get the next element in the list, or NULL if this is the last element in - * the list. + * Get the next element in the list, or nullptr if this is the last element + * in the list. */ T* getNext() { return next->asT(); @@ -133,8 +133,8 @@ class LinkedListElement } /* - * Get the previous element in the list, or NULL if this is the first element - * in the list. + * Get the previous element in the list, or nullptr if this is the first + * element in the list. */ T* getPrevious() { return prev->asT(); @@ -201,24 +201,24 @@ class LinkedListElement }; LinkedListElement(NodeKind nodeKind) - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(nodeKind == NODE_KIND_SENTINEL) { } /* - * Return |this| cast to T* if we're a normal node, or return NULL if we're - * a sentinel node. + * Return |this| cast to T* if we're a normal node, or return nullptr if + * we're a sentinel node. */ T* asT() { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } const T* asT() const { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } @@ -285,7 +285,7 @@ class LinkedList } /* - * Get the first element of the list, or NULL if the list is empty. + * Get the first element of the list, or nullptr if the list is empty. */ T* getFirst() { return sentinel.getNext(); @@ -295,7 +295,7 @@ class LinkedList } /* - * Get the last element of the list, or NULL if the list is empty. + * Get the last element of the list, or nullptr if the list is empty. */ T* getLast() { return sentinel.getPrevious(); @@ -306,7 +306,7 @@ class LinkedList /* * Get and remove the first element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popFirst() { T* ret = sentinel.getNext(); @@ -317,7 +317,7 @@ class LinkedList /* * Get and remove the last element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popLast() { T* ret = sentinel.getPrevious(); @@ -415,7 +415,7 @@ class LinkedList if (elem == t) return; } - MOZ_NOT_REACHED("element wasn't found in this list!"); + MOZ_CRASH("element wasn't found in this list!"); #endif } @@ -425,5 +425,6 @@ class LinkedList } /* namespace mozilla */ -#endif /* ifdef __cplusplus */ -#endif /* ifdef mozilla_LinkedList_h_ */ +#endif /* __cplusplus */ + +#endif /* mozilla_LinkedList_h */ diff --git a/external/spidermonkey/include/ios/mozilla/MSStdInt.h b/external/spidermonkey/include/ios/mozilla/MSStdInt.h deleted file mode 100644 index 0447f2f11b..0000000000 --- a/external/spidermonkey/include/ios/mozilla/MSStdInt.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// 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. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/external/spidermonkey/include/ios/mozilla/MathAlgorithms.h b/external/spidermonkey/include/ios/mozilla/MathAlgorithms.h index 0a47810553..6d58691e06 100644 --- a/external/spidermonkey/include/ios/mozilla/MathAlgorithms.h +++ b/external/spidermonkey/include/ios/mozilla/MathAlgorithms.h @@ -1,19 +1,20 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt maths algorithms. */ -#ifndef mozilla_MathAlgorithms_h_ -#define mozilla_MathAlgorithms_h_ +#ifndef mozilla_MathAlgorithms_h +#define mozilla_MathAlgorithms_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" #include #include +#include namespace mozilla { @@ -142,6 +143,288 @@ Abs(const long double d) return std::fabs(d); } +} // namespace mozilla + +#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define MOZ_BITSCAN_WINDOWS + + extern "C" { + unsigned char _BitScanForward(unsigned long* Index, unsigned long mask); + unsigned char _BitScanReverse(unsigned long* Index, unsigned long mask); +# pragma intrinsic(_BitScanForward, _BitScanReverse) + +# if defined(_M_AMD64) || defined(_M_X64) +# define MOZ_BITSCAN_WINDOWS64 + unsigned char _BitScanForward64(unsigned long* index, unsigned __int64 mask); + unsigned char _BitScanReverse64(unsigned long* index, unsigned __int64 mask); +# pragma intrinsic(_BitScanForward64, _BitScanReverse64) +# endif + } // extern "C" + +#endif + +namespace mozilla { + +namespace detail { + +#if defined(MOZ_BITSCAN_WINDOWS) + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanReverse(&index, static_cast(u)); + return uint_fast8_t(31 - index); + } + + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanForward(&index, static_cast(u)); + return uint_fast8_t(index); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanReverse64(&index, static_cast(u)); + return uint_fast8_t(63 - index); +# else + uint32_t hi = uint32_t(u >> 32); + if (hi != 0) + return CountLeadingZeroes32(hi); + return 32 + CountLeadingZeroes32(uint32_t(u)); +# endif + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanForward64(&index, static_cast(u)); + return uint_fast8_t(index); +# else + uint32_t lo = uint32_t(u); + if (lo != 0) + return CountTrailingZeroes32(lo); + return 32 + CountTrailingZeroes32(uint32_t(u >> 32)); +# endif + } + +# ifdef MOZ_HAVE_BITSCAN64 +# undef MOZ_HAVE_BITSCAN64 +# endif + +#elif defined(__clang__) || defined(__GNUC__) + +# if defined(__clang__) +# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) +# error "A clang providing __builtin_c[lt]z is required to build" +# endif +# else + // gcc has had __builtin_clz and friends since 3.4: no need to check. +# endif + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + return __builtin_clz(u); + } + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + return __builtin_ctz(u); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { + return __builtin_clzll(u); + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { + return __builtin_ctzll(u); + } + +#else +# error "Implement these!" + inline uint_fast8_t CountLeadingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountLeadingZeroes64(uint64_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes64(uint64_t u) MOZ_DELETE; +#endif + +} // namespace detail + +/** + * Compute the number of high-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the highest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountLeadingZeroes32(0xF0FF1000) is 0; + * CountLeadingZeroes32(0x7F8F0001) is 1; + * CountLeadingZeroes32(0x3FFF0100) is 2; + * CountLeadingZeroes32(0x1FF50010) is 3; and so on. + */ +inline uint_fast8_t +CountLeadingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes32(u); +} + +/** + * Compute the number of low-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the lowest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountTrailingZeroes32(0x0100FFFF) is 0; + * CountTrailingZeroes32(0x7000FFFE) is 1; + * CountTrailingZeroes32(0x0080FFFC) is 2; + * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. + */ +inline uint_fast8_t +CountTrailingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes32(u); +} + +/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountLeadingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes64(u); +} + +/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountTrailingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes64(u); +} + +namespace detail { + +template +class CeilingLog2; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 32 - CountLeadingZeroes32(t - 1); + } +}; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 64 - CountLeadingZeroes64(t - 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the least power of 2 greater than or equal to |t|. + * + * CeilingLog2(0..1) is 0; + * CeilingLog2(2) is 1; + * CeilingLog2(3..4) is 2; + * CeilingLog2(5..8) is 3; + * CeilingLog2(9..16) is 4; and so on. + */ +template +inline uint_fast8_t +CeilingLog2(const T t) +{ + return detail::CeilingLog2::compute(t); +} + +/** A CeilingLog2 variant that accepts only size_t. */ +inline uint_fast8_t +CeilingLog2Size(size_t n) +{ + return CeilingLog2(n); +} + +namespace detail { + +template +class FloorLog2; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 31 - CountLeadingZeroes32(t | 1); + } +}; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 63 - CountLeadingZeroes64(t | 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the greatest power of 2 less than or equal to |t|. + * + * FloorLog2(0..1) is 0; + * FloorLog2(2..3) is 1; + * FloorLog2(4..7) is 2; + * FloorLog2(8..15) is 3; and so on. + */ +template +inline uint_fast8_t +FloorLog2(const T t) +{ + return detail::FloorLog2::compute(t); +} + +/** A FloorLog2 variant that accepts only size_t. */ +inline uint_fast8_t +FloorLog2Size(size_t n) +{ + return FloorLog2(n); +} + +/* + * Compute the smallest power of 2 greater than or equal to |x|. |x| must not + * be so great that the computed value would overflow |size_t|. + */ +inline size_t +RoundUpPow2(size_t x) +{ + MOZ_ASSERT(x <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), + "can't round up -- will overflow!"); + return size_t(1) << CeilingLog2(x); +} + } /* namespace mozilla */ -#endif /* mozilla_MathAlgorithms_h_ */ +#endif /* mozilla_MathAlgorithms_h */ diff --git a/external/spidermonkey/include/ios/mozilla/MemoryChecking.h b/external/spidermonkey/include/ios/mozilla/MemoryChecking.h index 3287e57ba1..2130990c6b 100644 --- a/external/spidermonkey/include/ios/mozilla/MemoryChecking.h +++ b/external/spidermonkey/include/ios/mozilla/MemoryChecking.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -19,8 +20,8 @@ * With no memory checker available, all macros expand to the empty statement. */ -#ifndef mozilla_MemoryChecking_h_ -#define mozilla_MemoryChecking_h_ +#ifndef mozilla_MemoryChecking_h +#define mozilla_MemoryChecking_h #if defined(MOZ_VALGRIND) #include "valgrind/memcheck.h" @@ -68,4 +69,4 @@ extern "C" { #endif -#endif /* mozilla_MemoryChecking_h_ */ +#endif /* mozilla_MemoryChecking_h */ diff --git a/external/spidermonkey/include/ios/mozilla/MemoryReporting.h b/external/spidermonkey/include/ios/mozilla/MemoryReporting.h new file mode 100644 index 0000000000..d2340ecf09 --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/MemoryReporting.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Memory reporting infrastructure. */ + +#ifndef mozilla_MemoryReporting_h +#define mozilla_MemoryReporting_h + +#include + +#ifdef __cplusplus + +namespace mozilla { + +/* + * This is for functions that are like malloc_usable_size. Such functions are + * used for measuring the size of data structures. + */ +typedef size_t (*MallocSizeOf)(const void* p); + +} /* namespace mozilla */ + +#endif /* __cplusplus */ + +typedef size_t (*MozMallocSizeOf)(const void* p); + +#endif /* mozilla_MemoryReporting_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Move.h b/external/spidermonkey/include/ios/mozilla/Move.h new file mode 100644 index 0000000000..97178daaa6 --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/Move.h @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* C++11-style, but C++98-usable, "move references" implementation. */ + +#ifndef mozilla_Move_h +#define mozilla_Move_h + +namespace mozilla { + +/* + * "Move" References + * + * Some types can be copied much more efficiently if we know the original's + * value need not be preserved --- that is, if we are doing a "move", not a + * "copy". For example, if we have: + * + * Vector u; + * Vector v(u); + * + * the constructor for v must apply a copy constructor to each element of u --- + * taking time linear in the length of u. However, if we know we will not need u + * any more once v has been initialized, then we could initialize v very + * efficiently simply by stealing u's dynamically allocated buffer and giving it + * to v --- a constant-time operation, regardless of the size of u. + * + * Moves often appear in container implementations. For example, when we append + * to a vector, we may need to resize its buffer. This entails moving each of + * its extant elements from the old, smaller buffer to the new, larger buffer. + * But once the elements have been migrated, we're just going to throw away the + * old buffer; we don't care if they still have their values. So if the vector's + * element type can implement "move" more efficiently than "copy", the vector + * resizing should by all means use a "move" operation. Hash tables also need to + * be resized. + * + * The details of the optimization, and whether it's worth applying, vary from + * one type to the next. And while some constructor calls are moves, many really + * are copies, and can't be optimized this way. So we need: + * + * 1) a way for a particular invocation of a copy constructor to say that it's + * really a move, and that the value of the original isn't important + * afterwards (although it must still be safe to destroy); and + * + * 2) a way for a type (like Vector) to announce that it can be moved more + * efficiently than it can be copied, and provide an implementation of that + * move operation. + * + * The Move(T&) function takes a reference to a T, and returns a MoveRef + * referring to the same value; that's 1). A MoveRef is simply a reference + * to a T, annotated to say that a copy constructor applied to it may move that + * T, instead of copying it. Finally, a constructor that accepts an MoveRef + * should perform a more efficient move, instead of a copy, providing 2). + * + * So, where we might define a copy constructor for a class C like this: + * + * C(const C& rhs) { ... copy rhs to this ... } + * + * we would declare a move constructor like this: + * + * C(MoveRef rhs) { ... move rhs to this ... } + * + * And where we might perform a copy like this: + * + * C c2(c1); + * + * we would perform a move like this: + * + * C c2(Move(c1)) + * + * Note that MoveRef implicitly converts to T&, so you can pass a MoveRef + * to an ordinary copy constructor for a type that doesn't support a special + * move constructor, and you'll just get a copy. This means that templates can + * use Move whenever they know they won't use the original value any more, even + * if they're not sure whether the type at hand has a specialized move + * constructor. If it doesn't, the MoveRef will just convert to a T&, and + * the ordinary copy constructor will apply. + * + * A class with a move constructor can also provide a move assignment operator, + * which runs this's destructor, and then applies the move constructor to + * *this's memory. A typical definition: + * + * C& operator=(MoveRef rhs) { + * this->~C(); + * new(this) C(rhs); + * return *this; + * } + * + * With that in place, one can write move assignments like this: + * + * c2 = Move(c1); + * + * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but + * destructible state. + * + * This header file defines MoveRef and Move in the mozilla namespace. It's up + * to individual containers to annotate moves as such, by calling Move; and it's + * up to individual types to define move constructors. + * + * One hint: if you're writing a move constructor where the type has members + * that should be moved themselves, it's much nicer to write this: + * + * C(MoveRef c) : x(Move(c->x)), y(Move(c->y)) { } + * + * than the equivalent: + * + * C(MoveRef c) { new(&x) X(Move(c->x)); new(&y) Y(Move(c->y)); } + * + * especially since GNU C++ fails to notice that this does indeed initialize x + * and y, which may matter if they're const. + */ +template +class MoveRef +{ + T* pointer; + + public: + explicit MoveRef(T& t) : pointer(&t) { } + T& operator*() const { return *pointer; } + T* operator->() const { return pointer; } + operator T& () const { return *pointer; } +}; + +template +inline MoveRef +Move(T& t) +{ + return MoveRef(t); +} + +template +inline MoveRef +Move(const T& t) +{ + // With some versions of gcc, for a class C, there's an (incorrect) ambiguity + // between the C(const C&) constructor and the default C(C&&) C++11 move + // constructor, when the constructor is called with a const C& argument. + // + // This ambiguity manifests with the Move implementation above when Move is + // passed const U& for some class U. Calling Move(const U&) returns a + // MoveRef, which is then commonly passed to the U constructor, + // triggering an implicit conversion to const U&. gcc doesn't know whether to + // call U(const U&) or U(U&&), so it wrongly reports a compile error. + // + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50442 has since been fixed, so + // this is no longer an issue for up-to-date compilers. But there's no harm + // in keeping it around for older compilers, so we might as well. See also + // bug 686280. + return MoveRef(const_cast(t)); +} + +/** Swap |t| and |u| using move-construction if possible. */ +template +inline void +Swap(T& t, T& u) +{ + T tmp(Move(t)); + t = Move(u); + u = Move(tmp); +} + +} // namespace mozilla + +#endif /* mozilla_Move_h */ diff --git a/external/spidermonkey/include/ios/mozilla/NullPtr.h b/external/spidermonkey/include/ios/mozilla/NullPtr.h index 7dcb03d734..14c0f07df2 100644 --- a/external/spidermonkey/include/ios/mozilla/NullPtr.h +++ b/external/spidermonkey/include/ios/mozilla/NullPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * constant. */ -#ifndef mozilla_NullPtr_h_ -#define mozilla_NullPtr_h_ +#ifndef mozilla_NullPtr_h +#define mozilla_NullPtr_h #include "mozilla/Compiler.h" @@ -45,4 +46,4 @@ # endif #endif -#endif /* mozilla_NullPtr_h_ */ +#endif /* mozilla_NullPtr_h */ diff --git a/external/spidermonkey/include/ios/mozilla/PodOperations.h b/external/spidermonkey/include/ios/mozilla/PodOperations.h index 6c6af27fc9..bec89fa928 100644 --- a/external/spidermonkey/include/ios/mozilla/PodOperations.h +++ b/external/spidermonkey/include/ios/mozilla/PodOperations.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -156,4 +157,4 @@ PodEqual(const T* one, const T* two, size_t len) } // namespace mozilla -#endif // mozilla_PodOperations_h_ +#endif /* mozilla_PodOperations_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Poison.h b/external/spidermonkey/include/ios/mozilla/Poison.h index c4adc23e71..75e0f081cd 100644 --- a/external/spidermonkey/include/ios/mozilla/Poison.h +++ b/external/spidermonkey/include/ios/mozilla/Poison.h @@ -9,13 +9,14 @@ * an address that leads to a safe crash when dereferenced. */ -#ifndef mozilla_Poison_h_ -#define mozilla_Poison_h_ +#ifndef mozilla_Poison_h +#define mozilla_Poison_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + MOZ_BEGIN_EXTERN_C extern MFBT_DATA uintptr_t gMozillaPoisonValue; @@ -36,11 +37,11 @@ inline uintptr_t mozPoisonValue() */ inline void mozWritePoison(void* aPtr, size_t aSize) { - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); const uintptr_t POISON = mozPoisonValue(); char* p = (char*)aPtr; char* limit = p + aSize; + MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); + MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); for (; p < limit; p += sizeof(uintptr_t)) { *((uintptr_t*)p) = POISON; } @@ -58,4 +59,4 @@ extern MFBT_DATA uintptr_t gMozillaPoisonSize; MOZ_END_EXTERN_C -#endif /* mozilla_Poison_h_ */ +#endif /* mozilla_Poison_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Range.h b/external/spidermonkey/include/ios/mozilla/Range.h index e14594d09d..4e02d962b5 100644 --- a/external/spidermonkey/include/ios/mozilla/Range.h +++ b/external/spidermonkey/include/ios/mozilla/Range.h @@ -1,12 +1,11 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef mozilla_Range_h_ -#define mozilla_Range_h_ +#ifndef mozilla_Range_h +#define mozilla_Range_h #include "mozilla/NullPtr.h" #include "mozilla/RangedPtr.h" @@ -40,10 +39,13 @@ class Range return mStart[offset]; } + const T& operator[](size_t offset) const { + return mStart[offset]; + } + operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; } }; } // namespace mozilla -#endif // mozilla_Range_h_ - +#endif /* mozilla_Range_h */ diff --git a/external/spidermonkey/include/ios/mozilla/RangedPtr.h b/external/spidermonkey/include/ios/mozilla/RangedPtr.h index 7ce19d071f..493fcdbaee 100644 --- a/external/spidermonkey/include/ios/mozilla/RangedPtr.h +++ b/external/spidermonkey/include/ios/mozilla/RangedPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,11 +9,12 @@ * construction. */ -#ifndef mozilla_RangedPtr_h_ -#define mozilla_RangedPtr_h_ +#ifndef mozilla_RangedPtr_h +#define mozilla_RangedPtr_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #include "mozilla/Util.h" namespace mozilla { @@ -59,7 +61,7 @@ class RangedPtr #ifdef DEBUG return RangedPtr(p, rangeStart, rangeEnd); #else - return RangedPtr(p, NULL, size_t(0)); + return RangedPtr(p, nullptr, size_t(0)); #endif } @@ -251,4 +253,4 @@ class RangedPtr } /* namespace mozilla */ -#endif /* mozilla_RangedPtr_h_ */ +#endif /* mozilla_RangedPtr_h */ diff --git a/external/spidermonkey/include/ios/mozilla/ReentrancyGuard.h b/external/spidermonkey/include/ios/mozilla/ReentrancyGuard.h new file mode 100644 index 0000000000..d589f368a2 --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/ReentrancyGuard.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Small helper class for asserting uses of a class are non-reentrant. */ + +#ifndef mozilla_ReentrancyGuard_h +#define mozilla_ReentrancyGuard_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/GuardObjects.h" + +namespace mozilla { + +/* Useful for implementing containers that assert non-reentrancy */ +class ReentrancyGuard +{ + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER +#ifdef DEBUG + bool& entered; +#endif + + public: + template +#ifdef DEBUG + ReentrancyGuard(T& obj + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : entered(obj.entered) +#else + ReentrancyGuard(T& + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) +#endif + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; +#ifdef DEBUG + MOZ_ASSERT(!entered); + entered = true; +#endif + } + ~ReentrancyGuard() + { +#ifdef DEBUG + entered = false; +#endif + } + + private: + ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE; + void operator=(const ReentrancyGuard&) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_ReentrancyGuard_h */ diff --git a/external/spidermonkey/include/ios/mozilla/RefPtr.h b/external/spidermonkey/include/ios/mozilla/RefPtr.h index 9f4163a21a..3c275afdc7 100644 --- a/external/spidermonkey/include/ios/mozilla/RefPtr.h +++ b/external/spidermonkey/include/ios/mozilla/RefPtr.h @@ -1,14 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Helpers for defining and using refcounted objects. */ -#ifndef mozilla_RefPtr_h_ -#define mozilla_RefPtr_h_ +#ifndef mozilla_RefPtr_h +#define mozilla_RefPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/TypeTraits.h" @@ -41,13 +43,19 @@ template OutParamRef byRef(RefPtr&); * state distinguishes use-before-ref (refcount==0) from * use-after-destroy (refcount==0xffffdead). */ -#ifdef DEBUG namespace detail { +#ifdef DEBUG static const int DEAD = 0xffffdead; -} #endif -template +// This is used WeakPtr.h as well as this file. +enum RefCountAtomicity +{ + AtomicRefCount, + NonAtomicRefCount +}; + +template class RefCounted { friend class RefPtr; @@ -56,8 +64,6 @@ class RefCounted RefCounted() : refCnt(0) { } ~RefCounted() { MOZ_ASSERT(refCnt == detail::DEAD); - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from RefCounted"); } public: @@ -87,7 +93,33 @@ class RefCounted } private: - int refCnt; + typename Conditional, int>::Type refCnt; +}; + +} + +template +class RefCounted : public detail::RefCounted +{ + public: + ~RefCounted() { + static_assert(IsBaseOf::value, + "T must derive from RefCounted"); + } +}; + +/** + * AtomicRefCounted is like RefCounted, with an atomically updated + * reference counter. + */ +template +class AtomicRefCounted : public detail::RefCounted +{ + public: + ~AtomicRefCounted() { + static_assert(IsBaseOf::value, + "T must derive from AtomicRefCounted"); + } }; /** @@ -259,9 +291,6 @@ byRef(RefPtr& ptr) } // namespace mozilla -#endif // mozilla_RefPtr_h_ - - #if 0 // Command line that builds these tests @@ -416,3 +445,5 @@ main(int argc, char** argv) } #endif + +#endif /* mozilla_RefPtr_h */ diff --git a/external/spidermonkey/include/ios/mozilla/SHA1.h b/external/spidermonkey/include/ios/mozilla/SHA1.h index a6604e699f..b167648540 100644 --- a/external/spidermonkey/include/ios/mozilla/SHA1.h +++ b/external/spidermonkey/include/ios/mozilla/SHA1.h @@ -1,17 +1,18 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Simple class for computing SHA1. */ -#ifndef mozilla_SHA1_h_ -#define mozilla_SHA1_h_ +#ifndef mozilla_SHA1_h +#define mozilla_SHA1_h -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" #include +#include namespace mozilla { @@ -58,4 +59,4 @@ class SHA1Sum } /* namespace mozilla */ -#endif /* mozilla_SHA1_h_ */ +#endif /* mozilla_SHA1_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Scoped.h b/external/spidermonkey/include/ios/mozilla/Scoped.h index 677a1a3797..fc48584b3e 100644 --- a/external/spidermonkey/include/ios/mozilla/Scoped.h +++ b/external/spidermonkey/include/ios/mozilla/Scoped.h @@ -1,11 +1,13 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* A number of structures to simplify scope-based RAII management. */ -#ifndef mozilla_Scoped_h_ -#define mozilla_Scoped_h_ +#ifndef mozilla_Scoped_h +#define mozilla_Scoped_h /* * Resource Acquisition Is Initialization is a programming idiom used @@ -52,6 +54,7 @@ #include "mozilla/Attributes.h" #include "mozilla/GuardObjects.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -193,7 +196,7 @@ template struct ScopedFreePtrTraits { typedef T* type; - static T* empty() { return NULL; } + static T* empty() { return nullptr; } static void release(T* ptr) { free(ptr); } }; SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits) @@ -256,7 +259,7 @@ template struct TypeSpecificScopedPointerTraits { typedef T* type; - const static type empty() { return NULL; } + const static type empty() { return nullptr; } const static void release(type value) { if (value) @@ -268,4 +271,4 @@ SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) } /* namespace mozilla */ -#endif // mozilla_Scoped_h_ +#endif /* mozilla_Scoped_h */ diff --git a/external/spidermonkey/include/ios/mozilla/SplayTree.h b/external/spidermonkey/include/ios/mozilla/SplayTree.h index f9a10d36dd..de0235aec9 100644 --- a/external/spidermonkey/include/ios/mozilla/SplayTree.h +++ b/external/spidermonkey/include/ios/mozilla/SplayTree.h @@ -1,7 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -10,8 +9,8 @@ * are faster to access again. */ -#ifndef mozilla_SplayTree_h_ -#define mozilla_SplayTree_h_ +#ifndef mozilla_SplayTree_h +#define mozilla_SplayTree_h #include "mozilla/Assertions.h" #include "mozilla/NullPtr.h" @@ -282,4 +281,4 @@ class SplayTree } /* namespace mozilla */ -#endif /* mozilla_SplayTree_h_ */ +#endif /* mozilla_SplayTree_h */ diff --git a/external/spidermonkey/include/ios/mozilla/StandardInteger.h b/external/spidermonkey/include/ios/mozilla/StandardInteger.h deleted file mode 100644 index 8e4c8578f1..0000000000 --- a/external/spidermonkey/include/ios/mozilla/StandardInteger.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implements the C99 interface for C and C++ code. */ - -#ifndef mozilla_StandardInteger_h_ -#define mozilla_StandardInteger_h_ - -/* - * The C99 standard header exposes typedefs for common fixed-width - * integer types. It would be feasible to simply #include , but - * MSVC++ versions prior to 2010 don't provide . We could solve this - * by reimplementing for MSVC++ 2008 and earlier. But then we reach - * a second problem: our custom might conflict with a - * defined by an embedder already looking to work around the MSVC++ - * absence. - * - * We address these issues in this manner: - * - * 1. If the preprocessor macro MOZ_CUSTOM_STDINT_H is defined to a path to a - * custom implementation, we will #include it. Embedders using - * a custom must define this macro to an implementation that - * will work with their embedding. - * 2. Otherwise, if we are compiling with a an MSVC++ version without - * , #include our custom reimplementation. - * 3. Otherwise, #include the standard provided by the compiler. - * - * Note that we can't call this file "stdint.h" or something case-insensitively - * equal to "stdint.h" because then MSVC (and other compilers on - * case-insensitive file systems) will include this file, rather than the system - * stdint.h, when we ask for below. - */ -#if defined(MOZ_CUSTOM_STDINT_H) -# include MOZ_CUSTOM_STDINT_H -#elif defined(_MSC_VER) && _MSC_VER < 1600 -# include "mozilla/MSStdInt.h" -#else -# include -#endif - -#endif /* mozilla_StandardInteger_h_ */ diff --git a/external/spidermonkey/include/ios/mozilla/TemplateLib.h b/external/spidermonkey/include/ios/mozilla/TemplateLib.h new file mode 100644 index 0000000000..50275fdadb --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/TemplateLib.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Reusable template meta-functions on types and compile-time values. Meta- + * functions are placed inside the 'tl' namespace to avoid conflict with non- + * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. + * mozilla::FloorLog2). + * + * When constexpr support becomes universal, we should probably use that instead + * of some of these templates, for simplicity. + */ + +#ifndef mozilla_TemplateLib_h +#define mozilla_TemplateLib_h + +#include +#include + +namespace mozilla { + +namespace tl { + +/** Compute min/max. */ +template +struct Min +{ + static const size_t value = I < J ? I : J; +}; +template +struct Max +{ + static const size_t value = I > J ? I : J; +}; + +/** Compute floor(log2(i)). */ +template +struct FloorLog2 +{ + static const size_t value = 1 + FloorLog2::value; +}; +template<> struct FloorLog2<0> { /* Error */ }; +template<> struct FloorLog2<1> { static const size_t value = 0; }; + +/** Compute ceiling(log2(i)). */ +template +struct CeilingLog2 +{ + static const size_t value = FloorLog2<2 * I - 1>::value; +}; + +/** Round up to the nearest power of 2. */ +template +struct RoundUpPow2 +{ + static const size_t value = size_t(1) << CeilingLog2::value; +}; +template<> +struct RoundUpPow2<0> +{ + static const size_t value = 1; +}; + +/** Compute the number of bits in the given unsigned type. */ +template +struct BitSize +{ + static const size_t value = sizeof(T) * CHAR_BIT; +}; + +/** + * Produce an N-bit mask, where N <= BitSize::value. Handle the + * language-undefined edge case when N = BitSize::value. + */ +template +struct NBitMask +{ + // Assert the precondition. On success this evaluates to 0. Otherwise it + // triggers divide-by-zero at compile time: a guaranteed compile error in + // C++11, and usually one in C++98. Add this value to |value| to assure + // its computation. + static const size_t checkPrecondition = 0 / size_t(N < BitSize::value); + static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; +}; +template<> +struct NBitMask::value> +{ + static const size_t value = size_t(-1); +}; + +/** + * For the unsigned integral type size_t, compute a mask M for N such that + * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) + */ +template +struct MulOverflowMask +{ + static const size_t value = + ~NBitMask::value - CeilingLog2::value>::value; +}; +template<> struct MulOverflowMask<0> { /* Error */ }; +template<> struct MulOverflowMask<1> { static const size_t value = 0; }; + +} // namespace tl + +} // namespace mozilla + +#endif /* mozilla_TemplateLib_h */ diff --git a/external/spidermonkey/include/ios/mozilla/ThreadLocal.h b/external/spidermonkey/include/ios/mozilla/ThreadLocal.h index 2b4eb30207..6df109821f 100644 --- a/external/spidermonkey/include/ios/mozilla/ThreadLocal.h +++ b/external/spidermonkey/include/ios/mozilla/ThreadLocal.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cross-platform lightweight thread local data wrappers. */ -#ifndef mozilla_ThreadLocal_h_ -#define mozilla_ThreadLocal_h_ +#ifndef mozilla_ThreadLocal_h +#define mozilla_ThreadLocal_h #if defined(XP_WIN) // This file will get included in any file that wants to add a profiler mark. @@ -28,6 +29,7 @@ __declspec(dllimport) unsigned long __stdcall TlsAlloc(); #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -98,15 +100,15 @@ template inline bool ThreadLocal::init() { - MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); + static_assert(sizeof(T) <= sizeof(void*), + "mozilla::ThreadLocal can't be used for types larger than " + "a pointer"); MOZ_ASSERT(!initialized()); #ifdef XP_WIN key = TlsAlloc(); inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES #else - inited = !pthread_key_create(&key, NULL); + inited = !pthread_key_create(&key, nullptr); #endif return inited; } @@ -144,4 +146,4 @@ ThreadLocal::set(const T value) } // namespace mozilla -#endif // mozilla_ThreadLocal_h_ +#endif /* mozilla_ThreadLocal_h */ diff --git a/external/spidermonkey/include/ios/mozilla/TypeTraits.h b/external/spidermonkey/include/ios/mozilla/TypeTraits.h index 656bc775f8..53c0b5c2f6 100644 --- a/external/spidermonkey/include/ios/mozilla/TypeTraits.h +++ b/external/spidermonkey/include/ios/mozilla/TypeTraits.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Template-based metaprogramming and type-testing facilities. */ -#ifndef mozilla_TypeTraits_h_ -#define mozilla_TypeTraits_h_ +#ifndef mozilla_TypeTraits_h +#define mozilla_TypeTraits_h /* * These traits are approximate copies of the traits and semantics from C++11's @@ -126,6 +127,28 @@ struct IsPointer : FalseType {}; template struct IsPointer : TrueType {}; +namespace detail { + +// __is_enum is a supported extension across all of our supported compilers. +template +struct IsEnumHelper + : IntegralConstant +{}; + +} // namespace detail + +/** + * IsEnum determines whether a type is an enum type. + * + * mozilla::IsEnum::value is true; + * mozilla::IsEnum::value is false; + * mozilla::IsEnum::value is false; + */ +template +struct IsEnum + : detail::IsEnumHelper::Type> +{}; + /* 20.9.4.2 Composite type traits [meta.unary.comp] */ /** @@ -197,8 +220,24 @@ template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; template struct IsPod : TrueType {}; +namespace detail { + +template::value> +struct IsSignedHelper; + +template +struct IsSignedHelper : TrueType {}; + +template +struct IsSignedHelper + : IntegralConstant::value && T(-1) < T(1)> +{}; + +} // namespace detail + /** - * IsSigned determines whether a type is a signed arithmetic type. + * IsSigned determines whether a type is a signed arithmetic type. |char| is + * considered a signed type if it has the same representation as |signed char|. * * Don't use this if the type might be user-defined! You might or might not get * a compile error, depending. @@ -209,10 +248,26 @@ template struct IsPod : TrueType {}; * mozilla::IsSigned::value is true. */ template -struct IsSigned - : IntegralConstant::value && T(-1) < T(0)> +struct IsSigned : detail::IsSignedHelper {}; + +namespace detail { + +template::value> +struct IsUnsignedHelper; + +template +struct IsUnsignedHelper : FalseType {}; + +template +struct IsUnsignedHelper + : IntegralConstant::value && + (IsSame::Type, bool>::value || + T(1) < T(-1))> {}; +} // namespace detail + /** * IsUnsigned determines whether a type is an unsigned arithmetic type. * @@ -225,9 +280,7 @@ struct IsSigned * mozilla::IsUnsigned::value is false. */ template -struct IsUnsigned - : IntegralConstant::value && T(0) < T(-1)> -{}; +struct IsUnsigned : detail::IsUnsignedHelper {}; /* 20.9.5 Type property queries [meta.unary.prop.query] */ @@ -427,6 +480,160 @@ struct RemoveCV /* 20.9.7.3 Sign modifications [meta.trans.sign] */ +template +struct EnableIf; + +template +struct Conditional; + +namespace detail { + +template +struct WithC : Conditional +{}; + +template +struct WithV : Conditional +{}; + + +template +struct WithCV : WithC::Type> +{}; + +template +struct CorrespondingSigned; + +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef short Type; }; +template<> +struct CorrespondingSigned { typedef int Type; }; +template<> +struct CorrespondingSigned { typedef long Type; }; +template<> +struct CorrespondingSigned { typedef long long Type; }; + +template::Type, + bool IsSignedIntegerType = IsSigned::value && + !IsSame::value> +struct MakeSigned; + +template +struct MakeSigned +{ + typedef T Type; +}; + +template +struct MakeSigned + : WithCV::value, IsVolatile::value, + typename CorrespondingSigned::Type> +{}; + +} // namespace detail + +/** + * MakeSigned produces the corresponding signed integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already a signed integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an unsigned integer type, the signed variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the integral type of the same size as T, with the lowest rank, + * with T's const/volatile qualifiers, is produced. (This basically only acts + * to produce signed char when T = char.) + * + * mozilla::MakeSigned::Type is signed long; + * mozilla::MakeSigned::Type is volatile int; + * mozilla::MakeSigned::Type is const signed short; + * mozilla::MakeSigned::Type is const signed char; + * mozilla::MakeSigned is an error; + * mozilla::MakeSigned is an error. + */ +template +struct MakeSigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeSigned + >::Type +{}; + +namespace detail { + +template +struct CorrespondingUnsigned; + +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned short Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned int Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long long Type; }; + + +template::Type, + bool IsUnsignedIntegerType = IsUnsigned::value && + !IsSame::value> +struct MakeUnsigned; + +template +struct MakeUnsigned +{ + typedef T Type; +}; + +template +struct MakeUnsigned + : WithCV::value, IsVolatile::value, + typename CorrespondingUnsigned::Type> +{}; + +} // namespace detail + +/** + * MakeUnsigned produces the corresponding unsigned integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already an unsigned integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an signed integer type, the unsigned variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the unsigned integral type of the same size as T, with the lowest + * rank, with T's const/volatile qualifiers, is produced. (This basically only + * acts to produce unsigned char when T = char.) + * + * mozilla::MakeUnsigned::Type is unsigned long; + * mozilla::MakeUnsigned::Type is volatile unsigned int; + * mozilla::MakeUnsigned::Type is const unsigned short; + * mozilla::MakeUnsigned::Type is const unsigned char; + * mozilla::MakeUnsigned is an error; + * mozilla::MakeUnsigned is an error. + */ +template +struct MakeUnsigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeUnsigned + >::Type +{}; + /* 20.9.7.4 Array modifications [meta.trans.arr] */ /* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ @@ -451,7 +658,7 @@ struct RemoveCV * ... * }; */ -template +template struct EnableIf {}; @@ -481,4 +688,4 @@ struct Conditional } /* namespace mozilla */ -#endif /* mozilla_TypeTraits_h_ */ +#endif /* mozilla_TypeTraits_h */ diff --git a/external/spidermonkey/include/ios/mozilla/TypedEnum.h b/external/spidermonkey/include/ios/mozilla/TypedEnum.h index 889960a32d..6f595cb4c5 100644 --- a/external/spidermonkey/include/ios/mozilla/TypedEnum.h +++ b/external/spidermonkey/include/ios/mozilla/TypedEnum.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Macros to emulate C++11 typed enums and enum classes. */ -#ifndef mozilla_TypedEnum_h_ -#define mozilla_TypedEnum_h_ +#ifndef mozilla_TypedEnum_h +#define mozilla_TypedEnum_h #include "mozilla/Attributes.h" @@ -91,16 +92,33 @@ * mandatory. As with MOZ_ENUM_TYPE(), it will do nothing on compilers that do * not support it. * - * Note that the workaround implemented here is not compatible with enums - * nested inside a class. + * MOZ_{BEGIN,END}_ENUM_CLASS doesn't work for defining enum classes nested + * inside classes. To define an enum class nested inside another class, use + * MOZ_{BEGIN,END}_NESTED_ENUM_CLASS, and place a MOZ_FINISH_NESTED_ENUM_CLASS + * in namespace scope to handle bits that can only be implemented with + * namespace-scoped code. For example: + * + * class FooBar { + * + * MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t) + * A, + * B = 6 + * MOZ_END_NESTED_ENUM_CLASS(Enum) + * + * }; + * + * MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum) */ #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) /* * All compilers that support strong enums also support an explicit * underlying type, so no extra check is needed. */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) enum class Name : type { -# define MOZ_END_ENUM_CLASS(Name) }; +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ + enum class Name : type { +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) /* nothing */ #else /** * We need Name to both name a type, and scope the provided enumerator @@ -136,14 +154,14 @@ * { * return Enum::A; * } - */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) \ + */\ +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ class Name \ { \ public: \ enum Enum MOZ_ENUM_TYPE(type) \ { -# define MOZ_END_ENUM_CLASS(Name) \ +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; \ Name() {} \ Name(Enum aEnum) : mEnum(aEnum) {} \ @@ -151,7 +169,8 @@ operator Enum() const { return mEnum; } \ private: \ Enum mEnum; \ - }; \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) \ inline int operator+(const int&, const Name::Enum&) MOZ_DELETE; \ inline int operator+(const Name::Enum&, const int&) MOZ_DELETE; \ inline int operator-(const int&, const Name::Enum&) MOZ_DELETE; \ @@ -207,7 +226,11 @@ inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \ inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE; #endif +# define MOZ_BEGIN_ENUM_CLASS(Name, type) MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) +# define MOZ_END_ENUM_CLASS(Name) \ + MOZ_END_NESTED_ENUM_CLASS(Name) \ + MOZ_FINISH_NESTED_ENUM_CLASS(Name) #endif /* __cplusplus */ -#endif /* mozilla_TypedEnum_h_ */ +#endif /* mozilla_TypedEnum_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Types.h b/external/spidermonkey/include/ios/mozilla/Types.h index 56e5cb82fb..5340b2b600 100644 --- a/external/spidermonkey/include/ios/mozilla/Types.h +++ b/external/spidermonkey/include/ios/mozilla/Types.h @@ -1,28 +1,22 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt foundational types and macros. */ -#ifndef mozilla_Types_h_ -#define mozilla_Types_h_ +#ifndef mozilla_Types_h +#define mozilla_Types_h /* * This header must be valid C and C++, includable by code embedding either * SpiderMonkey or Gecko. */ -/* - * Expose all the integer types defined in C99's (and the integer - * limit and constant macros, if compiling C code or if compiling C++ code and - * the right __STDC_*_MACRO has been defined for each). These are all usable - * throughout mfbt code, and throughout Mozilla code more generally. - */ -#include "mozilla/StandardInteger.h" - -/* Also expose size_t. */ +/* Expose all types and size_t. */ #include +#include /* Implement compiler and linker macros needed for APIs. */ @@ -133,4 +127,12 @@ # define MOZ_END_EXTERN_C #endif -#endif /* mozilla_Types_h_ */ +/* + * GCC's typeof is available when decltype is not. + */ +#if defined(__GNUC__) && defined(__cplusplus) && \ + !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +# define decltype __typeof__ +#endif + +#endif /* mozilla_Types_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Util.h b/external/spidermonkey/include/ios/mozilla/Util.h index 097c5478eb..4f1c634a59 100644 --- a/external/spidermonkey/include/ios/mozilla/Util.h +++ b/external/spidermonkey/include/ios/mozilla/Util.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * new headers, or to other appropriate existing headers, not here. */ -#ifndef mozilla_Util_h_ -#define mozilla_Util_h_ +#ifndef mozilla_Util_h +#define mozilla_Util_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" @@ -196,6 +197,58 @@ class Maybe constructed = true; } + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); + constructed = true; + } + T* addr() { MOZ_ASSERT(constructed); return &asT(); @@ -271,7 +324,7 @@ ArrayEnd(T (&arr)[N]) /* * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for MOZ_STATIC_ASSERT() calls that + * that can't use C++ template functions and for static_assert() calls that * can't call ArrayLength() when it is not a C++11 constexpr function. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR @@ -280,4 +333,4 @@ ArrayEnd(T (&arr)[N]) # define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) #endif -#endif /* mozilla_Util_h_ */ +#endif /* mozilla_Util_h */ diff --git a/external/spidermonkey/include/ios/mozilla/Vector.h b/external/spidermonkey/include/ios/mozilla/Vector.h new file mode 100644 index 0000000000..8759df8c06 --- /dev/null +++ b/external/spidermonkey/include/ios/mozilla/Vector.h @@ -0,0 +1,1190 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A type/length-parametrized vector class. */ + +#ifndef mozilla_Vector_h +#define mozilla_Vector_h + +#include "mozilla/AllocPolicy.h" +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" +#include "mozilla/NullPtr.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" +#include "mozilla/TypeTraits.h" +#include "mozilla/Util.h" + +#include // for placement new + +/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4345) +#endif + +namespace mozilla { + +template +class VectorBase; + +namespace detail { + +/* + * Check that the given capacity wastes the minimal amount of space if + * allocated on the heap. This means that cap*sizeof(T) is as close to a + * power-of-two as possible. growStorageBy() is responsible for ensuring + * this. + */ +template +static bool CapacityHasExcessSpace(size_t cap) +{ + size_t size = cap * sizeof(T); + return RoundUpPow2(size) - size >= sizeof(T); +} + +/* + * This template class provides a default implementation for vector operations + * when the element type is not known to be a POD, as judged by IsPod. + */ +template +struct VectorImpl +{ + /* Destroys constructed objects in the range [begin, end). */ + static inline void destroy(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + p->~T(); + } + + /* Constructs objects in the uninitialized range [begin, end). */ + static inline void initialize(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + /* + * Copy-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(*p); + } + + /* + * Move-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(Move(*p)); + } + + /* + * Copy-constructs objects in the uninitialized range [dst, dst+n) from the + * same object u. + */ + template + static inline void copyConstructN(T* dst, size_t n, const U& u) { + for (T* end = dst + n; dst < end; ++dst) + new(dst) T(u); + } + + /* + * Grows the given buffer to have capacity newCap, preserving the objects + * constructed in the range [begin, end) and updating v. Assumes that (1) + * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will + * not overflow. + */ + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + T* newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); + if (!newbuf) + return false; + T* dst = newbuf; + T* src = v.beginNoCheck(); + for (; src < v.endNoCheck(); ++dst, ++src) + new(dst) T(Move(*src)); + VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); + v.free_(v.mBegin); + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +/* + * This partial template specialization provides a default implementation for + * vector operations when the element type is known to be a POD, as judged by + * IsPod. + */ +template +struct VectorImpl +{ + static inline void destroy(T*, T*) {} + + static inline void initialize(T* begin, T* end) { + /* + * You would think that memset would be a big win (or even break even) + * when we know T is a POD. But currently it's not. This is probably + * because |append| tends to be given small ranges and memset requires + * a function call that doesn't get inlined. + * + * memset(begin, 0, sizeof(T) * (end-begin)); + */ + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + /* + * See above memset comment. Also, notice that copyConstruct is + * currently templated (T != U), so memcpy won't work without + * requiring T == U. + * + * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); + */ + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + *dst = *p; + } + + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + copyConstruct(dst, srcbeg, srcend); + } + + static inline void copyConstructN(T* dst, size_t n, const T& t) { + for (T* end = dst + n; dst < end; ++dst) + *dst = t; + } + + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + size_t oldSize = sizeof(T) * v.mCapacity; + size_t newSize = sizeof(T) * newCap; + T* newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); + if (!newbuf) + return false; + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +} // namespace detail + +/* + * A CRTP base class for vector-like classes. Unless you really really want + * your own vector class -- and you almost certainly don't -- you should use + * mozilla::Vector instead! + * + * See mozilla::Vector for interface requirements. + */ +template +class VectorBase : private AllocPolicy +{ + /* utilities */ + + static const bool sElemIsPod = IsPod::value; + typedef detail::VectorImpl Impl; + friend struct detail::VectorImpl; + + bool growStorageBy(size_t incr); + bool convertToHeapStorage(size_t newCap); + + /* magic constants */ + + static const int sMaxInlineBytes = 1024; + + /* compute constants */ + + /* + * Consider element size to be 1 for buffer sizing if there are 0 inline + * elements. This allows us to compile when the definition of the element + * type is not visible here. + * + * Explicit specialization is only allowed at namespace scope, so in order + * to keep everything here, we use a dummy template parameter with partial + * specialization. + */ + template + struct ElemSize + { + static const size_t value = sizeof(T); + }; + template + struct ElemSize<0, Dummy> + { + static const size_t value = 1; + }; + + static const size_t sInlineCapacity = + tl::Min::value>::value; + + /* Calculate inline buffer size; avoid 0-sized array. */ + static const size_t sInlineBytes = + tl::Max<1, sInlineCapacity * ElemSize::value>::value; + + /* member data */ + + /* + * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, + * mBegin + mLength) hold valid constructed T objects. The range [mBegin + + * mLength, mBegin + mCapacity) holds uninitialized memory. The range + * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory + * previously allocated by a call to reserve(). + */ + T* mBegin; + + /* Number of elements in the vector. */ + size_t mLength; + + /* Max number of elements storable in the vector without resizing. */ + size_t mCapacity; + +#ifdef DEBUG + /* Max elements of reserved or used space in this vector. */ + size_t mReserved; +#endif + + /* Memory used for inline storage. */ + AlignedStorage storage; + +#ifdef DEBUG + friend class ReentrancyGuard; + bool entered; +#endif + + /* private accessors */ + + bool usingInlineStorage() const { + return mBegin == const_cast(this)->inlineStorage(); + } + + T* inlineStorage() { + return static_cast(storage.addr()); + } + + T* beginNoCheck() const { + return mBegin; + } + + T* endNoCheck() { + return mBegin + mLength; + } + + const T* endNoCheck() const { + return mBegin + mLength; + } + +#ifdef DEBUG + size_t reserved() const { + MOZ_ASSERT(mReserved <= mCapacity); + MOZ_ASSERT(mLength <= mReserved); + return mReserved; + } +#endif + + /* Append operations guaranteed to succeed due to pre-reserved space. */ + template void internalAppend(const U& u); + template + void internalAppendAll(const VectorBase& u); + void internalAppendN(const T& t, size_t n); + template void internalAppend(const U* begin, size_t length); + + public: + static const size_t sMaxInlineStorage = N; + + typedef T ElementType; + + VectorBase(AllocPolicy = AllocPolicy()); + VectorBase(MoveRef); /* Move constructor. */ + ThisVector& operator=(MoveRef); /* Move assignment. */ + ~VectorBase(); + + /* accessors */ + + const AllocPolicy& allocPolicy() const { + return *this; + } + + AllocPolicy& allocPolicy() { + return *this; + } + + enum { InlineLength = N }; + + size_t length() const { + return mLength; + } + + bool empty() const { + return mLength == 0; + } + + size_t capacity() const { + return mCapacity; + } + + T* begin() { + MOZ_ASSERT(!entered); + return mBegin; + } + + const T* begin() const { + MOZ_ASSERT(!entered); + return mBegin; + } + + T* end() { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + const T* end() const { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + T& operator[](size_t i) { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + T& back() { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + const T& back() const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + class Range + { + friend class VectorBase; + T* cur_; + T* end_; + Range(T* cur, T* end) : cur_(cur), end_(end) {} + + public: + Range() {} + bool empty() const { return cur_ == end_; } + size_t remain() const { return end_ - cur_; } + T& front() const { return *cur_; } + void popFront() { MOZ_ASSERT(!empty()); ++cur_; } + T popCopyFront() { MOZ_ASSERT(!empty()); return *cur_++; } + }; + + Range all() { + return Range(begin(), end()); + } + + /* mutators */ + + /** + * Given that the vector is empty and has no inline storage, grow to + * |capacity|. + */ + bool initCapacity(size_t request); + + /** + * If reserve(length() + N) succeeds, the N next appends are guaranteed to + * succeed. + */ + bool reserve(size_t request); + + /** + * Destroy elements in the range [end() - incr, end()). Does not deallocate + * or unreserve storage for those elements. + */ + void shrinkBy(size_t incr); + + /** Grow the vector by incr elements. */ + bool growBy(size_t incr); + + /** Call shrinkBy or growBy based on whether newSize > length(). */ + bool resize(size_t newLength); + + /** + * Increase the length of the vector, but don't initialize the new elements + * -- leave them as uninitialized memory. + */ + bool growByUninitialized(size_t incr); + bool resizeUninitialized(size_t newLength); + + /** Shorthand for shrinkBy(length()). */ + void clear(); + + /** Clears and releases any heap-allocated storage. */ + void clearAndFree(); + + /** + * If true, appending |needed| elements won't reallocate elements storage. + * This *doesn't* mean that infallibleAppend may be used! You still must + * reserve the extra space, even if this method indicates that appends won't + * need to reallocate elements storage. + */ + bool canAppendWithoutRealloc(size_t needed) const; + + /** + * Potentially fallible append operations. + * + * The function templates that take an unspecified type U require a const T& + * or a MoveRef. The MoveRef variants move their operands into the + * vector, instead of copying them. If they fail, the operand is left + * unmoved. + */ + template bool append(const U& u); + template + bool appendAll(const VectorBase& u); + bool appendN(const T& t, size_t n); + template bool append(const U* begin, const U* end); + template bool append(const U* begin, size_t length); + + /* + * Guaranteed-infallible append operations for use upon vectors whose + * memory has been pre-reserved. Don't use this if you haven't reserved the + * memory! + */ + template void infallibleAppend(const U& u) { + internalAppend(u); + } + void infallibleAppendN(const T& t, size_t n) { + internalAppendN(t, n); + } + template void infallibleAppend(const U* aBegin, const U* aEnd) { + internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); + } + template void infallibleAppend(const U* aBegin, size_t aLength) { + internalAppend(aBegin, aLength); + } + + void popBack(); + + T popCopy(); + + /** + * Transfers ownership of the internal buffer used by this vector to the + * caller. (It's the caller's responsibility to properly deallocate this + * buffer, in accordance with this vector's AllocPolicy.) After this call, + * the vector is empty. Since the returned buffer may need to be allocated + * (if the elements are currently stored in-place), the call can fail, + * returning nullptr. + * + * N.B. Although a T*, only the range [0, length()) is constructed. + */ + T* extractRawBuffer(); + + /** + * Transfer ownership of an array of objects into the vector. The caller + * must have allocated the array in accordance with this vector's + * AllocPolicy. + * + * N.B. This call assumes that there are no uninitialized elements in the + * passed array. + */ + void replaceRawBuffer(T* p, size_t length); + + /** + * Places |val| at position |p|, shifting existing elements from |p| onward + * one position higher. On success, |p| should not be reused because it'll + * be a dangling pointer if reallocation of the vector storage occurred; the + * return value should be used instead. On failure, nullptr is returned. + * + * Example usage: + * + * if (!(p = vec.insert(p, val))) + * + * + * + * This is inherently a linear-time operation. Be careful! + */ + T* insert(T* p, const T& val); + + /** + * Removes the element |t|, which must fall in the bounds [begin, end), + * shifting existing elements from |t + 1| onward one position lower. + */ + void erase(T* t); + + /** + * Measure the size of the vector's heap-allocated storage. + */ + size_t sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const; + + /** + * Like sizeOfExcludingThis, but also measures the size of the vector + * object (which must be heap-allocated) itself. + */ + size_t sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const; + + void swap(ThisVector& other); + + private: + VectorBase(const ThisVector&) MOZ_DELETE; + void operator=(const ThisVector&) MOZ_DELETE; +}; + +/* This does the re-entrancy check plus several other sanity checks. */ +#define MOZ_REENTRANCY_GUARD_ET_AL \ + ReentrancyGuard g(*this); \ + MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ + MOZ_ASSERT(reserved() <= mCapacity); \ + MOZ_ASSERT(mLength <= reserved()); \ + MOZ_ASSERT(mLength <= mCapacity) + +/* Vector Implementation */ + +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(AP ap) + : AP(ap), + mBegin(static_cast(storage.addr())), + mLength(0), + mCapacity(sInlineCapacity) +#ifdef DEBUG + , mReserved(sInlineCapacity), + entered(false) +#endif +{} + +/* Move constructor. */ +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(MoveRef rhs) + : AllocPolicy(rhs) +#ifdef DEBUG + , entered(false) +#endif +{ + mLength = rhs->mLength; + mCapacity = rhs->mCapacity; +#ifdef DEBUG + mReserved = rhs->mReserved; +#endif + + if (rhs->usingInlineStorage()) { + /* We can't move the buffer over in this case, so copy elements. */ + mBegin = static_cast(storage.addr()); + Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); + /* + * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. + * The elements in its in-line storage still need to be destroyed. + */ + } else { + /* + * Take src's buffer, and turn src into an empty vector using + * in-line storage. + */ + mBegin = rhs->mBegin; + rhs->mBegin = static_cast(rhs->storage.addr()); + rhs->mCapacity = sInlineCapacity; + rhs->mLength = 0; +#ifdef DEBUG + rhs->mReserved = sInlineCapacity; +#endif + } +} + +/* Move assignment. */ +template +MOZ_ALWAYS_INLINE +TV& +VectorBase::operator=(MoveRef rhs) +{ + TV* tv = static_cast(this); + tv->~TV(); + new(tv) TV(rhs); + return *tv; +} + +template +MOZ_ALWAYS_INLINE +VectorBase::~VectorBase() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); +} + +/* + * This function will create a new heap buffer with capacity newCap, + * move all elements in the inline buffer to this new buffer, + * and fail on OOM. + */ +template +inline bool +VectorBase::convertToHeapStorage(size_t newCap) +{ + MOZ_ASSERT(usingInlineStorage()); + + /* Allocate buffer. */ + MOZ_ASSERT(!detail::CapacityHasExcessSpace(newCap)); + T* newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); + if (!newBuf) + return false; + + /* Copy inline elements into heap buffer. */ + Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + + /* Switch in heap buffer. */ + mBegin = newBuf; + /* mLength is unchanged. */ + mCapacity = newCap; + return true; +} + +template +MOZ_NEVER_INLINE bool +VectorBase::growStorageBy(size_t incr) +{ + MOZ_ASSERT(mLength + incr > mCapacity); + MOZ_ASSERT_IF(!usingInlineStorage(), + !detail::CapacityHasExcessSpace(mCapacity)); + + /* + * When choosing a new capacity, its size should is as close to 2**N bytes + * as possible. 2**N-sized requests are best because they are unlikely to + * be rounded up by the allocator. Asking for a 2**N number of elements + * isn't as good, because if sizeof(T) is not a power-of-two that would + * result in a non-2**N request size. + */ + + size_t newCap; + + if (incr == 1) { + if (usingInlineStorage()) { + /* This case occurs in ~70--80% of the calls to this function. */ + size_t newSize = + tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::value; + newCap = newSize / sizeof(T); + goto convert; + } + + if (mLength == 0) { + /* This case occurs in ~0--10% of the calls to this function. */ + newCap = 1; + goto grow; + } + + /* This case occurs in ~15--20% of the calls to this function. */ + + /* + * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector + * to 1GB of memory on a 32-bit system, which is a reasonable limit. It + * also ensures that + * + * static_cast(end()) - static_cast(begin()) + * + * doesn't overflow ptrdiff_t (see bug 510319). + */ + if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::value) { + this->reportAllocOverflow(); + return false; + } + + /* + * If we reach here, the existing capacity will have a size that is already + * as close to 2^N as sizeof(T) will allow. Just double the capacity, and + * then there might be space for one more element. + */ + newCap = mLength * 2; + if (detail::CapacityHasExcessSpace(newCap)) + newCap += 1; + } else { + /* This case occurs in ~2% of the calls to this function. */ + size_t newMinCap = mLength + incr; + + /* Did mLength + incr overflow? Will newCap * sizeof(T) overflow? */ + if (newMinCap < mLength || + newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value) + { + this->reportAllocOverflow(); + return false; + } + + size_t newMinSize = newMinCap * sizeof(T); + size_t newSize = RoundUpPow2(newMinSize); + newCap = newSize / sizeof(T); + } + + if (usingInlineStorage()) { + convert: + return convertToHeapStorage(newCap); + } + +grow: + return Impl::growTo(*this, newCap); +} + +template +inline bool +VectorBase::initCapacity(size_t request) +{ + MOZ_ASSERT(empty()); + MOZ_ASSERT(usingInlineStorage()); + if (request == 0) + return true; + T* newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); + if (!newbuf) + return false; + mBegin = newbuf; + mCapacity = request; +#ifdef DEBUG + mReserved = request; +#endif + return true; +} + +template +inline bool +VectorBase::reserve(size_t request) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (request > mCapacity && !growStorageBy(request - mLength)) + return false; + +#ifdef DEBUG + if (request > mReserved) + mReserved = request; + MOZ_ASSERT(mLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); +#endif + return true; +} + +template +inline void +VectorBase::shrinkBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(incr <= mLength); + Impl::destroy(endNoCheck() - incr, endNoCheck()); + mLength -= incr; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + T* newend = endNoCheck() + incr; + Impl::initialize(endNoCheck(), newend); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growByUninitialized(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +inline bool +VectorBase::resize(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growBy(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::resizeUninitialized(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growByUninitialized(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +inline void +VectorBase::clear() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + mLength = 0; +} + +template +inline void +VectorBase::clearAndFree() +{ + clear(); + + if (usingInlineStorage()) + return; + + this->free_(beginNoCheck()); + mBegin = static_cast(storage.addr()); + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif +} + +template +inline bool +VectorBase::canAppendWithoutRealloc(size_t needed) const +{ + return mLength + needed <= mCapacity; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendAll(const VectorBase& other) +{ + internalAppend(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U& u) +{ + MOZ_ASSERT(mLength + 1 <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + new(endNoCheck()) T(u); + ++mLength; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendN(const T& t, size_t needed) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppendN(t, needed); + return true; +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendN(const T& t, size_t needed) +{ + MOZ_ASSERT(mLength + needed <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstructN(endNoCheck(), needed, t); + mLength += needed; +} + +template +inline T* +VectorBase::insert(T* p, const T& val) +{ + MOZ_ASSERT(begin() <= p); + MOZ_ASSERT(p <= end()); + size_t pos = p - begin(); + MOZ_ASSERT(pos <= mLength); + size_t oldLength = mLength; + if (pos == oldLength) { + if (!append(val)) + return nullptr; + } else { + T oldBack = back(); + if (!append(oldBack)) /* Dup the last element. */ + return nullptr; + for (size_t i = oldLength; i > pos; --i) + (*this)[i] = (*this)[i - 1]; + (*this)[pos] = val; + } + return begin() + pos; +} + +template +inline void +VectorBase::erase(T* it) +{ + MOZ_ASSERT(begin() <= it); + MOZ_ASSERT(it < end()); + while (it + 1 < end()) { + *it = *(it + 1); + ++it; + } + popBack(); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U* insBegin, const U* insEnd) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + size_t needed = PointerRangeSize(insBegin, insEnd); + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppend(insBegin, needed); + return true; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U* insBegin, size_t insLength) +{ + MOZ_ASSERT(mLength + insLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); + mLength += insLength; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U& u) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength == mCapacity && !growStorageBy(1)) + return false; + +#ifdef DEBUG + if (mLength + 1 > mReserved) + mReserved = mLength + 1; +#endif + internalAppend(u); + return true; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendAll(const VectorBase& other) +{ + return append(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U *insBegin, size_t insLength) +{ + return append(insBegin, insBegin + insLength); +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::popBack() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(!empty()); + --mLength; + endNoCheck()->~T(); +} + +template +MOZ_ALWAYS_INLINE T +VectorBase::popCopy() +{ + T ret = back(); + popBack(); + return ret; +} + +template +inline T* +VectorBase::extractRawBuffer() +{ + T* ret; + if (usingInlineStorage()) { + ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); + if (!ret) + return nullptr; + Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + /* mBegin, mCapacity are unchanged. */ + mLength = 0; + } else { + ret = mBegin; + mBegin = static_cast(storage.addr()); + mLength = 0; + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif + } + return ret; +} + +template +inline void +VectorBase::replaceRawBuffer(T* p, size_t aLength) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + + /* Destroy what we have. */ + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); + + /* Take in the new buffer. */ + if (aLength <= sInlineCapacity) { + /* + * We convert to inline storage if possible, even though p might + * otherwise be acceptable. Maybe this behaviour should be + * specifiable with an argument to this function. + */ + mBegin = static_cast(storage.addr()); + mLength = aLength; + mCapacity = sInlineCapacity; + Impl::moveConstruct(mBegin, p, p + aLength); + Impl::destroy(p, p + aLength); + this->free_(p); + } else { + mBegin = p; + mLength = aLength; + mCapacity = aLength; + } +#ifdef DEBUG + mReserved = aLength; +#endif +} + +template +inline size_t +VectorBase::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const +{ + return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); +} + +template +inline size_t +VectorBase::sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const +{ + return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); +} + +template +inline void +VectorBase::swap(TV& other) +{ + static_assert(N == 0, + "still need to implement this for N != 0"); + + // This only works when inline storage is always empty. + if (!usingInlineStorage() && other.usingInlineStorage()) { + other.mBegin = mBegin; + mBegin = inlineStorage(); + } else if (usingInlineStorage() && !other.usingInlineStorage()) { + mBegin = other.mBegin; + other.mBegin = other.inlineStorage(); + } else if (!usingInlineStorage() && !other.usingInlineStorage()) { + Swap(mBegin, other.mBegin); + } else { + // This case is a no-op, since we'd set both to use their inline storage. + } + + Swap(mLength, other.mLength); + Swap(mCapacity, other.mCapacity); +#ifdef DEBUG + Swap(mReserved, other.mReserved); +#endif +} + +/* + * STL-like container providing a short-lived, dynamic buffer. Vector calls the + * constructors/destructors of all elements stored in its internal buffer, so + * non-PODs may be safely used. Additionally, Vector will store the first N + * elements in-place before resorting to dynamic allocation. + * + * T requirements: + * - default and copy constructible, assignable, destructible + * - operations do not throw + * N requirements: + * - any value, however, N is clamped to min/max values + * AllocPolicy: + * - see "Allocation policies" in AllocPolicy.h (defaults to + * mozilla::MallocAllocPolicy) + * + * Vector is not reentrant: T member functions called during Vector member + * functions must not call back into the same object! + */ +template +class Vector + : public VectorBase > +{ + typedef VectorBase Base; + + public: + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector& operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); + } +}; + +} // namespace mozilla + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif /* mozilla_Vector_h */ diff --git a/external/spidermonkey/include/ios/mozilla/WeakPtr.h b/external/spidermonkey/include/ios/mozilla/WeakPtr.h index d61b0b37d3..c714ebf565 100644 --- a/external/spidermonkey/include/ios/mozilla/WeakPtr.h +++ b/external/spidermonkey/include/ios/mozilla/WeakPtr.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Weak pointer functionality, implemented as a mixin for use with any class. */ @@ -13,6 +14,9 @@ * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime * of 'Foo'. * + * AtomicSupportsWeakPtr can be used for a variant with an atomically updated + * reference counter. + * * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional * dereference, and an additional heap allocated pointer sized object shared * between all of the WeakPtrs. @@ -55,10 +59,11 @@ * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h */ -#ifndef mozilla_WeakPtr_h_ -#define mozilla_WeakPtr_h_ +#ifndef mozilla_WeakPtr_h +#define mozilla_WeakPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/NullPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/TypeTraits.h" @@ -71,8 +76,8 @@ template class SupportsWeakPtrBase; namespace detail { // This can live beyond the lifetime of the class derived from SupportsWeakPtrBase. -template -class WeakReference : public RefCounted > +template +class WeakReference : public RefCounted, Atomicity> { public: explicit WeakReference(T* p) : ptr(p) {} @@ -81,8 +86,8 @@ class WeakReference : public RefCounted > } private: - friend class WeakPtrBase >; - friend class SupportsWeakPtrBase >; + friend class WeakPtrBase; + friend class SupportsWeakPtrBase; void detach() { ptr = nullptr; } @@ -103,8 +108,8 @@ class SupportsWeakPtrBase protected: ~SupportsWeakPtrBase() { - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from SupportsWeakPtrBase"); + static_assert(IsBaseOf, T>::value, + "T must derive from SupportsWeakPtrBase"); if (weakRef) weakRef->detach(); } @@ -116,10 +121,30 @@ class SupportsWeakPtrBase }; template -class SupportsWeakPtr : public SupportsWeakPtrBase > +class SupportsWeakPtr + : public SupportsWeakPtrBase > { }; +template +class AtomicSupportsWeakPtr + : public SupportsWeakPtrBase > +{ +}; + +namespace detail { + +template +struct WeakReferenceCount +{ + static const RefCountAtomicity atomicity = + IsBaseOf, T>::value + ? AtomicRefCount + : NonAtomicRefCount; +}; + +} + template class WeakPtrBase { @@ -152,9 +177,9 @@ class WeakPtrBase }; template -class WeakPtr : public WeakPtrBase > +class WeakPtr : public WeakPtrBase::atomicity> > { - typedef WeakPtrBase > Base; + typedef WeakPtrBase::atomicity> > Base; public: WeakPtr(const WeakPtr& o) : Base(o) {} WeakPtr(const Base& o) : Base(o) {} @@ -163,4 +188,4 @@ class WeakPtr : public WeakPtrBase > } // namespace mozilla -#endif /* ifdef mozilla_WeakPtr_h_ */ +#endif /* mozilla_WeakPtr_h */ diff --git a/external/spidermonkey/include/mac/js-config.h b/external/spidermonkey/include/mac/js-config.h index 6a77e674d7..ae4f2abf71 100644 --- a/external/spidermonkey/include/mac/js-config.h +++ b/external/spidermonkey/include/mac/js-config.h @@ -38,8 +38,8 @@ JS_HAVE_STDINT_H. */ #define JS_BYTES_PER_WORD 8 -/* Some mozilla code uses JS-friend APIs that depend on JS_METHODJIT being - correct. */ -#define JS_METHODJIT 1 +/* MOZILLA JSAPI version number components */ +#define MOZJS_MAJOR_VERSION 25 +#define MOZJS_MINOR_VERSION 0 #endif /* js_config_h___ */ diff --git a/external/spidermonkey/include/mac/js.msg b/external/spidermonkey/include/mac/js.msg index 3e57bdf174..3f665d8d54 100644 --- a/external/spidermonkey/include/mac/js.msg +++ b/external/spidermonkey/include/mac/js.msg @@ -184,7 +184,7 @@ MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} oper MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id") MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error") -MSG_DEF(JSMSG_UNUSED134, 134, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 134, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent") MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory") @@ -193,10 +193,10 @@ MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many paren MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment") MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_UNUSED143, 143, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 143, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_UNUSED146, 146, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 146, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses") @@ -220,7 +220,7 @@ MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot ind MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals") MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_UNUSED170, 170, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 170, 0, JSEXN_RANGEERR, "repeat count must be non-negative") MSG_DEF(JSMSG_UNUSED171, 171, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED172, 172, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED173, 173, 0, JSEXN_NONE, "") @@ -286,7 +286,7 @@ MSG_DEF(JSMSG_DEPRECATED_OCTAL, 232, 0, JSEXN_SYNTAXERR, "octal literals a MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated") +MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "can't assign to {0} in strict mode") MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 238, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 239, 1, JSEXN_TYPEERR, "{0} is not extensible") @@ -313,16 +313,16 @@ MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 259, 0, JSEXN_TYPEERR, "can't change ob MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 260, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 261, 0, JSEXN_TYPEERR, "unsupported type for structured data") MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive object") -MSG_DEF(JSMSG_UNUSED263, 263, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 263, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee") MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version") MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_UNUSED266, 266, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 266, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function") MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer") MSG_DEF(JSMSG_CLEARED_SCOPE, 269, 0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope") MSG_DEF(JSMSG_MALFORMED_ESCAPE, 270, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") MSG_DEF(JSMSG_BAD_GENEXP_BODY, 271, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_UNUSED272, 272, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_YIELD_WITHOUT_OPERAND, 272, 0, JSEXN_SYNTAXERR, "yield without a value is deprecated, and illegal in ES6 (use 'yield undefined' instead)") MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 273, 0, JSEXN_SYNTAXERR, "function statement requires a name") MSG_DEF(JSMSG_CCW_REQUIRED, 274, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 275, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") @@ -391,12 +391,21 @@ MSG_DEF(JSMSG_DATE_NOT_FINITE, 337, 0, JSEXN_RANGEERR, "date value is not MSG_DEF(JSMSG_MODULE_STATEMENT, 338, 0, JSEXN_SYNTAXERR, "module declarations may only appear at the top level of a program or module body") MSG_DEF(JSMSG_CURLY_BEFORE_MODULE, 339, 0, JSEXN_SYNTAXERR, "missing { before module body") MSG_DEF(JSMSG_CURLY_AFTER_MODULE, 340, 0, JSEXN_SYNTAXERR, "missing } after module body") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "'use asm' directive only works on function code") +MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 342, 1, JSEXN_TYPEERR, "asm.js type error: {0}") MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 343, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 0, JSEXN_ERR, "successfully compiled asm.js code") +MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 1, JSEXN_ERR, "successfully compiled asm.js code ({0})") MSG_DEF(JSMSG_BAD_ARROW_ARGS, 345, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") MSG_DEF(JSMSG_YIELD_IN_ARROW, 346, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") MSG_DEF(JSMSG_WRONG_VALUE, 347, 2, JSEXN_ERR, "expected {0} but found {1}") MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, 348, 1, JSEXN_ERR, "target for index {0} is not an integer") MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME,349, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") +MSG_DEF(JSMSG_DEPRECATED_SOURCE_MAP, 350, 0, JSEXN_SYNTAXERR, "Using //@ to indicate source map URL pragmas is deprecated. Use //# instead") +MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN, 351, 1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment") +MSG_DEF(JSMSG_BINARYDATA_ARRAYTYPE_BAD_ARGS, 352, 0, JSEXN_ERR, "Invalid arguments") +MSG_DEF(JSMSG_BINARYDATA_BINARYARRAY_BAD_INDEX, 353, 0, JSEXN_RANGEERR, "invalid or out-of-range index") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_ARGS, 354, 0, JSEXN_RANGEERR, "invalid field descriptor") +MSG_DEF(JSMSG_BINARYDATA_NOT_BINARYSTRUCT, 355, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct") +MSG_DEF(JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor") diff --git a/external/spidermonkey/include/mac/js/Anchor.h b/external/spidermonkey/include/mac/js/Anchor.h index d0c2476cf7..0d458e6fb6 100644 --- a/external/spidermonkey/include/mac/js/Anchor.h +++ b/external/spidermonkey/include/mac/js/Anchor.h @@ -6,8 +6,8 @@ /* JS::Anchor implementation. */ -#ifndef js_Anchor_h___ -#define js_Anchor_h___ +#ifndef js_Anchor_h +#define js_Anchor_h #include "mozilla/Attributes.h" @@ -159,4 +159,4 @@ inline Anchor::~Anchor() } // namespace JS -#endif /* js_Anchor_h___ */ +#endif /* js_Anchor_h */ diff --git a/external/spidermonkey/include/mac/js/CallArgs.h b/external/spidermonkey/include/mac/js/CallArgs.h index af78fde0a0..8027ffc71a 100644 --- a/external/spidermonkey/include/mac/js/CallArgs.h +++ b/external/spidermonkey/include/mac/js/CallArgs.h @@ -26,11 +26,12 @@ * methods' implementations, potentially under time pressure. */ -#ifndef js_CallArgs_h___ -#define js_CallArgs_h___ +#ifndef js_CallArgs_h +#define js_CallArgs_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/TypeTraits.h" #include "jstypes.h" @@ -44,6 +45,29 @@ class JSObject; typedef JSBool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp); +/* Typedef for native functions that may be called in parallel. */ +typedef js::ParallelResult +(* JSParallelNative)(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + +/* + * Typedef for native functions that may be called either in parallel or + * sequential execution. + */ +typedef JSBool +(* JSThreadSafeNative)(js::ThreadSafeContext *cx, unsigned argc, JS::Value *vp); + +/* + * Convenience wrappers for passing in ThreadSafeNative to places that expect + * a JSNative or a JSParallelNative. + */ +template +inline JSBool +JSNativeThreadSafeWrapper(JSContext *cx, unsigned argc, JS::Value *vp); + +template +inline js::ParallelResult +JSParallelNativeThreadSafeWrapper(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + /* * Compute |this| for the |vp| inside a JSNative, either boxing primitives or * replacing with the global object as necessary. @@ -58,6 +82,8 @@ JS_ComputeThis(JSContext *cx, JS::Value *vp); namespace JS { +extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; + /* * JS::CallReceiver encapsulates access to the callee, |this|, and eventual * return value for a function call. The principal way to create a @@ -92,30 +118,55 @@ namespace JS { * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallReceiver + +namespace detail { + +#ifdef DEBUG +extern JS_PUBLIC_API(void) +CheckIsValidConstructible(Value v); +#endif + +enum UsedRval { IncludeUsedRval, NoUsedRval }; + +template +class MOZ_STACK_CLASS UsedRvalBase; + +template<> +class MOZ_STACK_CLASS UsedRvalBase { protected: -#ifdef DEBUG mutable bool usedRval_; void setUsedRval() const { usedRval_ = true; } void clearUsedRval() const { usedRval_ = false; } -#else +}; + +template<> +class MOZ_STACK_CLASS UsedRvalBase +{ + protected: void setUsedRval() const {} void clearUsedRval() const {} +}; + +template +class MOZ_STACK_CLASS CallReceiverBase : public UsedRvalBase< +#ifdef DEBUG + WantUsedRval +#else + NoUsedRval #endif - + > +{ + protected: Value *argv_; - friend CallReceiver CallReceiverFromVp(Value *vp); - friend CallReceiver CallReceiverFromArgv(Value *argv); - public: /* * Returns the function being called, as an object. Must not be called * after rval() has been used! */ JSObject &callee() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return argv_[-2].toObject(); } @@ -124,7 +175,7 @@ class MOZ_STACK_CLASS CallReceiver * rval() has been used! */ HandleValue calleev() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return HandleValue::fromMarkedLocation(&argv_[-2]); } @@ -148,6 +199,14 @@ class MOZ_STACK_CLASS CallReceiver return JS_ComputeThis(cx, base()); } + bool isConstructing() const { +#ifdef DEBUG + if (this->usedRval_) + CheckIsValidConstructible(calleev()); +#endif + return argv_[-1].isMagic(); + } + /* * Returns the currently-set return value. The initial contents of this * value are unspecified. Once this method has been called, callee() and @@ -160,7 +219,7 @@ class MOZ_STACK_CLASS CallReceiver * fails. */ MutableHandleValue rval() const { - setUsedRval(); + this->setUsedRval(); return MutableHandleValue::fromMarkedLocation(&argv_[-2]); } @@ -171,7 +230,7 @@ class MOZ_STACK_CLASS CallReceiver Value *base() const { return argv_ - 2; } Value *spAfterCall() const { - setUsedRval(); + this->setUsedRval(); return argv_ - 1; } @@ -181,7 +240,7 @@ class MOZ_STACK_CLASS CallReceiver // it. You probably don't want to use these! void setCallee(Value aCalleev) const { - clearUsedRval(); + this->clearUsedRval(); argv_[-2] = aCalleev; } @@ -194,6 +253,15 @@ class MOZ_STACK_CLASS CallReceiver } }; +} // namespace detail + +class MOZ_STACK_CLASS CallReceiver : public detail::CallReceiverBase +{ + private: + friend CallReceiver CallReceiverFromVp(Value *vp); + friend CallReceiver CallReceiverFromArgv(Value *argv); +}; + MOZ_ALWAYS_INLINE CallReceiver CallReceiverFromArgv(Value *argv) { @@ -233,11 +301,59 @@ CallReceiverFromVp(Value *vp) * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallArgs : public CallReceiver +namespace detail { + +template +class MOZ_STACK_CLASS CallArgsBase : + public mozilla::Conditional >::Type { protected: unsigned argc_; + public: + /* Returns the number of arguments. */ + unsigned length() const { return argc_; } + + /* Returns the i-th zero-indexed argument. */ + MutableHandleValue operator[](unsigned i) const { + MOZ_ASSERT(i < argc_); + return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); + } + + /* + * Returns the i-th zero-indexed argument, or |undefined| if there's no + * such argument. + */ + HandleValue get(unsigned i) const { + return i < length() + ? HandleValue::fromMarkedLocation(&this->argv_[i]) + : UndefinedHandleValue; + } + + /* + * Returns true if the i-th zero-indexed argument is present and is not + * |undefined|. + */ + bool hasDefined(unsigned i) const { + return i < argc_ && !this->argv_[i].isUndefined(); + } + + public: + // These methods are publicly exposed, but we're less sure of the interface + // here than we'd like (because they're hackish and drop assertions). Try + // to avoid using these if you can. + + Value *array() const { return this->argv_; } + Value *end() const { return this->argv_ + argc_; } +}; + +} // namespace detail + +class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase +{ + private: friend CallArgs CallArgsFromVp(unsigned argc, Value *vp); friend CallArgs CallArgsFromSp(unsigned argc, Value *sp); @@ -249,45 +365,6 @@ class MOZ_STACK_CLASS CallArgs : public CallReceiver return args; } - public: - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - Value &operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return argv_[i]; - } - - /* Returns a mutable handle for the i-th zero-indexed argument. */ - MutableHandleValue handleAt(unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - Value get(unsigned i) const { - return i < length() ? argv_[i] : UndefinedValue(); - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !argv_[i].isUndefined(); - } - - public: - // These methods are publicly exposed, but we're less sure of the interface - // here than we'd like (because they're hackish and drop assertions). Try - // to avoid using these if you can. - - Value *array() const { return argv_; } - Value *end() const { return argv_ + argc_; } }; MOZ_ALWAYS_INLINE CallArgs @@ -345,4 +422,4 @@ JS_THIS(JSContext *cx, JS::Value *vp) */ #define JS_THIS_VALUE(cx,vp) ((vp)[1]) -#endif /* js_CallArgs_h___ */ +#endif /* js_CallArgs_h */ diff --git a/external/spidermonkey/include/mac/js/CharacterEncoding.h b/external/spidermonkey/include/mac/js/CharacterEncoding.h index 63e5cc6650..e88e08e1be 100644 --- a/external/spidermonkey/include/mac/js/CharacterEncoding.h +++ b/external/spidermonkey/include/mac/js/CharacterEncoding.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_CharacterEncoding_h___ -#define js_CharacterEncoding_h___ +#ifndef js_CharacterEncoding_h +#define js_CharacterEncoding_h #include "mozilla/Range.h" @@ -58,6 +58,20 @@ class Latin1CharsZ : public mozilla::RangedPtr char *c_str() { return reinterpret_cast(get()); } }; +class UTF8Chars : public mozilla::Range +{ + typedef mozilla::Range Base; + + public: + UTF8Chars() : Base() {} + UTF8Chars(char *aBytes, size_t aLength) + : Base(reinterpret_cast(aBytes), aLength) + {} + UTF8Chars(const char *aBytes, size_t aLength) + : Base(reinterpret_cast(const_cast(aBytes)), aLength) + {} +}; + /* * SpiderMonkey also deals directly with UTF-8 encoded text in some places. */ @@ -124,10 +138,12 @@ class TwoByteCharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: + TwoByteCharsZ() : Base(NULL, 0) {} + TwoByteCharsZ(jschar *chars, size_t length) : Base(chars, length) { - JS_ASSERT(chars[length] = '\0'); + JS_ASSERT(chars[length] == '\0'); } }; @@ -142,14 +158,34 @@ class TwoByteCharsZ : public mozilla::RangedPtr * This method cannot trigger GC. */ extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars); +LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); extern UTF8CharsZ -TwoByteCharsToNewUTF8CharsZ(JSContext *cx, TwoByteChars tbchars); +TwoByteCharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); + +uint32_t +Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length); + +/* + * Inflate bytes in UTF-8 encoding to jschars. + * - On error, returns an empty TwoByteCharsZ. + * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold + * its length; the length value excludes the trailing null. + */ +extern TwoByteCharsZ +UTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); + +/* + * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters + * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 + * input. + */ +extern TwoByteCharsZ +LossyUTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); } // namespace JS inline void JS_free(JS::Latin1CharsZ &ptr) { js_free((void*)ptr.get()); } inline void JS_free(JS::UTF8CharsZ &ptr) { js_free((void*)ptr.get()); } -#endif // js_CharacterEncoding_h___ +#endif /* js_CharacterEncoding_h */ diff --git a/external/spidermonkey/include/mac/js/Date.h b/external/spidermonkey/include/mac/js/Date.h index 7ca961e30a..6199f9eca5 100644 --- a/external/spidermonkey/include/mac/js/Date.h +++ b/external/spidermonkey/include/mac/js/Date.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_Date_h___ -#define js_Date_h___ +#ifndef js_Date_h +#define js_Date_h #include "jstypes.h" @@ -32,4 +32,4 @@ DayFromTime(double time); } // namespace JS -#endif /* js_Date_h___ */ +#endif /* js_Date_h */ diff --git a/external/spidermonkey/include/mac/js/GCAPI.h b/external/spidermonkey/include/mac/js/GCAPI.h index 1b0036116c..a9bef77c09 100644 --- a/external/spidermonkey/include/mac/js/GCAPI.h +++ b/external/spidermonkey/include/mac/js/GCAPI.h @@ -4,10 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_gc_api_h___ -#define js_gc_api_h___ +#ifndef js_GCAPI_h +#define js_GCAPI_h -#include "HeapAPI.h" +#include "js/HeapAPI.h" namespace JS { @@ -181,6 +181,9 @@ DisableIncrementalGC(JSRuntime *rt); extern JS_FRIEND_API(void) DisableGenerationalGC(JSRuntime *rt); +extern JS_FRIEND_API(void) +EnableGenerationalGC(JSRuntime *rt); + extern JS_FRIEND_API(bool) IsIncrementalBarrierNeeded(JSRuntime *rt); @@ -205,7 +208,7 @@ WasIncrementalGC(JSRuntime *rt); class ObjectPtr { - JSObject *value; + Heap value; public: ObjectPtr() : value(NULL) {} @@ -240,7 +243,7 @@ class ObjectPtr } void trace(JSTracer *trc, const char *name) { - JS_CallObjectTracer(trc, &value, name); + JS_CallHeapObjectTracer(trc, &value, name); } JSObject &operator*() const { return *value; } @@ -291,4 +294,4 @@ ExposeValueToActiveJS(const Value &v) } /* namespace JS */ -#endif /* js_gc_api_h___ */ +#endif /* js_GCAPI_h */ diff --git a/external/spidermonkey/include/mac/js/HashTable.h b/external/spidermonkey/include/mac/js/HashTable.h index 3402bfbff4..aa05b71472 100644 --- a/external/spidermonkey/include/mac/js/HashTable.h +++ b/external/spidermonkey/include/mac/js/HashTable.h @@ -4,17 +4,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_HashTable_h__ -#define js_HashTable_h__ +#ifndef js_HashTable_h +#define js_HashTable_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" #include "mozilla/PodOperations.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" #include "mozilla/Util.h" -#include "js/TemplateLib.h" #include "js/Utility.h" namespace js { @@ -68,15 +72,7 @@ class HashMap // HashMap construction is fallible (due to OOM); thus the user must call // init after constructing a HashMap and check the return value. - HashMap(AllocPolicy a = AllocPolicy()) - : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Key type must be relocatable"); - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Value type must be relocatable"); - } - + HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -142,18 +138,18 @@ class HashMap template bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } bool add(AddPtr &p, const Key &k) { Entry e(k, Value()); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } template bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.relookupOrAdd(p, k, Move(e)); + return impl.relookupOrAdd(p, k, mozilla::Move(e)); } // |all()| returns a Range containing |count()| elements. E.g.: @@ -203,10 +199,10 @@ class HashMap // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -235,7 +231,7 @@ class HashMap template bool putNew(const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.putNew(k, Move(e)); + return impl.putNew(k, mozilla::Move(e)); } // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. @@ -253,9 +249,17 @@ class HashMap remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const Key &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashMap is movable - HashMap(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashMap(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashMap is not copyable or assignable @@ -303,11 +307,7 @@ class HashSet // HashSet construction is fallible (due to OOM); thus the user must call // init after constructing a HashSet and check the return value. - HashSet(AllocPolicy a = AllocPolicy()) : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Set element type must be relocatable"); - } + HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -411,10 +411,10 @@ class HashSet // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -448,9 +448,17 @@ class HashSet remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const T &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashSet is movable - HashSet(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashSet(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashSet is not copyable or assignable @@ -532,7 +540,7 @@ struct DefaultHasher // Specialize hashing policy for pointer types. It assumes that the type is // at least word-aligned. For types with smaller size use PointerHasher. template -struct DefaultHasher : PointerHasher::result> +struct DefaultHasher : PointerHasher::value> {}; // For doubles, we can xor the two uint32s. @@ -542,18 +550,11 @@ struct DefaultHasher typedef double Lookup; static HashNumber hash(double d) { JS_STATIC_ASSERT(sizeof(HashNumber) == 4); - union { - struct { - uint32_t lo; - uint32_t hi; - } s; - double d; - } u; - u.d = d; - return u.s.lo ^ u.s.hi; + uint64_t u = mozilla::BitwiseCast(d); + return HashNumber(u ^ (u >> 32)); } static bool match(double lhs, double rhs) { - return lhs == rhs; + return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); } }; @@ -577,8 +578,8 @@ class HashMapEntry template HashMapEntry(const KeyInput &k, const ValueInput &v) : key(k), value(v) {} - HashMapEntry(MoveRef rhs) - : key(Move(rhs->key)), value(Move(rhs->value)) { } + HashMapEntry(mozilla::MoveRef rhs) + : key(mozilla::Move(rhs->key)), value(mozilla::Move(rhs->value)) { } typedef Key KeyType; typedef Value ValueType; @@ -647,8 +648,8 @@ class HashTableEntry } void swap(HashTableEntry *other) { - Swap(keyHash, other->keyHash); - Swap(mem, other->mem); + mozilla::Swap(keyHash, other->keyHash); + mozilla::Swap(mem, other->mem); } T &get() { JS_ASSERT(isLive()); return *mem.addr(); } @@ -807,10 +808,7 @@ class HashTable : private AllocPolicy // a new key at the new Lookup position. |front()| is invalid after // this operation until the next call to |popFront()|. void rekeyFront(const Lookup &l, const Key &k) { - typename HashTableEntry::NonConstT t(Move(this->cur->get())); - HashPolicy::setKey(t, const_cast(k)); - table.remove(*this->cur); - table.putNewInfallible(l, Move(t)); + table.rekey(*this->cur, l, k); rekeyed = true; this->validEntry = false; } @@ -832,13 +830,13 @@ class HashTable : private AllocPolicy }; // HashTable is movable - HashTable(MoveRef rhs) + HashTable(mozilla::MoveRef rhs) : AllocPolicy(*rhs) { mozilla::PodAssign(this, &*rhs); rhs->table = NULL; } - void operator=(MoveRef rhs) { + void operator=(mozilla::MoveRef rhs) { if (table) destroyTable(*this, table, capacity()); mozilla::PodAssign(this, &*rhs); @@ -882,7 +880,7 @@ class HashTable : private AllocPolicy # define METER(x) #endif - friend class js::ReentrancyGuard; + friend class mozilla::ReentrancyGuard; mutable mozilla::DebugOnly entered; mozilla::DebugOnly mutationCount; @@ -892,7 +890,7 @@ class HashTable : private AllocPolicy static const unsigned sMinCapacity = 1 << sMinCapacityLog2; static const unsigned sMaxInit = JS_BIT(23); static const unsigned sMaxCapacity = JS_BIT(24); - static const unsigned sHashBits = tl::BitSize::result; + static const unsigned sHashBits = mozilla::tl::BitSize::value; static const uint8_t sMinAlphaFrac = 64; // (0x100 * .25) static const uint8_t sMaxAlphaFrac = 192; // (0x100 * .75) static const uint8_t sInvMaxAlpha = 171; // (ceil(0x100 / .75) >> 1) @@ -1165,7 +1163,7 @@ class HashTable : private AllocPolicy for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) { if (src->isLive()) { HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive(hn, Move(src->get())); + findFreeEntry(hn).setLive(hn, mozilla::Move(src->get())); src->destroy(); } } @@ -1346,19 +1344,19 @@ class HashTable : private AllocPolicy return gen; } - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(table); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); } Ptr lookup(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); return Ptr(lookup(l, keyHash, 0)); } @@ -1371,7 +1369,7 @@ class HashTable : private AllocPolicy AddPtr lookupForAdd(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); Entry &entry = lookup(l, keyHash, sCollisionBit); AddPtr p(entry, keyHash); @@ -1382,7 +1380,7 @@ class HashTable : private AllocPolicy template bool add(AddPtr &p, const U &rhs) { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(mutationCount == p.mutationCount); JS_ASSERT(table); JS_ASSERT(!p.found()); @@ -1443,7 +1441,7 @@ class HashTable : private AllocPolicy { p.mutationCount = mutationCount; { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); p.entry_ = &lookup(l, p.keyHash, sCollisionBit); } return p.found() || add(p, u); @@ -1452,17 +1450,27 @@ class HashTable : private AllocPolicy void remove(Ptr p) { JS_ASSERT(table); - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(p.found()); remove(*p.entry_); checkUnderloaded(); } + void rekey(Ptr p, const Lookup &l, const Key &k) + { + JS_ASSERT(table); + mozilla::ReentrancyGuard g(*this); + JS_ASSERT(p.found()); + typename HashTableEntry::NonConstT t(mozilla::Move(*p)); + HashPolicy::setKey(t, const_cast(k)); + remove(*p.entry_); + putNewInfallible(l, mozilla::Move(t)); + } + #undef METER }; } // namespace detail } // namespace js -#endif // js_HashTable_h__ - +#endif /* js_HashTable_h */ diff --git a/external/spidermonkey/include/mac/js/HeapAPI.h b/external/spidermonkey/include/mac/js/HeapAPI.h index f0f4411ac9..4d739304bc 100644 --- a/external/spidermonkey/include/mac/js/HeapAPI.h +++ b/external/spidermonkey/include/mac/js/HeapAPI.h @@ -4,33 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_heap_api_h___ -#define js_heap_api_h___ +#ifndef js_HeapAPI_h +#define js_HeapAPI_h #include "jspubtd.h" +#include "js/Utility.h" + /* These values are private to the JS engine. */ namespace js { namespace gc { -/* - * Page size must be static to support our arena pointer optimizations, so we - * are forced to support each platform with non-4096 pages as a special case. - * Note: The freelist supports a maximum arena shift of 15. - * Note: Do not use JS_CPU_SPARC here, this header is used outside JS. - */ -#if (defined(SOLARIS) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ - (defined(__sparc) || defined(__sparcv9) || defined(__ia64)) -const size_t PageShift = 13; -const size_t ArenaShift = PageShift; -#elif defined(__powerpc64__) -const size_t PageShift = 16; const size_t ArenaShift = 12; -#else -const size_t PageShift = 12; -const size_t ArenaShift = PageShift; -#endif -const size_t PageSize = size_t(1) << PageShift; const size_t ArenaSize = size_t(1) << ArenaShift; const size_t ArenaMask = ArenaSize - 1; @@ -67,7 +52,7 @@ namespace shadow { struct ArenaHeader { - js::Zone *zone; + JS::Zone *zone; }; struct Zone @@ -153,10 +138,10 @@ IsIncrementalBarrierNeededOnGCThing(shadow::Runtime *rt, void *thing, JSGCTraceK { if (!rt->needsBarrier_) return false; - js::Zone *zone = GetGCThingZone(thing); + JS::Zone *zone = GetGCThingZone(thing); return reinterpret_cast(zone)->needsBarrier_; } } /* namespace JS */ -#endif /* js_heap_api_h___ */ +#endif /* js_HeapAPI_h */ diff --git a/external/spidermonkey/include/mac/js/LegacyIntTypes.h b/external/spidermonkey/include/mac/js/LegacyIntTypes.h index 387a68b9e9..2c8498c89e 100644 --- a/external/spidermonkey/include/mac/js/LegacyIntTypes.h +++ b/external/spidermonkey/include/mac/js/LegacyIntTypes.h @@ -17,13 +17,12 @@ * Indeed, if you use this header and third-party code defining these * types, *expect* to encounter either compile errors or link errors, * depending how these types are used and on the order of inclusion. - * It is safest to use only the JSAPI -style types, - * customizing those types using MOZ_CUSTOM_STDINT_H if necessary. + * It is safest to use only the types. */ -#ifndef PROTYPES_H -#define PROTYPES_H +#ifndef js_LegacyIntTypes_h +#define js_LegacyIntTypes_h -#include "mozilla/StandardInteger.h" +#include #include "js-config.h" @@ -57,4 +56,4 @@ typedef int16_t JSInt16; typedef int32_t JSInt32; typedef int64_t JSInt64; -#endif /* !defined(PROTYPES_H) */ +#endif /* js_LegacyIntTypes_h */ diff --git a/external/spidermonkey/include/mac/js/MemoryMetrics.h b/external/spidermonkey/include/mac/js/MemoryMetrics.h index 7e84f2ae11..ed61e1c427 100644 --- a/external/spidermonkey/include/mac/js/MemoryMetrics.h +++ b/external/spidermonkey/include/mac/js/MemoryMetrics.h @@ -10,6 +10,8 @@ // These declarations are not within jsapi.h because they are highly likely to // change in the future. Depend on them at your own risk. +#include "mozilla/MemoryReporting.h" + #include #include "jsalloc.h" @@ -91,7 +93,6 @@ struct TypeInferenceSizes // Data for tracking JIT-code memory usage. struct CodeSizes { - size_t jaeger; size_t ion; size_t asmJS; size_t baseline; @@ -136,7 +137,7 @@ struct RuntimeSizes size_t dtoa; size_t temporary; size_t regexpData; - size_t stack; + size_t interpreterStack; size_t gcMarker; size_t mathCache; size_t scriptData; @@ -153,9 +154,11 @@ struct ZoneStats gcHeapUnusedGcThings(0), gcHeapStringsNormal(0), gcHeapStringsShort(0), + gcHeapLazyScripts(0), gcHeapTypeObjects(0), gcHeapIonCodes(0), stringCharsNonHuge(0), + lazyScripts(0), typeObjects(0), typePool(0), hugeStrings() @@ -167,14 +170,16 @@ struct ZoneStats gcHeapUnusedGcThings(other.gcHeapUnusedGcThings), gcHeapStringsNormal(other.gcHeapStringsNormal), gcHeapStringsShort(other.gcHeapStringsShort), + gcHeapLazyScripts(other.gcHeapLazyScripts), gcHeapTypeObjects(other.gcHeapTypeObjects), gcHeapIonCodes(other.gcHeapIonCodes), stringCharsNonHuge(other.stringCharsNonHuge), + lazyScripts(other.lazyScripts), typeObjects(other.typeObjects), typePool(other.typePool), hugeStrings() { - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // Add other's numbers to this object's numbers. @@ -186,16 +191,18 @@ struct ZoneStats ADD(gcHeapStringsNormal); ADD(gcHeapStringsShort); + ADD(gcHeapLazyScripts); ADD(gcHeapTypeObjects); ADD(gcHeapIonCodes); ADD(stringCharsNonHuge); + ADD(lazyScripts); ADD(typeObjects); ADD(typePool); #undef ADD - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // This field can be used by embedders. @@ -207,10 +214,12 @@ struct ZoneStats size_t gcHeapStringsNormal; size_t gcHeapStringsShort; + size_t gcHeapLazyScripts; size_t gcHeapTypeObjects; size_t gcHeapIonCodes; size_t stringCharsNonHuge; + size_t lazyScripts; size_t typeObjects; size_t typePool; @@ -241,7 +250,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(0), shapesCompartmentTables(0), scriptData(0), - jaegerData(0), baselineData(0), baselineStubsFallback(0), baselineStubsOptimized(0), @@ -271,7 +279,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids), shapesCompartmentTables(other.shapesCompartmentTables), scriptData(other.scriptData), - jaegerData(other.jaegerData), baselineData(other.baselineData), baselineStubsFallback(other.baselineStubsFallback), baselineStubsOptimized(other.baselineStubsOptimized), @@ -306,7 +313,6 @@ struct CompartmentStats size_t shapesExtraTreeShapeKids; size_t shapesCompartmentTables; size_t scriptData; - size_t jaegerData; size_t baselineData; size_t baselineStubsFallback; size_t baselineStubsOptimized; @@ -339,7 +345,6 @@ struct CompartmentStats ADD(shapesExtraTreeShapeKids); ADD(shapesCompartmentTables); ADD(scriptData); - ADD(jaegerData); ADD(baselineData); ADD(baselineStubsFallback); ADD(baselineStubsOptimized); @@ -360,7 +365,7 @@ struct CompartmentStats struct RuntimeStats { - RuntimeStats(JSMallocSizeOfFun mallocSizeOf) + RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) : runtime(), gcHeapChunkTotal(0), gcHeapDecommittedArenas(0), @@ -417,7 +422,7 @@ struct RuntimeStats ZoneStats *currZoneStats; - JSMallocSizeOfFun mallocSizeOf_; + mozilla::MallocSizeOf mallocSizeOf_; virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0; virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0; @@ -454,4 +459,4 @@ PeakSizeOfTemporary(const JSRuntime *rt); } // namespace JS -#endif // js_MemoryMetrics_h +#endif /* js_MemoryMetrics_h */ diff --git a/external/spidermonkey/include/mac/js/PropertyKey.h b/external/spidermonkey/include/mac/js/PropertyKey.h index 53158c26f3..c949db13a5 100644 --- a/external/spidermonkey/include/mac/js/PropertyKey.h +++ b/external/spidermonkey/include/mac/js/PropertyKey.h @@ -6,8 +6,8 @@ /* JS::PropertyKey implementation. */ -#ifndef js_PropertyKey_h___ -#define js_PropertyKey_h___ +#ifndef js_PropertyKey_h +#define js_PropertyKey_h #include "mozilla/Attributes.h" @@ -95,4 +95,4 @@ ToPropertyKey(JSContext *cx, HandleValue v, PropertyKey *key) } // namespace JS -#endif /* js_PropertyKey_h___ */ +#endif /* js_PropertyKey_h */ diff --git a/external/spidermonkey/include/mac/js/RequiredDefines.h b/external/spidermonkey/include/mac/js/RequiredDefines.h index 2be2efbf9a..6af9ca871b 100644 --- a/external/spidermonkey/include/mac/js/RequiredDefines.h +++ b/external/spidermonkey/include/mac/js/RequiredDefines.h @@ -10,8 +10,8 @@ * or SpiderMonkey public headers may not work correctly. */ -#ifndef js_RequiredDefines_h___ -#define js_RequiredDefines_h___ +#ifndef js_RequiredDefines_h +#define js_RequiredDefines_h /* * The c99 defining the limit macros (UINT32_MAX for example), says: @@ -20,4 +20,4 @@ */ #define __STDC_LIMIT_MACROS -#endif /* js_RequiredDefines_h___ */ +#endif /* js_RequiredDefines_h */ diff --git a/external/spidermonkey/include/mac/js/RootingAPI.h b/external/spidermonkey/include/mac/js/RootingAPI.h index 3e2e0d2a7c..99295f1238 100644 --- a/external/spidermonkey/include/mac/js/RootingAPI.h +++ b/external/spidermonkey/include/mac/js/RootingAPI.h @@ -4,14 +4,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsgc_root_h__ -#define jsgc_root_h__ +#ifndef js_RootingAPI_h +#define js_RootingAPI_h #include "mozilla/GuardObjects.h" #include "mozilla/TypeTraits.h" #include "js/Utility.h" -#include "js/TemplateLib.h" #include "jspubtd.h" @@ -99,9 +98,10 @@ namespace js { class Module; +class ScriptSourceObject; template -struct RootMethods {}; +struct GCMethods {}; template class RootedBase {}; @@ -112,6 +112,9 @@ class HandleBase {}; template class MutableHandleBase {}; +template +class HeapBase {}; + /* * js::NullPtr acts like a NULL pointer in contexts that require a Handle. * @@ -130,6 +133,10 @@ struct NullPtr static void * const constNullValue; }; +namespace gc { +struct Cell; +} /* namespace gc */ + } /* namespace js */ namespace JS { @@ -161,6 +168,204 @@ struct JS_PUBLIC_API(NullPtr) static void * const constNullValue; }; +/* + * The Heap class is a C/C++ heap-stored reference to a JS GC thing. All + * members of heap classes that refer to GC thing should use Heap (or + * possibly TenuredHeap, described below). + * + * Heap wraps the complex mechanisms required to ensure GC safety for the + * contained reference into a C++ class that behaves similarly to a normal + * pointer. + * + * GC references stored on the C/C++ stack must use Rooted/Handle/MutableHandle + * instead. + * + * Requirements for type T: + * - Must be one of: Value, jsid, JSObject*, JSString*, JSScript* + */ +template +class Heap : public js::HeapBase +{ + public: + Heap() { + static_assert(sizeof(T) == sizeof(Heap), + "Heap must be binary compatible with T."); + init(js::GCMethods::initial()); + } + explicit Heap(T p) { init(p); } + explicit Heap(const Heap &p) { init(p.ptr); } + + ~Heap() { + if (js::GCMethods::needsPostBarrier(ptr)) + relocate(); + } + + bool operator==(const Heap &other) { return ptr == other.ptr; } + bool operator!=(const Heap &other) { return ptr != other.ptr; } + + bool operator==(const T &other) const { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + + operator T() const { return ptr; } + T operator->() const { return ptr; } + const T *address() const { return &ptr; } + const T &get() const { return ptr; } + + T *unsafeGet() { return &ptr; } + + Heap &operator=(T p) { + set(p); + return *this; + } + + void set(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (js::GCMethods::needsPostBarrier(newPtr)) { + ptr = newPtr; + post(); + } else if (js::GCMethods::needsPostBarrier(ptr)) { + relocate(); /* Called before overwriting ptr. */ + ptr = newPtr; + } else { + ptr = newPtr; + } + } + + private: + void init(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + ptr = newPtr; + if (js::GCMethods::needsPostBarrier(ptr)) + post(); + } + + void post() { +#ifdef JSGC_GENERATIONAL + JS_ASSERT(js::GCMethods::needsPostBarrier(ptr)); + js::GCMethods::postBarrier(&ptr); +#endif + } + + void relocate() { +#ifdef JSGC_GENERATIONAL + js::GCMethods::relocate(&ptr); +#endif + } + + T ptr; +}; + +#ifdef DEBUG +/* + * For generational GC, assert that an object is in the tenured generation as + * opposed to being in the nursery. + */ +extern JS_FRIEND_API(void) +AssertGCThingMustBeTenured(JSObject* obj); +#else +inline void +AssertGCThingMustBeTenured(JSObject *obj) {} +#endif + +/* + * The TenuredHeap class is similar to the Heap class above in that it + * encapsulates the GC concerns of an on-heap reference to a JS object. However, + * it has two important differences: + * + * 1) Pointers which are statically known to only reference "tenured" objects + * can avoid the extra overhead of SpiderMonkey's write barriers. + * + * 2) Objects in the "tenured" heap have stronger alignment restrictions than + * those in the "nursery", so it is possible to store flags in the lower + * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged + * pointer with a nice API for accessing the flag bits and adds various + * assertions to ensure that it is not mis-used. + * + * GC things are said to be "tenured" when they are located in the long-lived + * heap: e.g. they have gained tenure as an object by surviving past at least + * one GC. For performance, SpiderMonkey allocates some things which are known + * to normally be long lived directly into the tenured generation; for example, + * global objects. Additionally, SpiderMonkey does not visit individual objects + * when deleting non-tenured objects, so object with finalizers are also always + * tenured; for instance, this includes most DOM objects. + * + * The considerations to keep in mind when using a TenuredHeap vs a normal + * Heap are: + * + * - It is invalid for a TenuredHeap to refer to a non-tenured thing. + * - It is however valid for a Heap to refer to a tenured thing. + * - It is not possible to store flag bits in a Heap. + */ +template +class TenuredHeap : public js::HeapBase +{ + public: + TenuredHeap() : bits(0) { + static_assert(sizeof(T) == sizeof(TenuredHeap), + "TenuredHeap must be binary compatible with T."); + } + explicit TenuredHeap(T p) : bits(0) { setPtr(p); } + explicit TenuredHeap(const TenuredHeap &p) : bits(0) { setPtr(p.ptr); } + + bool operator==(const TenuredHeap &other) { return bits == other.bits; } + bool operator!=(const TenuredHeap &other) { return bits != other.bits; } + + void setPtr(T newPtr) { + JS_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (newPtr) + AssertGCThingMustBeTenured(newPtr); + bits = (bits & flagsMask) | reinterpret_cast(newPtr); + } + + void setFlags(uintptr_t flagsToSet) { + JS_ASSERT((flagsToSet & ~flagsMask) == 0); + bits |= flagsToSet; + } + + void unsetFlags(uintptr_t flagsToUnset) { + JS_ASSERT((flagsToUnset & ~flagsMask) == 0); + bits &= ~flagsToUnset; + } + + bool hasFlag(uintptr_t flag) const { + JS_ASSERT((flag & ~flagsMask) == 0); + return (bits & flag) != 0; + } + + T getPtr() const { return reinterpret_cast(bits & ~flagsMask); } + uintptr_t getFlags() const { return bits & flagsMask; } + + operator T() const { return getPtr(); } + T operator->() const { return getPtr(); } + + TenuredHeap &operator=(T p) { + setPtr(p); + return *this; + } + + /* + * Set the pointer to a value which will cause a crash if it is + * dereferenced. + */ + void setToCrashOnTouch() { + bits = (bits & flagsMask) | crashOnTouchPointer; + } + + bool isSetToCrashOnTouch() { + return (bits & ~flagsMask) == crashOnTouchPointer; + } + + private: + enum { + maskBits = 3, + flagsMask = (1 << maskBits) - 1, + crashOnTouchPointer = 1 << maskBits + }; + + uintptr_t bits; +}; + /* * Reference to a T that has been rooted elsewhere. This is most useful * as a parameter type, which guarantees that the T lvalue is properly @@ -170,7 +375,7 @@ struct JS_PUBLIC_API(NullPtr) * specialization, define a HandleBase specialization containing them. */ template -class MOZ_STACK_CLASS Handle : public js::HandleBase +class MOZ_NONHEAP_CLASS Handle : public js::HandleBase { friend class MutableHandle; @@ -180,20 +385,22 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase Handle(Handle handle, typename mozilla::EnableIf::value, int>::Type dummy = 0) { + static_assert(sizeof(Handle) == sizeof(T *), + "Handle must be binary compatible with T*."); ptr = reinterpret_cast(handle.address()); } /* Create a handle for a NULL pointer. */ Handle(js::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "js::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "js::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&js::NullPtr::constNullValue); } /* Create a handle for a NULL pointer. */ Handle(JS::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "JS::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "JS::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&JS::NullPtr::constNullValue); } @@ -202,11 +409,19 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase } /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. + * Take care when calling this method! * - * Create a Handle from a raw location of a T. + * This creates a Handle from the raw location of a T. + * + * It should be called only if the following conditions hold: + * + * 1) the location of the T is guaranteed to be marked (for some reason + * other than being a Rooted), e.g., if it is guaranteed to be reachable + * from an implicit root. + * + * 2) the contents of the location are immutable, or at least cannot change + * for the lifetime of the handle, as its users may not expect its value + * to change underneath them. */ static Handle fromMarkedLocation(const T *p) { Handle h; @@ -230,13 +445,17 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase typename mozilla::EnableIf::value, int>::Type dummy = 0); const T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a Handle to something that + * takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } - bool operator!=(const T &other) { return *ptr != other; } - bool operator==(const T &other) { return *ptr == other; } + bool operator!=(const T &other) const { return *ptr != other; } + bool operator==(const T &other) const { return *ptr == other; } private: Handle() {} @@ -247,13 +466,14 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase void operator=(S v) MOZ_DELETE; }; -typedef Handle HandleObject; -typedef Handle HandleModule; -typedef Handle HandleFunction; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleId; -typedef Handle HandleValue; +typedef Handle HandleObject; +typedef Handle HandleModule; +typedef Handle HandleScriptSource; +typedef Handle HandleFunction; +typedef Handle HandleScript; +typedef Handle HandleString; +typedef Handle HandleId; +typedef Handle HandleValue; /* * Similar to a handle, but the underlying storage can be changed. This is @@ -270,7 +490,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase inline MutableHandle(Rooted *root); void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -288,9 +508,13 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase } T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a MutableHandle to something that takes + * a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } private: @@ -298,8 +522,8 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase T *ptr; - template - void operator=(S v) MOZ_DELETE; + template void operator=(S v) MOZ_DELETE; + void operator=(MutableHandle other) MOZ_DELETE; }; typedef MutableHandle MutableHandleObject; @@ -309,6 +533,11 @@ typedef MutableHandle MutableHandleString; typedef MutableHandle MutableHandleId; typedef MutableHandle MutableHandleValue; +#ifdef JSGC_GENERATIONAL +JS_PUBLIC_API(void) HeapCellPostBarrier(js::gc::Cell **cellp); +JS_PUBLIC_API(void) HeapCellRelocate(js::gc::Cell **cellp); +#endif + } /* namespace JS */ namespace js { @@ -383,13 +612,28 @@ struct RootKind }; template -struct RootMethods +struct GCMethods { static T *initial() { return NULL; } static ThingRootKind kind() { return RootKind::rootKind(); } static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); } + static bool needsPostBarrier(T *v) { return v; } +#ifdef JSGC_GENERATIONAL + static void postBarrier(T **vp) { + JS::HeapCellPostBarrier(reinterpret_cast(vp)); + } + static void relocate(T **vp) { + JS::HeapCellRelocate(reinterpret_cast(vp)); + } +#endif }; +#if defined(DEBUG) +/* This helper allows us to assert that Rooted is scoped within a request. */ +extern JS_PUBLIC_API(bool) +IsInRequest(JSContext *cx); +#endif + } /* namespace js */ namespace JS { @@ -405,46 +649,63 @@ namespace JS { template class MOZ_STACK_CLASS Rooted : public js::RootedBase { - void init(JSContext *cxArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ContextFriendFields *cx = js::ContextFriendFields::get(cxArg); - commonInit(cx->thingGCRooters); -#endif - } + /* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */ + template + void init(CX *cx) { +#ifdef JSGC_TRACK_EXACT_ROOTS + js::ThingRootKind kind = js::GCMethods::kind(); + this->stack = &cx->thingGCRooters[kind]; + this->prev = *stack; + *stack = reinterpret_cast*>(this); - void init(js::PerThreadData *ptArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::PerThreadDataFriendFields *pt = js::PerThreadDataFriendFields::get(ptArg); - commonInit(pt->thingGCRooters); + JS_ASSERT(!js::GCMethods::poisoned(ptr)); #endif } public: Rooted(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - init(cx); + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); } Rooted(JSContext *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); + } + + Rooted(js::ContextFriendFields *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(cx); } - Rooted(js::PerThreadData *pt + Rooted(js::ContextFriendFields *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(cx); + } + + Rooted(js::PerThreadDataFriendFields *pt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(pt); } - Rooted(js::PerThreadData *pt, T initial + Rooted(js::PerThreadDataFriendFields *pt, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { @@ -452,18 +713,38 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase init(pt); } + Rooted(JSRuntime *rt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + + Rooted(JSRuntime *rt, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + ~Rooted() { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS JS_ASSERT(*stack == reinterpret_cast*>(this)); *stack = prev; #endif } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted *previous() { return prev; } #endif - operator T() const { return ptr; } + /* + * Important: Return a reference here so passing a Rooted to + * something that takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return ptr; } T operator->() const { return ptr; } T *address() { return &ptr; } const T *address() const { return &ptr; } @@ -471,7 +752,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!js::RootMethods::poisoned(value)); + JS_ASSERT(!js::GCMethods::poisoned(value)); ptr = value; return ptr; } @@ -481,28 +762,25 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } - - private: - void commonInit(Rooted **thingGCRooters) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ThingRootKind kind = js::RootMethods::kind(); - this->stack = &thingGCRooters[kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - - JS_ASSERT(!js::RootMethods::poisoned(ptr)); -#endif + void set(T value) { + JS_ASSERT(!js::GCMethods::poisoned(value)); + ptr = value; } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } + + private: +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted **stack, *prev; #endif #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) /* Has the rooting analysis ever scanned this Rooted's stack location? */ friend void JS::CheckStackRoots(JSContext*); +#endif + +#ifdef JSGC_ROOT_ANALYSIS bool scanned; #endif @@ -523,13 +801,14 @@ template <> class Rooted; #endif -typedef Rooted RootedObject; -typedef Rooted RootedModule; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedId; -typedef Rooted RootedValue; +typedef Rooted RootedObject; +typedef Rooted RootedModule; +typedef Rooted RootedScriptSource; +typedef Rooted RootedFunction; +typedef Rooted RootedScript; +typedef Rooted RootedString; +typedef Rooted RootedId; +typedef Rooted RootedValue; } /* namespace JS */ @@ -549,8 +828,9 @@ class SkipRoot const uint8_t *start; const uint8_t *end; - template - void init(SkipRoot **head, const T *ptr, size_t count) { + template + void init(CX *cx, const T *ptr, size_t count) { + SkipRoot **head = &cx->skipGCRooters; this->stack = head; this->prev = *stack; *stack = this; @@ -559,23 +839,6 @@ class SkipRoot } public: - template - SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(&ContextFriendFields::get(cx)->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - template - SkipRoot(js::PerThreadData *ptd, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - PerThreadDataFriendFields *ptff = PerThreadDataFriendFields::get(ptd); - init(&ptff->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~SkipRoot() { JS_ASSERT(*stack == this); *stack = prev; @@ -589,22 +852,36 @@ class SkipRoot #else /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {} + public: + +#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(ContextFriendFields::get(cx), ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } template - SkipRoot(PerThreadData *ptd, const T *ptr, size_t count = 1 + SkipRoot(ContextFriendFields *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(cx, ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } -#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + SkipRoot(PerThreadData *pt, const T *ptr, size_t count = 1 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + { + init(PerThreadDataFriendFields::get(pt), ptr, count); + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -614,15 +891,17 @@ template class FakeRooted : public RootedBase { public: - FakeRooted(JSContext *cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(RootMethods::initial()) + template + FakeRooted(CX *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } - FakeRooted(JSContext *cx, T initial - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + template + FakeRooted(CX *cx, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; @@ -636,13 +915,13 @@ class FakeRooted : public RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!RootMethods::poisoned(value)); + JS_ASSERT(!GCMethods::poisoned(value)); ptr = value; return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } private: T ptr; @@ -666,7 +945,7 @@ class FakeMutableHandle : public js::MutableHandleBase } void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -727,13 +1006,11 @@ template class MaybeRooted typedef FakeMutableHandle MutableHandleType; static inline JS::Handle toHandle(HandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::Handle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::MutableHandle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } }; @@ -761,6 +1038,8 @@ template inline MutableHandle::MutableHandle(Rooted *root) { + static_assert(sizeof(MutableHandle) == sizeof(T *), + "MutableHandle must be binary compatible with T*."); ptr = root->address(); } @@ -779,10 +1058,6 @@ inline void MaybeCheckStackRoots(JSContext *cx) #endif } -namespace gc { -struct Cell; -} /* namespace gc */ - /* Base class for automatic read-only object rooting during compilation. */ class CompilerRootNode { @@ -801,4 +1076,4 @@ class CompilerRootNode } /* namespace js */ -#endif /* jsgc_root_h___ */ +#endif /* js_RootingAPI_h */ diff --git a/external/spidermonkey/include/mac/js/TemplateLib.h b/external/spidermonkey/include/mac/js/TemplateLib.h deleted file mode 100644 index a4ff682912..0000000000 --- a/external/spidermonkey/include/mac/js/TemplateLib.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_template_lib_h__ -#define js_template_lib_h__ - -#include "jstypes.h" - -/* - * Library of reusable template meta-functions (that is, functions on types and - * compile-time values). Meta-functions are placed inside the 'tl' namespace to - * avoid conflict with non-meta functions that logically have the same name - * (e.g., js::tl::Min vs. js::Min). - */ - -namespace js { -namespace tl { - -/* Compute min/max/clamp. */ -template struct Min { - static const size_t result = i < j ? i : j; -}; -template struct Max { - static const size_t result = i > j ? i : j; -}; -template struct Clamp { - static const size_t result = i < min ? min : (i > max ? max : i); -}; - -/* Compute x^y. */ -template struct Pow { - static const size_t result = x * Pow::result; -}; -template struct Pow { - static const size_t result = 1; -}; - -/* Compute floor(log2(i)). */ -template struct FloorLog2 { - static const size_t result = 1 + FloorLog2::result; -}; -template <> struct FloorLog2<0> { /* Error */ }; -template <> struct FloorLog2<1> { static const size_t result = 0; }; - -/* Compute ceiling(log2(i)). */ -template struct CeilingLog2 { - static const size_t result = FloorLog2<2 * i - 1>::result; -}; - -/* Round up to the nearest power of 2. */ -template struct RoundUpPow2 { - static const size_t result = size_t(1) << CeilingLog2::result; -}; -template <> struct RoundUpPow2<0> { - static const size_t result = 1; -}; - -/* Compute the number of bits in the given unsigned type. */ -template struct BitSize { - static const size_t result = sizeof(T) * JS_BITS_PER_BYTE; -}; - -/* - * Produce an N-bit mask, where N <= BitSize::result. Handle the - * language-undefined edge case when N = BitSize::result. - */ -template struct NBitMask { - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |result| to assure - // its computation. - static const size_t checkPrecondition = 0 / size_t(N < BitSize::result); - static const size_t result = (size_t(1) << N) - 1 + checkPrecondition; -}; -template <> struct NBitMask::result> { - static const size_t result = size_t(-1); -}; - -/* - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template struct MulOverflowMask { - static const size_t result = - ~NBitMask::result - CeilingLog2::result>::result; -}; -template <> struct MulOverflowMask<0> { /* Error */ }; -template <> struct MulOverflowMask<1> { static const size_t result = 0; }; - -/* - * Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized - * array of T's is big enough to cause a ptrdiff_t overflow when subtracting - * a pointer to the end of the array from the beginning. - */ -template struct UnsafeRangeSizeMask { - /* - * The '2' factor means the top bit is clear, sizeof(T) converts from - * units of elements to bytes. - */ - static const size_t result = MulOverflowMask<2 * sizeof(T)>::result; -}; - -template struct If { static const T result = v1; }; -template struct If { static const T result = v2; }; - -/* - * Traits class for identifying types that are implicitly barriered. - */ -template struct IsRelocatableHeapType { static const bool result = true; }; - -} /* namespace tl */ -} /* namespace js */ - -#endif /* js_template_lib_h__ */ diff --git a/external/spidermonkey/include/mac/js/Utility.h b/external/spidermonkey/include/mac/js/Utility.h index c4ebf7ced6..9d391e5c8a 100644 --- a/external/spidermonkey/include/mac/js/Utility.h +++ b/external/spidermonkey/include/mac/js/Utility.h @@ -4,13 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_utility_h__ -#define js_utility_h__ +#ifndef js_Utility_h +#define js_Utility_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" +#include "mozilla/Move.h" #include "mozilla/Scoped.h" +#include "mozilla/TemplateLib.h" #include #include @@ -22,8 +24,6 @@ #include "jstypes.h" -#include "js/TemplateLib.h" - /* The public JS engine namespace. */ namespace JS {} @@ -41,7 +41,6 @@ namespace js {} #define JS_ASSERT(expr) MOZ_ASSERT(expr) #define JS_ASSERT_IF(cond, expr) MOZ_ASSERT_IF(cond, expr) -#define JS_NOT_REACHED(reason) MOZ_NOT_REACHED(reason) #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr) #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr) @@ -63,7 +62,7 @@ namespace js {} # define JS_DIAGNOSTICS_ASSERT(expr) ((void) 0) #endif -#define JS_STATIC_ASSERT(cond) MOZ_STATIC_ASSERT(cond, "JS_STATIC_ASSERT") +#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") #define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") extern MOZ_NORETURN JS_PUBLIC_API(void) @@ -84,10 +83,11 @@ extern JS_PUBLIC_API(void) JS_Abort(void); #else # ifdef DEBUG /* - * In order to test OOM conditions, when the shell command-line option - * |-A NUM| is passed, we fail continuously after the NUM'th allocation. + * In order to test OOM conditions, when the testing function + * oomAfterAllocations COUNT is passed, we fail continuously after the NUM'th + * allocation from now. */ -extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set from shell/js.cpp */ +extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set in builtins/TestingFunctions.cpp */ extern JS_PUBLIC_DATA(uint32_t) OOM_counter; /* data race, who cares. */ #ifdef JS_OOM_DO_BACKTRACES @@ -157,6 +157,12 @@ static JS_INLINE void* js_calloc(size_t bytes) return calloc(bytes, 1); } +static JS_INLINE void* js_calloc(size_t nmemb, size_t size) +{ + JS_OOM_POSSIBLY_FAIL(); + return calloc(nmemb, size); +} + static JS_INLINE void* js_realloc(void* p, size_t bytes) { JS_OOM_POSSIBLY_FAIL(); @@ -169,205 +175,6 @@ static JS_INLINE void js_free(void* p) } #endif/* JS_USE_CUSTOM_ALLOCATOR */ -JS_BEGIN_EXTERN_C - -/* - * Replace bit-scanning code sequences with CPU-specific instructions to - * speedup calculations of ceiling/floor log2. - * - * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129. - * - * SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856. - */ -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) - -unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); -unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward,_BitScanReverse) - -__forceinline static int -__BitScanForward32(unsigned int val) -{ - unsigned long idx; - - _BitScanForward(&idx, (unsigned long)val); - return (int)idx; -} -__forceinline static int -__BitScanReverse32(unsigned int val) -{ - unsigned long idx; - - _BitScanReverse(&idx, (unsigned long)val); - return (int)(31-idx); -} -# define js_bitscan_ctz32(val) __BitScanForward32(val) -# define js_bitscan_clz32(val) __BitScanReverse32(val) -# define JS_HAS_BUILTIN_BITSCAN32 - -#if defined(_M_AMD64) || defined(_M_X64) -unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask); -unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask); -# pragma intrinsic(_BitScanForward64,_BitScanReverse64) - -__forceinline static int -__BitScanForward64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanForward64(&idx, val); - return (int)idx; -} -__forceinline static int -__BitScanReverse64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanReverse64(&idx, val); - return (int)(63-idx); -} -# define js_bitscan_ctz64(val) __BitScanForward64(val) -# define js_bitscan_clz64(val) __BitScanReverse64(val) -# define JS_HAS_BUILTIN_BITSCAN64 -#endif -#elif MOZ_IS_GCC - -#if MOZ_GCC_VERSION_AT_LEAST(3, 4, 0) -# define USE_BUILTIN_CTZ -#endif - -#elif defined(__clang__) - -#if __has_builtin(__builtin_ctz) -# define USE_BUILTIN_CTZ -#endif - -#endif - -#if defined(USE_BUILTIN_CTZ) -# define js_bitscan_ctz32(val) __builtin_ctz(val) -# define js_bitscan_clz32(val) __builtin_clz(val) -# define JS_HAS_BUILTIN_BITSCAN32 -# if (JS_BYTES_PER_WORD == 8) -# define js_bitscan_ctz64(val) __builtin_ctzll(val) -# define js_bitscan_clz64(val) __builtin_clzll(val) -# define JS_HAS_BUILTIN_BITSCAN64 -# endif - -# undef USE_BUILTIN_CTZ - -#endif - -/* -** Macro version of JS_CeilingLog2: Compute the log of the least power of -** 2 greater than or equal to _n. The result is returned in _log2. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)). - * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is - * undefined. - */ -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - unsigned int j_ = (unsigned int)(_n); \ - (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \ - JS_END_MACRO -#else -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) & ((j_)-1)) \ - (_log2) += 1; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -/* -** Macro version of JS_FloorLog2: Compute the log of the greatest power of -** 2 less than or equal to _n. The result is returned in _log2. -** -** This is equivalent to finding the highest set bit in the word. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)). - * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1 - * to ensure 0 result when _n == 0. - */ -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \ - JS_END_MACRO -#else -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -#if JS_BYTES_PER_WORD == 4 -# ifdef JS_HAS_BUILTIN_BITSCAN32 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#elif JS_BYTES_PER_WORD == 8 -# ifdef JS_HAS_BUILTIN_BITSCAN64 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#else -# error "NOT SUPPORTED" -#endif - -JS_END_EXTERN_C - -/* - * Internal function. - * Compute the log of the least power of 2 greater than or equal to n. This is - * a version of JS_CeilingLog2 that operates on unsigned integers with - * CPU-dependant size. - */ -#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) - -/* - * Internal function. - * Compute the log of the greatest power of 2 less than or equal to n. - * This is a version of JS_FloorLog2 that operates on unsigned integers with - * CPU-dependant size and requires that n != 0. - */ -static MOZ_ALWAYS_INLINE size_t -JS_FLOOR_LOG2W(size_t n) -{ - JS_ASSERT(n != 0); - return js_FloorLog2wImpl(n); -} - /* * JS_ROTATE_LEFT32 * @@ -552,7 +359,7 @@ template static JS_ALWAYS_INLINE T * js_pod_malloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_malloc(numElems * sizeof(T)); } @@ -561,7 +368,7 @@ template static JS_ALWAYS_INLINE T * js_pod_calloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_calloc(numElems * sizeof(T)); } @@ -595,175 +402,6 @@ SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) namespace js { -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables also need to - * be resized. - * - * The details of the optimization, and whether it's worth applying, vary from - * one type to the next. And while some constructor calls are moves, many really - * are copies, and can't be optimized this way. So we need: - * - * 1) a way for a particular invocation of a copy constructor to say that it's - * really a move, and that the value of the original isn't important - * afterwards (althought it must still be safe to destroy); and - * - * 2) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation. - * - * The Move(T &) function takes a reference to a T, and returns an MoveRef - * referring to the same value; that's 1). An MoveRef is simply a reference - * to a T, annotated to say that a copy constructor applied to it may move that - * T, instead of copying it. Finally, a constructor that accepts an MoveRef - * should perform a more efficient move, instead of a copy, providing 2). - * - * So, where we might define a copy constructor for a class C like this: - * - * C(const C &rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(MoveRef rhs) { ... move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)) - * - * Note that MoveRef implicitly converts to T &, so you can pass an - * MoveRef to an ordinary copy constructor for a type that doesn't support a - * special move constructor, and you'll just get a copy. This means that - * templates can use Move whenever they know they won't use the original value - * any more, even if they're not sure whether the type at hand has a specialized - * move constructor. If it doesn't, the MoveRef will just convert to a T &, - * and the ordinary copy constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator, - * which runs this's destructor, and then applies the move constructor to - * *this's memory. A typical definition: - * - * C &operator=(MoveRef rhs) { - * this->~C(); - * new(this) C(rhs); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * This header file defines MoveRef and Move in the js namespace. It's up to - * individual containers to annotate moves as such, by calling Move; and it's up - * to individual types to define move constructors. - * - * One hint: if you're writing a move constructor where the type has members - * that should be moved themselves, it's much nicer to write this: - * - * C(MoveRef c) : x(c->x), y(c->y) { } - * - * than the equivalent: - * - * C(MoveRef c) { new(&x) X(c->x); new(&y) Y(c->y); } - * - * especially since GNU C++ fails to notice that this does indeed initialize x - * and y, which may matter if they're const. - */ -template -class MoveRef { - public: - typedef T Referent; - explicit MoveRef(T &t) : pointer(&t) { } - T &operator*() const { return *pointer; } - T *operator->() const { return pointer; } - operator T& () const { return *pointer; } - private: - T *pointer; -}; - -template -MoveRef Move(T &t) { return MoveRef(t); } - -template -MoveRef Move(const T &t) { return MoveRef(const_cast(t)); } - -/* Useful for implementing containers that assert non-reentrancy */ -class ReentrancyGuard -{ - /* ReentrancyGuard is not copyable. */ - ReentrancyGuard(const ReentrancyGuard &); - void operator=(const ReentrancyGuard &); - -#ifdef DEBUG - bool &entered; -#endif - public: - template -#ifdef DEBUG - ReentrancyGuard(T &obj) - : entered(obj.entered) -#else - ReentrancyGuard(T &/*obj*/) -#endif - { -#ifdef DEBUG - JS_ASSERT(!entered); - entered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - entered = false; -#endif - } -}; - -template -JS_ALWAYS_INLINE static void -Swap(T &t, T &u) -{ - T tmp(Move(t)); - t = Move(u); - u = Move(tmp); -} - -/* - * Round x up to the nearest power of 2. This function assumes that the most - * significant bit of x is not set, which would lead to overflow. - */ -JS_ALWAYS_INLINE size_t -RoundUpPow2(size_t x) -{ - return size_t(1) << JS_CEILING_LOG2W(x); -} - /* Integral types for all hash functions. */ typedef uint32_t HashNumber; const unsigned HashNumberSizeBits = 32; @@ -845,11 +483,6 @@ inline bool IsPoisonedPtr(T *v) } -/* - * This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|. - */ -typedef size_t(*JSMallocSizeOfFun)(const void *p); - /* sixgill annotation defines */ #ifndef HAVE_STATIC_ANNOTATIONS # define HAVE_STATIC_ANNOTATIONS @@ -891,4 +524,4 @@ typedef size_t(*JSMallocSizeOfFun)(const void *p); # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) #endif /* HAVE_STATIC_ANNOTATIONS */ -#endif /* js_utility_h__ */ +#endif /* js_Utility_h */ diff --git a/external/spidermonkey/include/mac/js/Value.h b/external/spidermonkey/include/mac/js/Value.h index 2c7fa1a600..9b2c5dd6f9 100644 --- a/external/spidermonkey/include/mac/js/Value.h +++ b/external/spidermonkey/include/mac/js/Value.h @@ -6,8 +6,8 @@ /* JS::Value implementation. */ -#ifndef js_Value_h___ -#define js_Value_h___ +#ifndef js_Value_h +#define js_Value_h #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" @@ -53,7 +53,7 @@ namespace JS { class Value; } * nice symbolic type tags, however we can only do this when we can force the * underlying type of the enum to be the desired size. */ -#if defined(__cplusplus) && !defined(__SUNPRO_CC) && !defined(__xlC__) +#if !defined(__SUNPRO_CC) && !defined(__xlC__) #if defined(_MSC_VER) # define JS_ENUM_HEADER(id, type) enum id : type @@ -132,7 +132,7 @@ JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64_t)); #endif -#else /* defined(__cplusplus) */ +#else /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ typedef uint8_t JSValueType; #define JSVAL_TYPE_DOUBLE ((uint8_t)0x00) @@ -180,7 +180,7 @@ typedef uint64_t JSValueShiftedTag; #define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) #endif /* JS_BITS_PER_WORD */ -#endif /* defined(__cplusplus) && !defined(__SUNPRO_CC) */ +#endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT @@ -265,7 +265,7 @@ typedef union jsval_layout typedef union jsval_layout { uint64_t asBits; -#if (!defined(_WIN64) && defined(__cplusplus)) +#if !defined(_WIN64) /* MSVC does not pack these correctly :-( */ struct { uint64_t payload47 : 47; @@ -321,7 +321,6 @@ typedef union jsval_layout int32_t i32; uint32_t u32; JSWhyMagic why; - uintptr_t word; } payload; } s; double asDouble; @@ -803,22 +802,31 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) #endif /* JS_BITS_PER_WORD */ -static inline double -JS_CANONICALIZE_NAN(double d) -{ - if (MOZ_UNLIKELY(d != d)) { - jsval_layout l; - l.asBits = 0x7FF8000000000000LL; - return l.asDouble; - } - return d; -} - static inline jsval_layout JSVAL_TO_IMPL(JS::Value v); static inline JS::Value IMPL_TO_JSVAL(jsval_layout l); namespace JS { +/** + * Returns a generic quiet NaN value, with all payload bits set to zero. + * + * Among other properties, this NaN's bit pattern conforms to JS::Value's + * bit pattern restrictions. + */ +static MOZ_ALWAYS_INLINE double +GenericNaN() +{ + return mozilla::SpecificNaN(0, 0x8000000000000ULL); +} + +static inline double +CanonicalizeNaN(double d) +{ + if (MOZ_UNLIKELY(mozilla::IsNaN(d))) + return GenericNaN(); + return d; +} + /* * JS::Value is the interface for a single JavaScript Engine value. A few * general notes on JS::Value: @@ -1393,22 +1401,35 @@ SameType(const Value &lhs, const Value &rhs) /************************************************************************/ +#ifdef JSGC_GENERATIONAL +namespace JS { +JS_PUBLIC_API(void) HeapValuePostBarrier(Value *valuep); +JS_PUBLIC_API(void) HeapValueRelocate(Value *valuep); +} +#endif + namespace js { -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } }; -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } + static bool needsPostBarrier(const JS::Value &v) { return v.isMarkable(); } +#ifdef JSGC_GENERATIONAL + static void postBarrier(JS::Value *v) { JS::HeapValuePostBarrier(v); } + static void relocate(JS::Value *v) { JS::HeapValueRelocate(v); } +#endif }; +template class UnbarrieredMutableValueOperations; template class MutableValueOperations; /* @@ -1420,7 +1441,9 @@ template class MutableValueOperations; template class ValueOperations { + friend class UnbarrieredMutableValueOperations; friend class MutableValueOperations; + const JS::Value * value() const { return static_cast(this)->extract(); } public: @@ -1453,19 +1476,22 @@ class ValueOperations void *toGCThing() const { return value()->toGCThing(); } JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); } + uint32_t toPrivateUint32() const { return value()->toPrivateUint32(); } JSWhyMagic whyMagic() const { return value()->whyMagic(); } }; /* - * A class designed for CRTP use in implementing the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible extractMutable() and extract() - * methods returning the const Value* and Value* abstracted by Outer. + * A class designed for CRTP use in implementing the mutating parts of the Value + * interface in Value-like classes that don't need post barriers. Outer must be + * a class inheriting UnbarrieredMutableValueOperations with visible + * extractMutable() and extract() methods returning the const Value* and Value* + * abstracted by Outer. */ template -class MutableValueOperations : public ValueOperations +class UnbarrieredMutableValueOperations : public ValueOperations { + friend class MutableValueOperations; JS::Value * value() { return static_cast(this)->extractMutable(); } public: @@ -1473,14 +1499,66 @@ class MutableValueOperations : public ValueOperations void setUndefined() { value()->setUndefined(); } void setInt32(int32_t i) { value()->setInt32(i); } void setDouble(double d) { value()->setDouble(d); } - void setString(JSString *str) { value()->setString(str); } - void setString(const JS::Anchor &str) { value()->setString(str); } - void setObject(JSObject &obj) { value()->setObject(obj); } void setBoolean(bool b) { value()->setBoolean(b); } void setMagic(JSWhyMagic why) { value()->setMagic(why); } bool setNumber(uint32_t ui) { return value()->setNumber(ui); } bool setNumber(double d) { return value()->setNumber(d); } - void setObjectOrNull(JSObject *arg) { value()->setObjectOrNull(arg); } +}; + +/* + * A class designed for CRTP use in implementing all the mutating parts of the + * Value interface in Value-like classes. Outer must be a class inheriting + * MutableValueOperations with visible extractMutable() and extract() + * methods returning the const Value* and Value* abstracted by Outer. + */ +template +class MutableValueOperations : public UnbarrieredMutableValueOperations +{ + public: + void setString(JSString *str) { this->value()->setString(str); } + void setString(const JS::Anchor &str) { this->value()->setString(str); } + void setObject(JSObject &obj) { this->value()->setObject(obj); } + void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); } +}; + +/* + * Augment the generic Heap interface when T = Value with + * type-querying, value-extracting, and mutating operations. + */ +template <> +class HeapBase : public UnbarrieredMutableValueOperations > +{ + typedef JS::Heap Outer; + + friend class ValueOperations; + friend class UnbarrieredMutableValueOperations; + + const JS::Value * extract() const { return static_cast(this)->address(); } + JS::Value * extractMutable() { return static_cast(this)->unsafeGet(); } + + /* + * Setters that potentially change the value to a GC thing from a non-GC + * thing must call JS::Heap::set() to trigger the post barrier. + * + * Changing from a GC thing to a non-GC thing value will leave the heap + * value in the store buffer, but it will be ingored so this is not a + * problem. + */ + void setBarriered(const JS::Value &v) { + static_cast *>(this)->set(v); + } + + public: + void setString(JSString *str) { setBarriered(JS::StringValue(str)); } + void setString(const JS::Anchor &str) { setBarriered(JS::StringValue(str.get())); } + void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); } + + void setObjectOrNull(JSObject *arg) { + if (arg) + setObject(*arg); + else + setNull(); + } }; /* @@ -1508,6 +1586,7 @@ class MutableHandleBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1526,6 +1605,7 @@ class RootedBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1574,12 +1654,12 @@ inline Anchor::~Anchor() namespace detail { struct ValueAlignmentTester { char c; JS::Value v; }; -MOZ_STATIC_ASSERT(sizeof(ValueAlignmentTester) == 16, - "JS::Value must be 16-byte-aligned"); +static_assert(sizeof(ValueAlignmentTester) == 16, + "JS::Value must be 16-byte-aligned"); struct LayoutAlignmentTester { char c; jsval_layout l; }; -MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, - "jsval_layout must be 16-byte-aligned"); +static_assert(sizeof(LayoutAlignmentTester) == 16, + "jsval_layout must be 16-byte-aligned"); } // namespace detail #endif /* DEBUG */ @@ -1593,8 +1673,8 @@ MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, */ typedef JS::Value jsval; -MOZ_STATIC_ASSERT(sizeof(jsval_layout) == sizeof(JS::Value), - "jsval_layout and JS::Value must have identical layouts"); +static_assert(sizeof(jsval_layout) == sizeof(JS::Value), + "jsval_layout and JS::Value must have identical layouts"); /************************************************************************/ @@ -1762,4 +1842,4 @@ JSVAL_TO_PRIVATE(jsval v) return JSVAL_TO_PRIVATE_PTR_IMPL(JSVAL_TO_IMPL(v)); } -#endif /* js_Value_h___ */ +#endif /* js_Value_h */ diff --git a/external/spidermonkey/include/mac/js/Vector.h b/external/spidermonkey/include/mac/js/Vector.h index 5f40dd634b..b14d75c758 100644 --- a/external/spidermonkey/include/mac/js/Vector.h +++ b/external/spidermonkey/include/mac/js/Vector.h @@ -4,14 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsvector_h_ -#define jsvector_h_ +#ifndef js_Vector_h +#define js_Vector_h -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "TemplateLib.h" -#include "Utility.h" +#include "mozilla/Vector.h" /* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ #ifdef _MSC_VER @@ -23,1085 +19,48 @@ namespace js { class TempAllocPolicy; -template +// using Vector = mozilla::Vector; +// +// ...and get rid of all the CRTP madness in mozilla::Vector(Base). But we +// can't because compiler support's not up to snuff. (Template aliases are in +// gcc 4.7 and clang 3.0 and are expected to be in MSVC 2013.) Instead, have a +// completely separate class inheriting from mozilla::Vector, and throw CRTP at +// the problem til things work. +// +// This workaround presents a couple issues. First, because js::Vector is a +// distinct type from mozilla::Vector, overload resolution, method calls, etc. +// are affected. *Hopefully* this won't be too bad in practice. (A bunch of +// places had to be fixed when mozilla::Vector was introduced, but it wasn't a +// crazy number.) Second, mozilla::Vector's interface has to be made subclass- +// ready via CRTP -- or rather, via mozilla::VectorBase, which basically no one +// should use. :-) Third, we have to redefine the constructors and the non- +// inherited operators. Blech. Happily there aren't too many of these, so it +// isn't the end of the world. + +template -class Vector; - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that cap*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring - * this. - */ -template -static bool CapacityHasExcessSpace(size_t cap) +class Vector + : public mozilla::VectorBase > { - size_t size = cap * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* Destroys constructed objects in the range [begin, end). */ - static inline void destroy(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - p->~T(); - } - - /* Constructs objects in the uninitialized range [begin, end). */ - static inline void initialize(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - /* - * Copy-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(*p); - } - - /* - * Move-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(Move(*p)); - } - - /* - * Copy-constructs objects in the uninitialized range [dst, dst+n) from the - * same object u. - */ - template - static inline void copyConstructN(T *dst, size_t n, const U &u) { - for (T *end = dst + n; dst != end; ++dst) - new(dst) T(u); - } - - /* - * Grows the given buffer to have capacity newCap, preserving the objects - * constructed in the range [begin, end) and updating v. Assumes that (1) - * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will - * not overflow. - */ - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); - if (!newbuf) - return false; - for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src) - new(dst) T(Move(*src)); - VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); - v.free_(v.mBegin); - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - static inline void destroy(T *, T *) {} - - static inline void initialize(T *begin, T *end) { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(begin, 0, sizeof(T) * (end-begin)); - */ - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); - */ - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - *dst = *p; - } - - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - copyConstruct(dst, srcbeg, srcend); - } - - static inline void copyConstructN(T *dst, size_t n, const T &t) { - for (T *p = dst, *end = dst + n; p != end; ++p) - *p = t; - } - - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - size_t oldSize = sizeof(T) * v.mCapacity; - size_t newSize = sizeof(T) * newCap; - T *newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); - if (!newbuf) - return false; - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * JS-friendly, STL-like container providing a short-lived, dynamic buffer. - * Vector calls the constructors/destructors of all elements stored in - * its internal buffer, so non-PODs may be safely used. Additionally, - * Vector will store the first N elements in-place before resorting to - * dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * N requirements: - * - any value, however, N is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in jsalloc.h (default js::TempAllocPolicy) - * - * N.B: Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object. - */ -template -class Vector : private AllocPolicy -{ - // typedef typename tl::StaticAssert::result>::result _; - - /* utilities */ - - static const bool sElemIsPod = mozilla::IsPod::value; - typedef VectorImpl Impl; - friend struct VectorImpl; - - bool growStorageBy(size_t incr); - bool convertToHeapStorage(size_t newCap); - - template inline bool growByImpl(size_t inc); - - /* magic constants */ - - static const int sMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are - * 0 inline elements. This allows us to compile when the definition - * of the element type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so - * in order to keep everything here, we use a dummy template - * parameter with partial specialization. - */ - template - struct ElemSize { - static const size_t result = sizeof(T); - }; - template - struct ElemSize<0, Dummy> { - static const size_t result = 1; - }; - - static const size_t sInlineCapacity = - tl::Min::result>::result; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t sInlineBytes = - tl::Max<1, sInlineCapacity * ElemSize::result>::result; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T *mBegin; - size_t mLength; /* Number of elements in the Vector. */ - size_t mCapacity; /* Max number of elements storable in the Vector without resizing. */ -#ifdef DEBUG - size_t mReserved; /* Max elements of reserved or used space in this vector. */ -#endif - - mozilla::AlignedStorage storage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool entered; -#endif - - Vector(const Vector &) MOZ_DELETE; - Vector &operator=(const Vector &) MOZ_DELETE; - - /* private accessors */ - - bool usingInlineStorage() const { - return mBegin == inlineStorage(); - } - - T *inlineStorage() const { - return (T *)storage.addr(); - } - - T *beginNoCheck() const { - return mBegin; - } - - T *endNoCheck() { - return mBegin + mLength; - } - - const T *endNoCheck() const { - return mBegin + mLength; - } - -#ifdef DEBUG - size_t reserved() const { - JS_ASSERT(mReserved <= mCapacity); - JS_ASSERT(mLength <= mReserved); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U u); - void internalAppendN(const T &t, size_t n); - template void internalAppend(const U *begin, size_t length); - template void internalAppend(const Vector &other); + typedef typename mozilla::VectorBase Base; public: - static const size_t sMaxInlineStorage = N; - - typedef T ElementType; - - Vector(AllocPolicy = AllocPolicy()); - Vector(MoveRef); /* Move constructor. */ - Vector &operator=(MoveRef); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy &allocPolicy() const { - return *this; + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector &operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); } - - AllocPolicy &allocPolicy() { - return *this; - } - - enum { InlineLength = N }; - - size_t length() const { - return mLength; - } - - bool empty() const { - return mLength == 0; - } - - size_t capacity() const { - return mCapacity; - } - - T *begin() { - JS_ASSERT(!entered); - return mBegin; - } - - const T *begin() const { - JS_ASSERT(!entered); - return mBegin; - } - - T *end() { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - const T *end() const { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - T &operator[](size_t i) { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - const T &operator[](size_t i) const { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - T &back() { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - const T &back() const { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - class Range { - friend class Vector; - T *cur_, *end_; - Range(T *cur, T *end) : cur_(cur), end_(end) {} - public: - Range() {} - bool empty() const { return cur_ == end_; } - size_t remain() const { return end_ - cur_; } - T &front() const { return *cur_; } - void popFront() { JS_ASSERT(!empty()); ++cur_; } - T popCopyFront() { JS_ASSERT(!empty()); return *cur_++; } - }; - - Range all() { - return Range(begin(), end()); - } - - /* mutators */ - - /* Given that the Vector is empty and has no inline storage, grow to |capacity|. */ - bool initCapacity(size_t request); - - /* If reserve(length() + N) succeeds, the N next appends are guaranteed to succeed. */ - bool reserve(size_t request); - - /* - * Destroy elements in the range [end() - incr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t incr); - - /* Grow the vector by incr elements. */ - bool growBy(size_t incr); - - /* Call shrinkBy or growBy based on whether newSize > length(). */ - bool resize(size_t newLength); - - /* Leave new elements as uninitialized memory. */ - bool growByUninitialized(size_t incr); - bool resizeUninitialized(size_t newLength); - - /* Shorthand for shrinkBy(length()). */ - void clear(); - - /* Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /* If true, appending |needed| elements will not call realloc(). */ - bool canAppendWithoutRealloc(size_t needed) const; - - /* - * Potentially fallible append operations. - * - * The function templates that take an unspecified type U require a - * const T & or a MoveRef. The MoveRef variants move their - * operands into the vector, instead of copying them. If they fail, the - * operand is left unmoved. - */ - template bool append(U t); - bool appendN(const T &t, size_t n); - template bool append(const U *begin, const U *end); - template bool append(const U *begin, size_t length); - template bool append(const Vector &other); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. - */ - template void infallibleAppend(const U &u) { - internalAppend(u); - } - void infallibleAppendN(const T &t, size_t n) { - internalAppendN(t, n); - } - template void infallibleAppend(const U *aBegin, const U *aEnd) { - internalAppend(aBegin, mozilla::PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U *aBegin, size_t aLength) { - internalAppend(aBegin, aLength); - } - template void infallibleAppend(const Vector &other) { - internalAppend(other); - } - - void popBack(); - - T popCopy(); - - /* - * Transfers ownership of the internal buffer used by Vector to the caller. - * After this call, the Vector is empty. Since the returned buffer may need - * to be allocated (if the elements are currently stored in-place), the - * call can fail, returning NULL. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - T *extractRawBuffer(); - - /* - * Transfer ownership of an array of objects into the Vector. - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T *p, size_t length); - - /* - * Places |val| at position |p|, shifting existing elements from |p| - * onward one position higher. On success, |p| should not be reused - * because it will be a dangling pointer if reallocation of the vector - * storage occurred; the return value should be used instead. On failure, - * NULL is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) - * - * - */ - T *insert(T *p, const T &val); - - /* - * Removes the element |t|, which must fall in the bounds [begin, end), - * shifting existing elements from |t + 1| onward one position lower. - */ - void erase(T *t); - - /* - * Measure the size of the Vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - /* - * Like sizeOfExcludingThis, but also measures the size of the Vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - void swap(Vector &other); }; -/* This does the re-entrancy check plus several other sanity checks. */ -#define REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - JS_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ - JS_ASSERT(reserved() <= mCapacity); \ - JS_ASSERT(mLength <= reserved()); \ - JS_ASSERT(mLength <= mCapacity) +} // namespace js -/* Vector Implementation */ - -template -JS_ALWAYS_INLINE -Vector::Vector(AllocPolicy ap) - : AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0), - mCapacity(sInlineCapacity) -#ifdef DEBUG - , mReserved(sInlineCapacity), entered(false) -#endif -{} - -/* Move constructor. */ -template -JS_ALWAYS_INLINE -Vector::Vector(MoveRef rhs) - : AllocPolicy(rhs) -#ifdef DEBUG - , entered(false) -#endif -{ - mLength = rhs->mLength; - mCapacity = rhs->mCapacity; -#ifdef DEBUG - mReserved = rhs->mReserved; -#endif - - if (rhs->usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = (T *)storage.addr(); - Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); - /* - * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = rhs->mBegin; - rhs->mBegin = (T *) rhs->storage.addr(); - rhs->mCapacity = sInlineCapacity; - rhs->mLength = 0; -#ifdef DEBUG - rhs->mReserved = sInlineCapacity; -#endif - } -} - -/* Move assignment. */ -template -JS_ALWAYS_INLINE -Vector & -Vector::operator=(MoveRef rhs) -{ - this->~Vector(); - new(this) Vector(rhs); - return *this; -} - -template -JS_ALWAYS_INLINE -Vector::~Vector() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); -} - -/* - * This function will create a new heap buffer with capacity newCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t newCap) -{ - JS_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); - if (!newBuf) - return false; - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = newCap; - return true; -} - -template -JS_NEVER_INLINE bool -Vector::growStorageBy(size_t incr) -{ - JS_ASSERT(mLength + incr > mCapacity); - JS_ASSERT_IF(!usingInlineStorage(), !CapacityHasExcessSpace(mCapacity)); - - /* - * When choosing a new capacity, its size should is as close to 2^N bytes - * as possible. 2^N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2^N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2^N request size. - */ - - size_t newCap; - - if (incr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::result; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength*4*sizeof(T) overflow? This condition limits a Vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. - * It also ensures that the ((char *)end() - (char *)begin()) does not - * overflow ptrdiff_t (see Bug 510319). - */ - if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::result) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is - * already as close to 2^N as sizeof(T) will allow. Just double the - * capacity, and then there might be space for one more element. - */ - newCap = mLength * 2; - if (CapacityHasExcessSpace(newCap)) - newCap += 1; - - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + incr; - - /* Did mLength+incr overflow? Will newCap*sizeof(T) overflow? */ - if (newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { - convert: - return convertToHeapStorage(newCap); - } - - grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t request) -{ - JS_ASSERT(empty()); - JS_ASSERT(usingInlineStorage()); - if (request == 0) - return true; - T *newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); - if (!newbuf) - return false; - mBegin = newbuf; - mCapacity = request; -#ifdef DEBUG - mReserved = request; -#endif - return true; -} - -template -inline bool -Vector::reserve(size_t request) -{ - REENTRANCY_GUARD_ET_AL; - if (request > mCapacity && !growStorageBy(request - mLength)) - return false; - -#ifdef DEBUG - if (request > mReserved) - mReserved = request; - JS_ASSERT(mLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(incr <= mLength); - Impl::destroy(endNoCheck() - incr, endNoCheck()); - mLength -= incr; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::growByImpl(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - if (incr > mCapacity - mLength && !growStorageBy(incr)) - return false; - - JS_ASSERT(mLength + incr <= mCapacity); - T *newend = endNoCheck() + incr; - if (InitNewElems) - Impl::initialize(endNoCheck(), newend); - mLength += incr; -#ifdef DEBUG - if (mLength > mReserved) - mReserved = mLength; -#endif - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::growBy(size_t incr) -{ - return growByImpl(incr); -} - -template -JS_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t incr) -{ - return growByImpl(incr); -} - -template -STATIC_POSTCONDITION(!return || ubound(this->begin()) >= newLength) -inline bool -Vector::resize(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growBy(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growByUninitialized(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -inline void -Vector::clear() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) - return; - - this->free_(beginNoCheck()); - mBegin = (T *)storage.addr(); - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t needed) const -{ - return mLength + needed <= mCapacity; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(U t) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity && !growStorageBy(1)) - return false; - -#ifdef DEBUG - if (mLength + 1 > mReserved) - mReserved = mLength + 1; -#endif - internalAppend(t); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(U u) -{ - JS_ASSERT(mLength + 1 <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - new(endNoCheck()) T(u); - ++mLength; -} - -template -JS_ALWAYS_INLINE bool -Vector::appendN(const T &t, size_t needed) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppendN(t, needed); - return true; -} - -template -JS_ALWAYS_INLINE void -Vector::internalAppendN(const T &t, size_t needed) -{ - JS_ASSERT(mLength + needed <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), needed, t); - mLength += needed; -} - -template -inline T * -Vector::insert(T *p, const T &val) -{ - JS_ASSERT(begin() <= p && p <= end()); - size_t pos = p - begin(); - JS_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(val)) - return NULL; - } else { - T oldBack = back(); - if (!append(oldBack)) /* Dup the last element. */ - return NULL; - for (size_t i = oldLength; i > pos; --i) - (*this)[i] = (*this)[i - 1]; - (*this)[pos] = val; - } - return begin() + pos; -} - -template -inline void -Vector::erase(T *it) -{ - JS_ASSERT(begin() <= it && it < end()); - while (it + 1 != end()) { - *it = *(it + 1); - ++it; - } - popBack(); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, const U *insEnd) -{ - REENTRANCY_GUARD_ET_AL; - size_t needed = mozilla::PointerRangeSize(insBegin, insEnd); - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppend(insBegin, needed); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(const U *insBegin, size_t insLength) -{ - JS_ASSERT(mLength + insLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); - mLength += insLength; -} - -template -template -inline bool -Vector::append(const Vector &other) -{ - return append(other.begin(), other.end()); -} - -template -template -inline void -Vector::internalAppend(const Vector &other) -{ - internalAppend(other.begin(), other.length()); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, size_t insLength) -{ - return this->append(insBegin, insBegin + insLength); -} - -template -JS_ALWAYS_INLINE void -Vector::popBack() -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -JS_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T * -Vector::extractRawBuffer() -{ - T *ret; - if (usingInlineStorage()) { - ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); - if (!ret) - return NULL; - Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - /* mBegin, mCapacity are unchanged. */ - mLength = 0; - } else { - ret = mBegin; - mBegin = (T *)storage.addr(); - mLength = 0; - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif - } - return ret; -} - -template -inline void -Vector::replaceRawBuffer(T *p, size_t aLength) -{ - REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); - - /* Take in the new buffer. */ - if (aLength <= sInlineCapacity) { - /* - * We convert to inline storage if possible, even though p might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = (T *)storage.addr(); - mLength = aLength; - mCapacity = sInlineCapacity; - Impl::moveConstruct(mBegin, p, p + aLength); - Impl::destroy(p, p + aLength); - this->free_(p); - } else { - mBegin = p; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); -} - -template -inline void -Vector::swap(Vector &other) -{ - // TODO Implement N != 0 - JS_STATIC_ASSERT(N == 0); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && other.usingInlineStorage()) { - other.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !other.usingInlineStorage()) { - mBegin = other.mBegin; - other.mBegin = other.inlineStorage(); - } else if (!usingInlineStorage() && !other.usingInlineStorage()) { - Swap(mBegin, other.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, other.mLength); - Swap(mCapacity, other.mCapacity); -#ifdef DEBUG - Swap(mReserved, other.mReserved); -#endif -} - -} /* namespace js */ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* jsvector_h_ */ +#endif /* js_Vector_h */ diff --git a/external/spidermonkey/include/mac/jsalloc.h b/external/spidermonkey/include/mac/jsalloc.h index e7e64fc540..3abc4966d1 100644 --- a/external/spidermonkey/include/mac/jsalloc.h +++ b/external/spidermonkey/include/mac/jsalloc.h @@ -4,32 +4,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsalloc_h_ -#define jsalloc_h_ +/* JS allocation policies. */ + +#ifndef jsalloc_h +#define jsalloc_h + +#include "mozilla/AllocPolicy.h" #include "js/Utility.h" -#include "jstypes.h" struct JSContext; namespace js { -/* - * Allocation policies. These model the concept: - * - public copy constructor, assignment, destructor - * - void *malloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *calloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *realloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * The *used* bytes of the previous buffer is passed in - * (rather than the old allocation size), in addition to - * the *new* allocation size requested. - * - void free_(void *) - * - reportAllocOverflow() - * Called on overflow before the container returns NULL. - */ +class ContextFriendFields; /* Policy for using system memory functions and doing no error reporting. */ class SystemAllocPolicy @@ -53,7 +41,7 @@ class SystemAllocPolicy */ class TempAllocPolicy { - JSContext *const cx_; + ContextFriendFields *const cx_; /* * Non-inline helper to call JSRuntime::onOutOfMemory with minimal @@ -62,11 +50,8 @@ class TempAllocPolicy JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes); public: - TempAllocPolicy(JSContext *cx) : cx_(cx) {} - - JSContext *context() const { - return cx_; - } + TempAllocPolicy(JSContext *cx) : cx_((ContextFriendFields *) cx) {} // :( + TempAllocPolicy(ContextFriendFields *cx) : cx_(cx) {} void *malloc_(size_t bytes) { void *p = js_malloc(bytes); @@ -98,4 +83,4 @@ class TempAllocPolicy } /* namespace js */ -#endif /* jsalloc_h_ */ +#endif /* jsalloc_h */ diff --git a/external/spidermonkey/include/mac/jsapi.h.REMOVED.git-id b/external/spidermonkey/include/mac/jsapi.h.REMOVED.git-id index db9dbac6b4..27b6bbed78 100644 --- a/external/spidermonkey/include/mac/jsapi.h.REMOVED.git-id +++ b/external/spidermonkey/include/mac/jsapi.h.REMOVED.git-id @@ -1 +1 @@ -0ec74a6f5f2aa9bbaa6a8cbf6e2ae95ec7c4ee43 \ No newline at end of file +e14ea931f699b1808c06886e55e977c9819f3774 \ No newline at end of file diff --git a/external/spidermonkey/include/mac/jsclass.h b/external/spidermonkey/include/mac/jsclass.h index c9b53c7679..def641715d 100644 --- a/external/spidermonkey/include/mac/jsclass.h +++ b/external/spidermonkey/include/mac/jsclass.h @@ -4,14 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclass_h__ -#define jsclass_h__ +#ifndef jsclass_h +#define jsclass_h /* * A JSClass acts as a vtable for JS objects that allows JSAPI clients to * control various aspects of the behavior of an object like property lookup. * js::Class is an engine-private extension that allows more control over * object behavior and, e.g., allows custom slow layout. */ + #include "jsapi.h" #include "jsprvtd.h" @@ -21,6 +22,10 @@ class PropertyName; class SpecialId; class PropertyId; +// This is equal to JSFunction::class_. Use it in places where you don't want +// to #include jsfun.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionClassPtr; + static JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid); @@ -195,7 +200,7 @@ typedef void const char *name; \ uint32_t flags; \ \ - /* Mandatory non-null function pointer members. */ \ + /* Mandatory function pointer members. */ \ JSPropertyOp addProperty; \ JSDeletePropertyOp delProperty; \ JSPropertyOp getProperty; \ @@ -203,9 +208,9 @@ typedef void JSEnumerateOp enumerate; \ JSResolveOp resolve; \ JSConvertOp convert; \ - FinalizeOp finalize; \ \ - /* Optionally non-null members start here. */ \ + /* Optional members (may be null). */ \ + FinalizeOp finalize; \ JSCheckAccessOp checkAccess; \ JSNative call; \ JSHasInstanceOp hasInstance; \ @@ -214,7 +219,7 @@ typedef void /* * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much - * we have to padd js::Class to match the size of JSClass; + * we have to pad js::Class to match the size of JSClass. */ struct ClassSizeMeasurement { @@ -312,8 +317,9 @@ struct Class return flags & JSCLASS_EMULATES_UNDEFINED; } - /* Defined in jsfuninlines.h */ - inline bool isCallable() const; + bool isCallable() const { + return this == js::FunctionClassPtr || call; + } static size_t offsetOfFlags() { return offsetof(Class, flags); } }; @@ -387,7 +393,7 @@ IsPoisonedSpecialId(js::SpecialId iden) return false; } -template <> struct RootMethods +template <> struct GCMethods { static SpecialId initial() { return SpecialId(); } static ThingRootKind kind() { return THING_ROOT_ID; } @@ -396,4 +402,4 @@ template <> struct RootMethods } /* namespace js */ -#endif /* jsclass_h__ */ +#endif /* jsclass_h */ diff --git a/external/spidermonkey/include/mac/jsclist.h b/external/spidermonkey/include/mac/jsclist.h index 8782307fa4..23da9b8cd5 100644 --- a/external/spidermonkey/include/mac/jsclist.h +++ b/external/spidermonkey/include/mac/jsclist.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclist_h___ -#define jsclist_h___ +#ifndef jsclist_h +#define jsclist_h #include "jstypes.h" @@ -104,4 +104,4 @@ typedef struct JSCListStr { #define JS_INIT_STATIC_CLIST(_l) \ {(_l), (_l)} -#endif /* jsclist_h___ */ +#endif /* jsclist_h */ diff --git a/external/spidermonkey/include/mac/jscpucfg.h b/external/spidermonkey/include/mac/jscpucfg.h index 6bb62b420f..c79bd7ad14 100644 --- a/external/spidermonkey/include/mac/jscpucfg.h +++ b/external/spidermonkey/include/mac/jscpucfg.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_cpucfg___ -#define js_cpucfg___ +#ifndef jscpucfg_h +#define jscpucfg_h #define JS_HAVE_LONG_LONG @@ -114,4 +114,4 @@ # endif #endif -#endif /* js_cpucfg___ */ +#endif /* jscpucfg_h */ diff --git a/external/spidermonkey/include/mac/jsdbgapi.h b/external/spidermonkey/include/mac/jsdbgapi.h index 4907d913a0..0ce7101337 100644 --- a/external/spidermonkey/include/mac/jsdbgapi.h +++ b/external/spidermonkey/include/mac/jsdbgapi.h @@ -4,12 +4,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsdbgapi_h___ -#define jsdbgapi_h___ +#ifndef jsdbgapi_h +#define jsdbgapi_h /* * JS debugger API. */ -#include "jsapi.h" + #include "jsprvtd.h" namespace JS { @@ -111,7 +111,7 @@ JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapHandler *handlerp, jsval *closurep); extern JS_PUBLIC_API(void) -JS_ClearScriptTraps(JSContext *cx, JSScript *script); +JS_ClearScriptTraps(JSRuntime *rt, JSScript *script); extern JS_PUBLIC_API(void) JS_ClearAllTrapsForCompartment(JSContext *cx); @@ -224,12 +224,6 @@ JS_GetScriptLineExtent(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(JSVersion) JS_GetScriptVersion(JSContext *cx, JSScript *script); -extern JS_PUBLIC_API(bool) -JS_GetScriptUserBit(JSScript *script); - -extern JS_PUBLIC_API(void) -JS_SetScriptUserBit(JSScript *script, bool b); - extern JS_PUBLIC_API(bool) JS_GetScriptIsSelfHosted(JSScript *script); @@ -433,9 +427,6 @@ JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); /************************************************************************/ -extern JS_FRIEND_API(void) -js_RevertVersion(JSContext *cx); - extern JS_PUBLIC_API(const JSDebugHooks *) JS_GetGlobalDebugHooks(JSRuntime *rt); @@ -465,4 +456,4 @@ JS_DumpCompartmentPCCounts(JSContext *cx); extern JS_FRIEND_API(JSBool) js_CallContextDebugHandler(JSContext *cx); -#endif /* jsdbgapi_h___ */ +#endif /* jsdbgapi_h */ diff --git a/external/spidermonkey/include/mac/jsdhash.h b/external/spidermonkey/include/mac/jsdhash.h deleted file mode 100644 index 1f7830fd2b..0000000000 --- a/external/spidermonkey/include/mac/jsdhash.h +++ /dev/null @@ -1,612 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef jsdhash_h___ -#define jsdhash_h___ - -/* - * Double hashing, a la Knuth 6. - * - * Try to keep this file in sync with xpcom/glue/pldhash.h. - */ -#include "jstypes.h" -#include "jsutil.h" - -#if defined(__GNUC__) && defined(__i386__) && !defined(XP_OS2) -#define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall)) -#elif defined(XP_WIN) -#define JS_DHASH_FASTCALL __fastcall -#else -#define JS_DHASH_FASTCALL -#endif - -#ifdef DEBUG_XXXbrendan -#define JS_DHASHMETER 1 -#endif - -/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ -#undef JS_DHASH_SIZE_LIMIT -#define JS_DHASH_SIZE_LIMIT JS_BIT(24) - -/* Minimum table size, or gross entry count (net is at most .75 loaded). */ -#ifndef JS_DHASH_MIN_SIZE -#define JS_DHASH_MIN_SIZE 16 -#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0 -#error "JS_DHASH_MIN_SIZE must be a power of two!" -#endif - -/* - * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - * expressed as a fixed-point 32-bit fraction. - */ -#define JS_DHASH_BITS 32 -#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U - -/* Primitive and forward-struct typedefs. */ -typedef uint32_t JSDHashNumber; -typedef struct JSDHashEntryHdr JSDHashEntryHdr; -typedef struct JSDHashEntryStub JSDHashEntryStub; -typedef struct JSDHashTable JSDHashTable; -typedef struct JSDHashTableOps JSDHashTableOps; - -/* - * Table entry header structure. - * - * In order to allow in-line allocation of key and value, we do not declare - * either here. Instead, the API uses const void *key as a formal parameter. - * The key need not be stored in the entry; it may be part of the value, but - * need not be stored at all. - * - * Callback types are defined below and grouped into the JSDHashTableOps - * structure, for single static initialization per hash table sub-type. - * - * Each hash table sub-type should nest the JSDHashEntryHdr structure at the - * front of its particular entry type. The keyHash member contains the result - * of multiplying the hash code returned from the hashKey callback (see below) - * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 - * and 1 values. The stored keyHash value is table size invariant, and it is - * maintained automatically by JS_DHashTableOperate -- users should never set - * it, and its only uses should be via the entry macros below. - * - * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor - * removed. An entry may be either busy or free; if busy, it may be live or - * removed. Consumers of this API should not access members of entries that - * are not live. - * - * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries - * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a - * non-live, busy (i.e., removed) entry pointer to its caller. See below for - * more details on JS_DHashTableOperate's calling rules. - */ -struct JSDHashEntryHdr { - JSDHashNumber keyHash; /* every entry must begin like this */ -}; - -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_FREE(JSDHashEntryHdr* entry) -{ - return entry->keyHash == 0; -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_BUSY(JSDHashEntryHdr* entry) -{ - return !JS_DHASH_ENTRY_IS_FREE(entry); -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_LIVE(JSDHashEntryHdr* entry) -{ - return entry->keyHash >= 2; -} - -/* - * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead) - * on most architectures, and may be allocated on the stack or within another - * structure or class (see below for the Init and Finish functions to use). - * - * To decide whether to use double hashing vs. chaining, we need to develop a - * trade-off relation, as follows: - * - * Let alpha be the load factor, esize the entry size in words, count the - * entry count, and pow2 the power-of-two table size in entries. - * - * (JSDHashTable overhead) > (JSHashTable overhead) - * (unused table entry space) > (malloc and .next overhead per entry) + - * (buckets overhead) - * (1 - alpha) * esize * pow2 > 2 * count + pow2 - * - * Notice that alpha is by definition (count / pow2): - * - * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2 - * (1 - alpha) * esize > 2 * alpha + 1 - * - * esize > (1 + 2 * alpha) / (1 - alpha) - * - * This assumes both tables must keep keyHash, key, and value for each entry, - * where key and value point to separately allocated strings or structures. - * If key and value can be combined into one pointer, then the trade-off is: - * - * esize > (1 + 3 * alpha) / (1 - alpha) - * - * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type - * that must be allocated separately and referenced by an entry.value pointer - * member, and provided key's allocation can be fused with its entry's, then - * k (the words wasted per entry with chaining) is 4. - * - * To see these curves, feed gnuplot input like so: - * - * gnuplot> f(x,k) = (1 + k * x) / (1 - x) - * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4) - * - * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4 - * words for chaining to be more space-efficient than double hashing. - * - * Solving for alpha helps us decide when to shrink an underloaded table: - * - * esize > (1 + k * alpha) / (1 - alpha) - * esize - alpha * esize > 1 + k * alpha - * esize - 1 > (k + esize) * alpha - * (esize - 1) / (k + esize) > alpha - * - * alpha < (esize - 1) / (esize + k) - * - * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k), - * assuming esize is not too large (in which case, chaining should probably be - * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3 - * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5 - * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below. - * - * The current implementation uses a configurable lower bound on alpha, which - * defaults to .25, when deciding to shrink the table (while still respecting - * JS_DHASH_MIN_SIZE). - * - * Note a qualitative difference between chaining and double hashing: under - * chaining, entry addresses are stable across table shrinks and grows. With - * double hashing, you can't safely hold an entry pointer and use it after an - * ADD or REMOVE operation, unless you sample table->generation before adding - * or removing, and compare the sample after, dereferencing the entry pointer - * only if table->generation has not changed. - * - * The moral of this story: there is no one-size-fits-all hash table scheme, - * but for small table entry size, and assuming entry address stability is not - * required, double hashing wins. - */ -struct JSDHashTable { - const JSDHashTableOps *ops; /* virtual operations, see below */ - void *data; /* ops- and instance-specific data */ - int16_t hashShift; /* multiplicative hash shift */ - uint8_t maxAlphaFrac; /* 8-bit fixed point max alpha */ - uint8_t minAlphaFrac; /* 8-bit fixed point min alpha */ - uint32_t entrySize; /* number of bytes in an entry */ - uint32_t entryCount; /* number of entries in table */ - uint32_t removedCount; /* removed entry sentinels in table */ - uint32_t generation; /* entry storage generation number */ - char *entryStore; /* entry storage */ -#ifdef JS_DHASHMETER - struct JSDHashStats { - uint32_t searches; /* total number of table searches */ - uint32_t steps; /* hash chain links traversed */ - uint32_t hits; /* searches that found key */ - uint32_t misses; /* searches that didn't find key */ - uint32_t lookups; /* number of JS_DHASH_LOOKUPs */ - uint32_t addMisses; /* adds that miss, and do work */ - uint32_t addOverRemoved; /* adds that recycled a removed entry */ - uint32_t addHits; /* adds that hit an existing entry */ - uint32_t addFailures; /* out-of-memory during add growth */ - uint32_t removeHits; /* removes that hit, and do work */ - uint32_t removeMisses; /* useless removes that miss */ - uint32_t removeFrees; /* removes that freed entry directly */ - uint32_t removeEnums; /* removes done by Enumerate */ - uint32_t grows; /* table expansions */ - uint32_t shrinks; /* table contractions */ - uint32_t compresses; /* table compressions */ - uint32_t enumShrinks; /* contractions after Enumerate */ - } stats; -#endif -}; - -/* - * Size in entries (gross, not net of free and removed sentinels) for table. - * We store hashShift rather than sizeLog2 to optimize the collision-free case - * in SearchTable. - */ -#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift) - -/* - * Table space at entryStore is allocated and freed using these callbacks. - * The allocator should return null on error only (not if called with nbytes - * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). - */ -typedef void * -(* JSDHashAllocTable)(JSDHashTable *table, uint32_t nbytes); - -typedef void -(* JSDHashFreeTable) (JSDHashTable *table, void *ptr); - -/* - * Compute the hash code for a given key to be looked up, added, or removed - * from table. A hash code may have any JSDHashNumber value. - */ -typedef JSDHashNumber -(* JSDHashHashKey) (JSDHashTable *table, const void *key); - -/* - * Compare the key identifying entry in table with the provided key parameter. - * Return JS_TRUE if keys match, JS_FALSE otherwise. - */ -typedef JSBool -(* JSDHashMatchEntry)(JSDHashTable *table, const JSDHashEntryHdr *entry, - const void *key); - -/* - * Copy the data starting at from to the new entry storage at to. Do not add - * reference counts for any strong references in the entry, however, as this - * is a "move" operation: the old entry storage at from will be freed without - * any reference-decrementing callback shortly. - */ -typedef void -(* JSDHashMoveEntry)(JSDHashTable *table, const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -/* - * Clear the entry and drop any strong references it holds. This callback is - * invoked during a JS_DHASH_REMOVE operation (see below for operation codes), - * but only if the given key is found in the table. - */ -typedef void -(* JSDHashClearEntry)(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Called when a table (whether allocated dynamically by itself, or nested in - * a larger structure, or allocated on the stack) is finished. This callback - * allows table->ops-specific code to finalize table->data. - */ -typedef void -(* JSDHashFinalize) (JSDHashTable *table); - -/* - * Initialize a new entry, apart from keyHash. This function is called when - * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the - * given key, and must add a new one. At that point, entry->keyHash is not - * set yet, to avoid claiming the last free entry in a severely overloaded - * table. - */ -typedef JSBool -(* JSDHashInitEntry)(JSDHashTable *table, JSDHashEntryHdr *entry, - const void *key); - -/* - * Finally, the "vtable" structure for JSDHashTable. The first eight hooks - * must be provided by implementations; they're called unconditionally by the - * generic jsdhash.c code. Hooks after these may be null. - * - * Summary of allocation-related hook usage with C++ placement new emphasis: - * allocTable Allocate raw bytes with malloc, no ctors run. - * freeTable Free raw bytes with free, no dtors run. - * initEntry Call placement new using default key-based ctor. - * Return JS_TRUE on success, JS_FALSE on error. - * moveEntry Call placement new using copy ctor, run dtor on old - * entry storage. - * clearEntry Run dtor on entry. - * finalize Stub unless table->data was initialized and needs to - * be finalized. - * - * Note the reason why initEntry is optional: the default hooks (stubs) clear - * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD), - * the returned entry pointer addresses an entry struct whose keyHash member - * has been set non-zero, but all other entry members are still clear (null). - * JS_DHASH_ADD callers can test such members to see whether the entry was - * newly created by the JS_DHASH_ADD call that just succeeded. If placement - * new or similar initialization is required, define an initEntry hook. Of - * course, the clearEntry hook must zero or null appropriately. - * - * XXX assumes 0 is null for pointer types. - */ -struct JSDHashTableOps { - /* Mandatory hooks. All implementations must provide these. */ - JSDHashAllocTable allocTable; - JSDHashFreeTable freeTable; - JSDHashHashKey hashKey; - JSDHashMatchEntry matchEntry; - JSDHashMoveEntry moveEntry; - JSDHashClearEntry clearEntry; - JSDHashFinalize finalize; - - /* Optional hooks start here. If null, these are not called. */ - JSDHashInitEntry initEntry; -}; - -/* - * Default implementations for the above ops. - */ -extern JS_PUBLIC_API(void *) -JS_DHashAllocTable(JSDHashTable *table, uint32_t nbytes); - -extern JS_PUBLIC_API(void) -JS_DHashFreeTable(JSDHashTable *table, void *ptr); - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashStringKey(JSDHashTable *table, const void *key); - -/* A minimal entry contains a keyHash header and a void key pointer. */ -struct JSDHashEntryStub { - JSDHashEntryHdr hdr; - const void *key; -}; - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchStringKey(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(void) -JS_DHashMoveEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -extern JS_PUBLIC_API(void) -JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFinalizeStub(JSDHashTable *table); - -/* - * If you use JSDHashEntryStub or a subclass of it as your entry struct, and - * if your entries move via memcpy and clear via memset(0), you can use these - * stub operations. - */ -extern JS_PUBLIC_API(const JSDHashTableOps *) -JS_DHashGetStubOps(void); - -/* - * Dynamically allocate a new JSDHashTable using malloc, initialize it using - * JS_DHashTableInit, and return its address. Return null on malloc failure. - * Note that the entry storage at table->entryStore will be allocated using - * the ops->allocTable callback. - */ -extern JS_PUBLIC_API(JSDHashTable *) -JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32_t entrySize, - uint32_t capacity); - -/* - * Finalize table's data, free its entry storage (via table->ops->freeTable), - * and return the memory starting at table to the malloc heap. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableDestroy(JSDHashTable *table); - -/* - * Initialize table with ops, data, entrySize, and capacity. Capacity is a - * guess for the smallest table size at which the table will usually be less - * than 75% loaded (the table will grow or shrink as needed; capacity serves - * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE). - */ -extern JS_PUBLIC_API(JSBool) -JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, - uint32_t entrySize, uint32_t capacity); - -/* - * Set maximum and minimum alpha for table. The defaults are 0.75 and .25. - * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if - * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or - * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that - * we don't shrink on the very next remove after growing a table upon adding - * an entry that brings entryCount past maxAlpha * tableSize. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableSetAlphaBounds(JSDHashTable *table, - float maxAlpha, - float minAlpha); - -/* - * Call this macro with k, the number of pointer-sized words wasted per entry - * under chaining, to compute the minimum alpha at which double hashing still - * beats chaining. - */ -#define JS_DHASH_MIN_ALPHA(table, k) \ - ((float)((table)->entrySize / sizeof(void *) - 1) \ - / ((table)->entrySize / sizeof(void *) + (k))) - -/* - * Default max/min alpha, and macros to compute the value for the |capacity| - * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any - * max alpha, such that adding entryCount entries right after initializing the - * table will not require a reallocation (so JS_DHASH_ADD can't fail for those - * JS_DHashTableOperate calls). - * - * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY. - * Don't use it directly! - */ -#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 -#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 - -#define JS_DHASH_CAP(entryCount, maxAlpha) \ - ((uint32_t)((double)(entryCount) / (maxAlpha))) - -#define JS_DHASH_CAPACITY(entryCount, maxAlpha) \ - (JS_DHASH_CAP(entryCount, maxAlpha) + \ - (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8_t)(0x100 * (maxAlpha))) \ - >> 8) < (entryCount))) - -#define JS_DHASH_DEFAULT_CAPACITY(entryCount) \ - JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) - -/* - * Finalize table's data, free its entry storage using table->ops->freeTable, - * and leave its members unchanged from their last live values (which leaves - * pointers dangling). If you want to burn cycles clearing table, it's up to - * your code to call memset. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableFinish(JSDHashTable *table); - -/* - * To consolidate keyHash computation and table grow/shrink code, we use a - * single entry point for lookup, add, and remove operations. The operation - * codes are declared here, along with codes returned by JSDHashEnumerator - * functions, which control JS_DHashTableEnumerate's behavior. - */ -typedef enum JSDHashOperator { - JS_DHASH_LOOKUP = 0, /* lookup entry */ - JS_DHASH_ADD = 1, /* add entry */ - JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */ - JS_DHASH_NEXT = 0, /* enumerator says continue */ - JS_DHASH_STOP = 1 /* enumerator says stop */ -} JSDHashOperator; - -/* - * To lookup a key in table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); - * - * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies - * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found. - * - * To add an entry identified by key to table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD); - * - * If entry is null upon return, then either the table is severely overloaded, - * and memory can't be allocated for entry storage via table->ops->allocTable; - * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may - * have returned false. - * - * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry) - * is true, and it is up to the caller to initialize the key and value parts - * of the entry sub-type, if they have not been set already (i.e. if entry was - * not already in the table, and if the optional initEntry hook was not used). - * - * To remove an entry identified by key from table, call: - * - * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); - * - * If key's entry is found, it is cleared (via table->ops->clearEntry) and - * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation - * returns null unconditionally; you should ignore its return value. - */ -extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL -JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); - -/* - * Remove an entry already accessed via LOOKUP or ADD. - * - * NB: this is a "raw" or low-level routine, intended to be used only where - * the inefficiency of a full JS_DHashTableOperate (which rehashes in order - * to find the entry given its key) is not tolerable. This function does not - * shrink the table if it is underloaded. It does not update stats #ifdef - * JS_DHASHMETER, either. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Enumerate entries in table using etor: - * - * count = JS_DHashTableEnumerate(table, etor, arg); - * - * JS_DHashTableEnumerate calls etor like so: - * - * op = etor(table, entry, number, arg); - * - * where number is a zero-based ordinal assigned to live entries according to - * their order in table->entryStore. - * - * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT, - * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via - * table->ops->clearEntry) and free entry. Then we check whether op contains - * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries - * that were enumerated so far. Return the total number of live entries when - * enumeration completes normally. - * - * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it - * must return JS_DHASH_STOP; otherwise undefined behavior results. - * - * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk - * or compressed after enumeration, but before JS_DHashTableEnumerate returns. - * Such an enumerator therefore can't safely set aside entry pointers, but an - * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries - * aside, e.g., to avoid copying live entries into an array of the entry type. - * Copying entry pointers is cheaper, and safe so long as the caller of such a - * "stable" Enumerate doesn't use the set-aside pointers after any call either - * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might - * grow or shrink entryStore. - * - * If your enumerator wants to remove certain entries, but set aside pointers - * to other entries that it retains, it can use JS_DHashTableRawRemove on the - * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if - * you want to remove entries, but for some reason you do not want entryStore - * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on - * the entry being enumerated, rather than returning JS_DHASH_REMOVE. - */ -typedef JSDHashOperator -(* JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number, void *arg); - -extern JS_PUBLIC_API(uint32_t) -JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); - -typedef size_t -(* JSDHashSizeOfEntryExcludingThisFun)(JSDHashEntryHdr *hdr, - JSMallocSizeOfFun mallocSizeOf, - void *arg); - -/** - * Measure the size of the table's entry storage, and if - * |sizeOfEntryExcludingThis| is non-NULL, measure the size of things pointed - * to by entries. Doesn't measure |ops| because it's often shared between - * tables, nor |data| because it's opaque. - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfExcludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -/** - * Like JS_DHashTableSizeOfExcludingThis, but includes sizeof(*this). - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfIncludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -#ifdef DEBUG -/** - * Mark a table as immutable for the remainder of its lifetime. This - * changes the implementation from ASSERTing one set of invariants to - * ASSERTing a different set. - * - * When a table is NOT marked as immutable, the table implementation - * asserts that the table is not mutated from its own callbacks. It - * assumes the caller protects the table from being accessed on multiple - * threads simultaneously. - * - * When the table is marked as immutable, the re-entry assertions will - * no longer trigger erroneously due to multi-threaded access. Instead, - * mutations will cause assertions. - */ -extern JS_PUBLIC_API(void) -JS_DHashMarkTableImmutable(JSDHashTable *table); -#endif - -#ifdef JS_DHASHMETER -#include - -extern JS_PUBLIC_API(void) -JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp); -#endif - -#endif /* jsdhash_h___ */ diff --git a/external/spidermonkey/include/mac/jsfriendapi.h b/external/spidermonkey/include/mac/jsfriendapi.h index 848049ffe3..a1c3024fed 100644 --- a/external/spidermonkey/include/mac/jsfriendapi.h +++ b/external/spidermonkey/include/mac/jsfriendapi.h @@ -4,15 +4,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsfriendapi_h___ -#define jsfriendapi_h___ +#ifndef jsfriendapi_h +#define jsfriendapi_h -#include "mozilla/GuardObjects.h" +#include "mozilla/MemoryReporting.h" #include "jsclass.h" -#include "jscpucfg.h" -#include "jspubtd.h" #include "jsprvtd.h" +#include "jspubtd.h" + +#include "js/CallArgs.h" /* * This macro checks if the stack pointer has exceeded a given limit. If @@ -29,6 +30,11 @@ #define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0) +namespace JS { +template +class Heap; +} /* namespace JS */ + extern JS_FRIEND_API(void) JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data); @@ -48,7 +54,7 @@ extern JS_FRIEND_API(JSObject *) JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JSHandleObject obj); +JS_ObjectCountDynamicSlots(JS::HandleObject obj); extern JS_FRIEND_API(size_t) JS_SetProtoCalled(JSContext *cx); @@ -118,14 +124,27 @@ extern JS_FRIEND_API(JSObject *) JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(JSString *) -JS_BasicObjectToString(JSContext *cx, JSHandleObject obj); +JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); extern JS_FRIEND_API(JSBool) -js_GetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp); +js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JSBool strict, + JS::MutableHandleValue vp); JS_FRIEND_API(void) js_ReportOverRecursed(JSContext *maybecx); +JS_FRIEND_API(bool) +js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); + +JS_FRIEND_API(const char *) +js_ObjectClassName(JSContext *cx, JS::HandleObject obj); + +JS_FRIEND_API(bool) +js_AddObjectRoot(JSRuntime *rt, JSObject **objp); + +JS_FRIEND_API(void) +js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp); + #ifdef DEBUG /* @@ -157,7 +176,7 @@ extern JS_FRIEND_API(JSBool) JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props); extern JS_FRIEND_API(JSBool) -JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, +JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op, js::MutableHandleValue statep, js::MutableHandleId idp); struct JSFunctionSpecWithHelp { @@ -177,25 +196,24 @@ struct JSFunctionSpecWithHelp { extern JS_FRIEND_API(bool) JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs); -typedef bool (* JS_SourceHook)(JSContext *cx, JSScript *script, jschar **src, uint32_t *length); +typedef bool (* JS_SourceHook)(JSContext *cx, JS::Handle script, + jschar **src, uint32_t *length); extern JS_FRIEND_API(void) JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook); namespace js { -extern mozilla::ThreadLocal TlsPerThreadData; - inline JSRuntime * GetRuntime(const JSContext *cx) { - return ContextFriendFields::get(cx)->runtime; + return ContextFriendFields::get(cx)->runtime_; } inline JSCompartment * GetContextCompartment(const JSContext *cx) { - return ContextFriendFields::get(cx)->compartment; + return ContextFriendFields::get(cx)->compartment_; } inline JS::Zone * @@ -217,19 +235,6 @@ typedef bool extern JS_FRIEND_API(void) DumpHeapComplete(JSRuntime *rt, FILE *fp); -class JS_FRIEND_API(AutoSwitchCompartment) { - private: - JSContext *cx; - JSCompartment *oldCompartment; - public: - AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - AutoSwitchCompartment(JSContext *cx, JSHandleObject target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoSwitchCompartment(); - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - #ifdef OLD_GETTER_SETTER_METHODS JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, unsigned argc, js::Value *vp); JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, unsigned argc, js::Value *vp); @@ -254,6 +259,15 @@ IsAtomsCompartment(JSCompartment *comp); extern JS_FRIEND_API(bool) ReportIfUndeclaredVarAssignment(JSContext *cx, HandleString propname); +/* + * Returns whether we're in a non-strict property set (in that we're in a + * non-strict script and the bytecode we're on is a property set). The return + * value does NOT indicate any sort of exception was thrown: it's just a + * boolean. + */ +extern JS_FRIEND_API(bool) +IsInNonStrictPropertySet(JSContext *cx); + struct WeakMapTracer; /* @@ -301,7 +315,7 @@ IterateGrayObjects(JS::Zone *zone, GCThingCallback cellCallback, void *data); #ifdef JS_HAS_CTYPES extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(JSMallocSizeOfFun mallocSizeOf, JSObject *obj); +SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject *obj); #endif extern JS_FRIEND_API(JSCompartment *) @@ -321,8 +335,9 @@ struct TypeObject { }; struct BaseShape { - js::Class *clasp; - JSObject *parent; + js::Class *clasp; + JSObject *parent; + JSObject *_1; JSCompartment *compartment; }; @@ -365,19 +380,22 @@ struct Function { }; struct Atom { - size_t _; + static const size_t LENGTH_SHIFT = 4; + size_t lengthAndFlags; const jschar *chars; }; } /* namespace shadow */ -extern JS_FRIEND_DATA(js::Class) CallClass; -extern JS_FRIEND_DATA(js::Class) DeclEnvClass; -extern JS_FRIEND_DATA(js::Class) FunctionClass; -extern JS_FRIEND_DATA(js::Class) FunctionProxyClass; -extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectClass; +// These are equal to |&{Function,Object,OuterWindow}ProxyObject::class_|. Use +// them in places where you don't want to #include vm/ProxyObject.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) ObjectProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr; + +// This is equal to |&JSObject::class_|. Use it in places where you don't want +// to #include jsobj.h. +extern JS_FRIEND_DATA(js::Class* const) ObjectClassPtr; inline js::Class * GetObjectClass(JSObject *obj) @@ -401,9 +419,15 @@ IsOuterObject(JSObject *obj) { return !!GetObjectClass(obj)->ext.innerObject; } +JS_FRIEND_API(bool) +IsFunctionObject(JSObject *obj); + JS_FRIEND_API(bool) IsScopeObject(JSObject *obj); +JS_FRIEND_API(bool) +IsCallObject(JSObject *obj); + inline JSObject * GetObjectParent(JSObject *obj) { @@ -423,6 +447,13 @@ GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +// For legacy consumers only. This whole concept is going away soon. +JS_FRIEND_API(JSObject *) +DefaultObjectForContextOrNull(JSContext *cx); + +JS_FRIEND_API(void) +SetDefaultObjectForContext(JSContext *cx, JSObject *obj); + JS_FRIEND_API(void) NotifyAnimationActivity(JSObject *obj); @@ -469,11 +500,11 @@ inline bool GetObjectProto(JSContext *cx, JS::Handle obj, JS::MutableHandle proto) { js::Class *clasp = GetObjectClass(obj); - if (clasp == &js::ObjectProxyClass || - clasp == &js::OuterWindowProxyClass || - clasp == &js::FunctionProxyClass) + if (clasp == js::ObjectProxyClassPtr || + clasp == js::OuterWindowProxyClassPtr || + clasp == js::FunctionProxyClassPtr) { - return JS_GetPrototype(cx, obj, proto.address()); + return JS_GetPrototype(cx, obj, proto); } proto.set(reinterpret_cast(obj.get())->type->proto); @@ -535,6 +566,13 @@ GetAtomChars(JSAtom *atom) return reinterpret_cast(atom)->chars; } +inline size_t +GetAtomLength(JSAtom *atom) +{ + using shadow::Atom; + return reinterpret_cast(atom)->lengthAndFlags >> Atom::LENGTH_SHIFT; +} + inline JSLinearString * AtomToLinearString(JSAtom *atom) { @@ -589,6 +627,12 @@ GetNativeStackLimit(const JSRuntime *rt) return PerThreadDataFriendFields::getMainThread(rt)->nativeStackLimit; } +inline uintptr_t +GetNativeStackLimit(JSContext *cx) +{ + return GetNativeStackLimit(GetRuntime(cx)); +} + /* * These macros report a stack overflow and run |onerror| if we are close to * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little @@ -598,18 +642,15 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \ js_ReportOverRecursed(cx); \ onerror; \ } \ JS_END_MACRO -#define JS_CHECK_RECURSION_WITH_EXTRA_DONT_REPORT(cx, extra, onerror) \ +#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ JS_BEGIN_MACRO \ - uint8_t stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ - &stackDummy_ - (extra))) \ - { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ onerror; \ } \ JS_END_MACRO @@ -617,7 +658,7 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_CHROME_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ + if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \ &stackDummy_, \ 1024 * sizeof(size_t))) \ { \ @@ -754,13 +795,13 @@ extern JS_FRIEND_API(bool) IsContextRunningJS(JSContext *cx); typedef void -(* AnalysisPurgeCallback)(JSRuntime *rt, JSFlatString *desc); +(* AnalysisPurgeCallback)(JSRuntime *rt, JS::Handle desc); extern JS_FRIEND_API(AnalysisPurgeCallback) SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback); typedef JSBool -(* DOMInstanceClassMatchesProto)(JSHandleObject protoObject, uint32_t protoID, +(* DOMInstanceClassMatchesProto)(JS::HandleObject protoObject, uint32_t protoID, uint32_t depth); struct JSDOMCallbacks { DOMInstanceClassMatchesProto instanceClassMatchesProto; @@ -851,10 +892,10 @@ NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& targetFilter, NukeReferencesToWindow nukeReferencesToWindow); -/* Specify information about ListBase proxies in the DOM, for use by ICs. */ +/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ /* - * The ListBaseShadowsCheck function will be called to check if the property for + * The DOMProxyShadowsCheck function will be called to check if the property for * id should be gotten from the prototype, or if there is an own property that * shadows it. * If DoesntShadow is returned then the slot at listBaseExpandoSlot should @@ -873,25 +914,31 @@ struct ExpandoAndGeneration { generation(0) {} - Value expando; + void Unlink() + { + ++generation; + expando.setUndefined(); + } + + JS::Heap expando; uint32_t generation; }; -typedef enum ListBaseShadowsResult { +typedef enum DOMProxyShadowsResult { ShadowCheckFailed, Shadows, DoesntShadow, DoesntShadowUnique -} ListBaseShadowsResult; -typedef ListBaseShadowsResult -(* ListBaseShadowsCheck)(JSContext* cx, JSHandleObject object, JSHandleId id); +} DOMProxyShadowsResult; +typedef DOMProxyShadowsResult +(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); JS_FRIEND_API(void) -SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot, - ListBaseShadowsCheck listBaseShadowsCheck); +SetDOMProxyInformation(void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, + DOMProxyShadowsCheck domProxyShadowsCheck); -void *GetListBaseHandlerFamily(); -uint32_t GetListBaseExpandoSlot(); -ListBaseShadowsCheck GetListBaseShadowsCheck(); +void *GetDOMProxyHandlerFamily(); +uint32_t GetDOMProxyExpandoSlot(); +DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); } /* namespace js */ @@ -960,6 +1007,137 @@ enum ViewType { }; } /* namespace ArrayBufferView */ + +/* + * A helper for building up an ArrayBuffer object's data + * before creating the ArrayBuffer itself. Will do doubling + * based reallocation, up to an optional maximum growth given. + * + * When all the data has been appended, call getArrayBuffer, + * passing in the JSContext* for which the ArrayBuffer object + * is to be created. This also implicitly resets the builder, + * or it can be reset explicitly at any point by calling reset(). + */ +class ArrayBufferBuilder +{ + void *rawcontents_; + uint8_t *dataptr_; + uint32_t capacity_; + uint32_t length_; + public: + ArrayBufferBuilder() + : rawcontents_(NULL), + dataptr_(NULL), + capacity_(0), + length_(0) + { + } + + ~ArrayBufferBuilder() { + reset(); + } + + void reset() { + if (rawcontents_) + JS_free(NULL, rawcontents_); + rawcontents_ = dataptr_ = NULL; + capacity_ = length_ = 0; + } + + // will truncate if newcap is < length() + bool setCapacity(uint32_t newcap) { + if (!JS_ReallocateArrayBufferContents(NULL, newcap, &rawcontents_, &dataptr_)) + return false; + + capacity_ = newcap; + if (length_ > newcap) + length_ = newcap; + + return true; + } + + // Append datalen bytes from data to the current buffer. If we + // need to grow the buffer, grow by doubling the size up to a + // maximum of maxgrowth (if given). If datalen is greater than + // what the new capacity would end up as, then grow by datalen. + // + // The data parameter must not overlap with anything beyond the + // builder's current valid contents [0..length) + bool append(const uint8_t *newdata, uint32_t datalen, uint32_t maxgrowth = 0) { + if (length_ + datalen > capacity_) { + uint32_t newcap; + // double while under maxgrowth or if not specified + if (!maxgrowth || capacity_ < maxgrowth) + newcap = capacity_ * 2; + else + newcap = capacity_ + maxgrowth; + + // but make sure there's always enough to satisfy our request + if (newcap < length_ + datalen) + newcap = length_ + datalen; + + // did we overflow? + if (newcap < capacity_) + return false; + + if (!setCapacity(newcap)) + return false; + } + + // assert that the region isn't overlapping so we can memcpy; + JS_ASSERT(!areOverlappingRegions(newdata, datalen, dataptr_ + length_, datalen)); + + memcpy(dataptr_ + length_, newdata, datalen); + length_ += datalen; + + return true; + } + + uint8_t *data() { + return dataptr_; + } + + uint32_t length() { + return length_; + } + + uint32_t capacity() { + return capacity_; + } + + JSObject* getArrayBuffer(JSContext *cx) { + // we need to check for length_ == 0, because nothing may have been + // added + if (capacity_ > length_ || length_ == 0) { + if (!setCapacity(length_)) + return NULL; + } + + JSObject* obj = JS_NewArrayBufferWithContents(cx, rawcontents_); + if (!obj) + return NULL; + + rawcontents_ = dataptr_ = NULL; + length_ = capacity_ = 0; + + return obj; + } + +protected: + + static bool areOverlappingRegions(const uint8_t *start1, uint32_t length1, + const uint8_t *start2, uint32_t length2) + { + const uint8_t *end1 = start1 + length1; + const uint8_t *end2 = start2 + length2; + + const uint8_t *max_start = start1 > start2 ? start1 : start2; + const uint8_t *min_end = end1 < end2 ? end1 : end2; + + return max_start < min_end; + } +}; + } /* namespace js */ typedef js::ArrayBufferView::ViewType JSArrayBufferViewType; @@ -1296,26 +1474,116 @@ JS_GetDataViewByteLength(JSObject *obj); JS_FRIEND_API(void *) JS_GetDataViewData(JSObject *obj); +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitGetterOp. + */ +class JSJitGetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitGetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args.rval()) + {} + + explicit JSJitGetterCallArgs(JS::Rooted* rooted) + : JS::MutableHandleValue(rooted) + {} + + JS::MutableHandleValue rval() { + return *this; + } +}; + +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitSetterOp. + */ +class JSJitSetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitSetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args[0]) + {} + + JS::MutableHandleValue operator[](unsigned i) { + MOZ_ASSERT(i == 0); + return *this; + } + + unsigned length() const { return 1; } + + // Add get() or maybe hasDefined() as needed +}; + +struct JSJitMethodCallArgsTraits; + +/* + * A class, expected to be passed by reference, which represents the CallArgs + * for a JSJitMethodOp. + */ +class JSJitMethodCallArgs : protected JS::detail::CallArgsBase +{ + private: + typedef JS::detail::CallArgsBase Base; + friend struct JSJitMethodCallArgsTraits; + + public: + explicit JSJitMethodCallArgs(const JS::CallArgs& args) { + argv_ = args.array(); + argc_ = args.length(); + } + + JS::MutableHandleValue rval() const { + return Base::rval(); + } + + unsigned length() const { return Base::length(); } + + JS::MutableHandleValue operator[](unsigned i) const { + return Base::operator[](i); + } + + bool hasDefined(unsigned i) const { + return Base::hasDefined(i); + } + + // Add get() as needed +}; + +struct JSJitMethodCallArgsTraits +{ + static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); + static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); +}; + /* * This struct contains metadata passed from the DOM to the JS Engine for JIT * optimizations on DOM property accessors. Eventually, this should be made * available to general JSAPI users, but we are not currently ready to do so. */ typedef bool -(* JSJitPropertyOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, JS::Value *vp); +(* JSJitGetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitGetterCallArgs args); typedef bool -(* JSJitMethodOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, unsigned argc, JS::Value *vp); +(* JSJitSetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitSetterCallArgs args); +typedef bool +(* JSJitMethodOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, const JSJitMethodCallArgs& args); struct JSJitInfo { enum OpType { Getter, Setter, - Method + Method, + OpType_None }; - JSJitPropertyOp op; + union { + JSJitGetterOp getter; + JSJitSetterOp setter; + JSJitMethodOp method; + }; uint32_t protoID; uint32_t depth; OpType type; @@ -1325,12 +1593,18 @@ struct JSJitInfo { keep returning the same value for the given "this" object" */ JSValueType returnType; /* The return type tag. Might be JSVAL_TYPE_UNKNOWN */ + + /* An alternative native that's safe to call in parallel mode. */ + JSParallelNative parallelNative; }; +#define JS_JITINFO_NATIVE_PARALLEL(op) \ + {{NULL},0,0,JSJitInfo::OpType_None,false,false,false,JSVAL_TYPE_MISSING,op} + static JS_ALWAYS_INLINE const JSJitInfo * FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) { - JS_ASSERT(js::GetObjectClass(&v.toObject()) == &js::FunctionClass); + JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr); return reinterpret_cast(&v.toObject())->jitinfo; } @@ -1482,9 +1756,46 @@ assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id); inline void assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id) {}; #endif +typedef bool +(* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata); + +/* + * Specify a callback to invoke when creating each JS object in the current + * compartment, which may return a metadata object to associate with the + * object. Objects with different metadata have different shape hierarchies, + * so for efficiency, objects should generally try to share metadata objects. + */ +JS_FRIEND_API(void) +SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback); + +/* Manipulate the metadata associated with an object. */ + +JS_FRIEND_API(bool) +SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata); + +JS_FRIEND_API(JSObject *) +GetObjectMetadata(JSObject *obj); + /* ES5 8.12.8. */ extern JS_FRIEND_API(JSBool) -DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); +DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValue vp); + +/* + * Helper function. To approximate a call to the [[DefineOwnProperty]] internal + * method described in ES5, first call this, then call JS_DefinePropertyById. + * + * JS_DefinePropertyById by itself does not enforce the invariants on + * non-configurable properties when obj->isNative(). This function performs the + * relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11), + * but only if obj is native. + * + * The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as + * a sort of extension point, but there is no hook in js::Class, + * js::ProxyHandler, or the JSAPI with precisely the right semantics for it. + */ +extern JS_FRIEND_API(bool) +CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, + PropertyOp getter, StrictPropertyOp setter, unsigned attrs); } /* namespace js */ @@ -1495,4 +1806,26 @@ js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, extern JS_FRIEND_API(JSBool) js_ReportIsNotFunction(JSContext *cx, const JS::Value& v); -#endif /* jsfriendapi_h___ */ +#ifdef JSGC_GENERATIONAL +extern JS_FRIEND_API(void) +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data); + +extern JS_FRIEND_API(void) +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data); +#else +inline void +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data) {} + +inline void +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data) {} +#endif /* JSGC_GENERATIONAL */ + +#endif /* jsfriendapi_h */ diff --git a/external/spidermonkey/include/mac/jslock.h b/external/spidermonkey/include/mac/jslock.h index b4a28a9fa9..522034ad68 100644 --- a/external/spidermonkey/include/mac/jslock.h +++ b/external/spidermonkey/include/mac/jslock.h @@ -4,18 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jslock_h__ -#define jslock_h__ - -#include "jsapi.h" +#ifndef jslock_h +#define jslock_h #ifdef JS_THREADSAFE +# include "jsapi.h" # include "pratom.h" -# include "prlock.h" # include "prcvar.h" -# include "prthread.h" # include "prinit.h" +# include "prlock.h" +# include "prthread.h" # define JS_ATOMIC_INCREMENT(p) PR_ATOMIC_INCREMENT((int32_t *)(p)) # define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p)) @@ -40,4 +39,4 @@ typedef struct PRLock PRLock; #endif /* JS_THREADSAFE */ -#endif /* jslock_h___ */ +#endif /* jslock_h */ diff --git a/external/spidermonkey/include/mac/json.h b/external/spidermonkey/include/mac/json.h deleted file mode 100644 index 7fa2c117c8..0000000000 --- a/external/spidermonkey/include/mac/json.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef json_h___ -#define json_h___ - -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsapi.h" - -#include "js/Vector.h" - -#define JSON_MAX_DEPTH 2048 -#define JSON_PARSER_BUFSIZE 1024 - -extern JSObject * -js_InitJSONClass(JSContext *cx, js::HandleObject obj); - -extern JSBool -js_Stringify(JSContext *cx, js::MutableHandleValue vp, - JSObject *replacer, js::Value space, - js::StringBuffer &sb); - -// Avoid build errors on certain platforms that define these names as constants -#undef STRICT -#undef LEGACY - -/* - * The type of JSON decoding to perform. Strict decoding is to-the-spec; - * legacy decoding accepts a few non-JSON syntaxes historically accepted by the - * implementation. (Full description of these deviations is deliberately - * omitted.) New users should use strict decoding rather than legacy decoding, - * as legacy decoding might be removed at a future time. - */ -enum DecodingMode { STRICT, LEGACY }; - -namespace js { - -extern JS_FRIEND_API(JSBool) -ParseJSONWithReviver(JSContext *cx, JS::StableCharPtr chars, size_t length, HandleValue filter, - MutableHandleValue vp, DecodingMode decodingMode = STRICT); - -} /* namespace js */ - -#endif /* json_h___ */ diff --git a/external/spidermonkey/include/mac/jsperf.h b/external/spidermonkey/include/mac/jsperf.h index a0287b4a57..468ce8609c 100644 --- a/external/spidermonkey/include/mac/jsperf.h +++ b/external/spidermonkey/include/mac/jsperf.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsperf_h___ -#define jsperf_h___ +#ifndef perf_jsperf_h +#define perf_jsperf_h #include "jsapi.h" @@ -127,4 +127,4 @@ extern JS_FRIEND_API(PerfMeasurement*) } // namespace JS -#endif // jsperf_h___ +#endif /* perf_jsperf_h */ diff --git a/external/spidermonkey/include/mac/jsprf.h b/external/spidermonkey/include/mac/jsprf.h index c0891f0e9e..ce159d8115 100644 --- a/external/spidermonkey/include/mac/jsprf.h +++ b/external/spidermonkey/include/mac/jsprf.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprf_h___ -#define jsprf_h___ +#ifndef jsprf_h +#define jsprf_h /* ** API for PR printf like routines. Supports the following formats @@ -24,9 +24,11 @@ ** %f - float ** %g - float */ -#include "jstypes.h" -#include + #include +#include + +#include "jstypes.h" /* ** sprintf into a fixed size buffer. Guarantees that a NUL is at the end @@ -75,4 +77,4 @@ extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); extern JS_PUBLIC_API(uint32_t) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); -#endif /* jsprf_h___ */ +#endif /* jsprf_h */ diff --git a/external/spidermonkey/include/mac/jsprototypes.h b/external/spidermonkey/include/mac/jsprototypes.h index 007d25d720..f9bacac409 100644 --- a/external/spidermonkey/include/mac/jsprototypes.h +++ b/external/spidermonkey/include/mac/jsprototypes.h @@ -6,8 +6,8 @@ /* A higher-order macro for enumerating all JSProtoKey values. */ -#ifndef jsprototypes_h___ -#define jsprototypes_h___ +#ifndef jsprototypes_h +#define jsprototypes_h #include "jsversion.h" @@ -56,5 +56,20 @@ macro(DataView, 35, js_InitTypedArrayClasses) \ macro(ParallelArray, 36, js_InitParallelArrayClass) \ macro(Intl, 37, js_InitIntlClass) \ + macro(Type, 38, js_InitBinaryDataClasses) \ + macro(Data, 39, js_InitBinaryDataClasses) \ + macro(uint8, 40, js_InitBinaryDataClasses) \ + macro(uint16, 41, js_InitBinaryDataClasses) \ + macro(uint32, 42, js_InitBinaryDataClasses) \ + macro(uint64, 43, js_InitBinaryDataClasses) \ + macro(int8, 44, js_InitBinaryDataClasses) \ + macro(int16, 45, js_InitBinaryDataClasses) \ + macro(int32, 46, js_InitBinaryDataClasses) \ + macro(int64, 47, js_InitBinaryDataClasses) \ + macro(float32, 48, js_InitBinaryDataClasses) \ + macro(float64, 49, js_InitBinaryDataClasses) \ + macro(ArrayType, 50, js_InitBinaryDataClasses) \ + macro(StructType, 51, js_InitBinaryDataClasses) \ + macro(ArrayTypeObject, 52, js_InitBinaryDataClasses) \ -#endif /* jsprototypes_h___ */ +#endif /* jsprototypes_h */ diff --git a/external/spidermonkey/include/mac/jsproxy.h b/external/spidermonkey/include/mac/jsproxy.h index 399490eddc..56868a05c3 100644 --- a/external/spidermonkey/include/mac/jsproxy.h +++ b/external/spidermonkey/include/mac/jsproxy.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsproxy_h___ -#define jsproxy_h___ +#ifndef jsproxy_h +#define jsproxy_h #include "jsapi.h" #include "jsfriendapi.h" @@ -129,7 +129,7 @@ class JS_FRIEND_API(BaseProxyHandler) MutableHandleValue vp); /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) = 0; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) = 0; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -190,7 +190,7 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -242,7 +242,7 @@ class Proxy static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); /* Spidermonkey extensions. */ - static bool isExtensible(JSObject *proxy); + static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -259,12 +259,17 @@ class Proxy inline bool IsObjectProxyClass(const Class *clasp) { - return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass; + return clasp == js::ObjectProxyClassPtr || clasp == js::OuterWindowProxyClassPtr; } inline bool IsFunctionProxyClass(const Class *clasp) { - return clasp == &js::FunctionProxyClass; + return clasp == js::FunctionProxyClassPtr; +} + +inline bool IsProxyClass(const Class *clasp) +{ + return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); } inline bool IsObjectProxy(JSObject *obj) @@ -279,36 +284,33 @@ inline bool IsFunctionProxy(JSObject *obj) inline bool IsProxy(JSObject *obj) { - Class *clasp = GetObjectClass(obj); - return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); + return IsProxyClass(GetObjectClass(obj)); } -/* Shared between object and function proxies. */ /* - * NOTE: JSSLOT_PROXY_PRIVATE is 0, because that way slot 0 is usable by API + * These are part of the API. + * + * NOTE: PROXY_PRIVATE_SLOT is 0 because that way slot 0 is usable by API * clients for both proxy and non-proxy objects. So an API client that only * needs to store one slot's worth of data doesn't need to branch on what sort * of object it has. */ -const uint32_t JSSLOT_PROXY_PRIVATE = 0; -const uint32_t JSSLOT_PROXY_HANDLER = 1; -const uint32_t JSSLOT_PROXY_EXTRA = 2; -/* Function proxies only. */ -const uint32_t JSSLOT_PROXY_CALL = 4; -const uint32_t JSSLOT_PROXY_CONSTRUCT = 5; +const uint32_t PROXY_PRIVATE_SLOT = 0; +const uint32_t PROXY_HANDLER_SLOT = 1; +const uint32_t PROXY_EXTRA_SLOT = 2; inline BaseProxyHandler * GetProxyHandler(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return (BaseProxyHandler *) GetReservedSlot(obj, JSSLOT_PROXY_HANDLER).toPrivate(); + return (BaseProxyHandler *) GetReservedSlot(obj, PROXY_HANDLER_SLOT).toPrivate(); } inline const Value & GetProxyPrivate(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE); + return GetReservedSlot(obj, PROXY_PRIVATE_SLOT); } inline JSObject * @@ -322,14 +324,14 @@ inline const Value & GetProxyExtra(JSObject *obj, size_t n) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n); + return GetReservedSlot(obj, PROXY_EXTRA_SLOT + n); } inline void SetProxyHandler(JSObject *obj, BaseProxyHandler *handler) { JS_ASSERT(IsProxy(obj)); - SetReservedSlot(obj, JSSLOT_PROXY_HANDLER, PrivateValue(handler)); + SetReservedSlot(obj, PROXY_HANDLER_SLOT, PrivateValue(handler)); } inline void @@ -337,7 +339,7 @@ SetProxyExtra(JSObject *obj, size_t n, const Value &extra) { JS_ASSERT(IsProxy(obj)); JS_ASSERT(n <= 1); - SetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n, extra); + SetReservedSlot(obj, PROXY_EXTRA_SLOT + n, extra); } enum ProxyCallable { @@ -346,7 +348,7 @@ enum ProxyCallable { }; JS_FRIEND_API(JSObject *) -NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv, +NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto, JSObject *parent, ProxyCallable callable = ProxyNotCallable); JSObject * @@ -426,6 +428,6 @@ class JS_FRIEND_API(AutoWaivePolicy) { } /* namespace js */ extern JS_FRIEND_API(JSObject *) -js_InitProxyClass(JSContext *cx, JSHandleObject obj); +js_InitProxyClass(JSContext *cx, JS::HandleObject obj); -#endif +#endif /* jsproxy_h */ diff --git a/external/spidermonkey/include/mac/jsprvtd.h b/external/spidermonkey/include/mac/jsprvtd.h index 4db5ed8c36..1fbc086a7c 100644 --- a/external/spidermonkey/include/mac/jsprvtd.h +++ b/external/spidermonkey/include/mac/jsprvtd.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprvtd_h___ -#define jsprvtd_h___ +#ifndef jsprvtd_h +#define jsprvtd_h /* * JS private typename definitions. * @@ -56,13 +56,7 @@ typedef struct JSStackHeader JSStackHeader; typedef struct JSSubString JSSubString; typedef struct JSSpecializedNative JSSpecializedNative; -/* - * Template declarations. - * - * jsprvtd.h can be included in both C and C++ translation units. For C++, it - * may possibly be wrapped in an extern "C" block which does not agree with - * templates. - */ +/* String typedefs. */ class JSDependentString; class JSExtensibleString; class JSExternalString; @@ -76,6 +70,7 @@ namespace js { struct ArgumentsData; struct Class; +class AutoNameVector; class RegExpGuard; class RegExpObject; class RegExpObjectBuilder; @@ -83,6 +78,7 @@ class RegExpShared; class RegExpStatics; class MatchPairs; class PropertyName; +class LazyScript; enum RegExpFlag { @@ -95,19 +91,14 @@ enum RegExpFlag AllFlags = 0x0f }; -class ExecuteArgsGuard; -class InvokeFrameGuard; -class InvokeArgsGuard; class StringBuffer; class FrameRegs; class StackFrame; -class StackSegment; -class StackSpace; -class ContextStack; class ScriptFrameIter; class Proxy; +class JS_FRIEND_API(AutoEnterPolicy); class JS_FRIEND_API(BaseProxyHandler); class JS_FRIEND_API(Wrapper); class JS_FRIEND_API(CrossCompartmentWrapper); @@ -140,24 +131,29 @@ class WatchpointMap; typedef JSObject Env; typedef JSNative Native; +typedef JSParallelNative ParallelNative; +typedef JSThreadSafeNative ThreadSafeNative; typedef JSPropertyOp PropertyOp; typedef JSStrictPropertyOp StrictPropertyOp; typedef JSPropertyDescriptor PropertyDescriptor; +struct SourceCompressionToken; + namespace frontend { struct BytecodeEmitter; struct Definition; +class FullParseHandler; class FunctionBox; class ObjectBox; struct Token; struct TokenPos; class TokenStream; class ParseMapPool; -struct ParseNode; +class ParseNode; template -struct Parser; +class Parser; } /* namespace frontend */ @@ -284,18 +280,18 @@ typedef void * if an error or exception was thrown on cx. */ typedef JSObject * -(* JSObjectOp)(JSContext *cx, JSHandleObject obj); +(* JSObjectOp)(JSContext *cx, JS::Handle obj); /* Signature for class initialization ops. */ typedef JSObject * -(* JSClassInitializerOp)(JSContext *cx, JSHandleObject obj); +(* JSClassInitializerOp)(JSContext *cx, JS::HandleObject obj); /* * Hook that creates an iterator object for a given object. Returns the * iterator object or null if an error or exception was thrown on cx. */ typedef JSObject * -(* JSIteratorOp)(JSContext *cx, JSHandleObject obj, JSBool keysonly); +(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, JSBool keysonly); -#endif /* jsprvtd_h___ */ +#endif /* jsprvtd_h */ diff --git a/external/spidermonkey/include/mac/jspubtd.h b/external/spidermonkey/include/mac/jspubtd.h index 6b7e63e6ba..96f5dd8297 100644 --- a/external/spidermonkey/include/mac/jspubtd.h +++ b/external/spidermonkey/include/mac/jspubtd.h @@ -4,16 +4,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jspubtd_h___ -#define jspubtd_h___ +#ifndef jspubtd_h +#define jspubtd_h /* * JS public API typedefs. */ +#include "mozilla/PodOperations.h" + #include "jsprototypes.h" #include "jstypes.h" +#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) +# define JSGC_TRACK_EXACT_ROOTS +#endif + namespace JS { /* @@ -25,6 +31,8 @@ class Value; template class Rooted; +class JS_PUBLIC_API(AutoGCRooter); + struct Zone; } /* namespace JS */ @@ -44,10 +52,8 @@ struct Zone; * oblivious to the change. This feature can be explicitly disabled in debug * builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. */ - // Needed for cocos2d-js -#define JS_NO_JSVAL_JSID_STRUCT_TYPES - +#define JS_NO_JSVAL_JSID_STRUCT_TYPES # if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) # define JS_USE_JSID_STRUCT_TYPES # endif @@ -154,9 +160,10 @@ typedef enum { JSTRACE_SCRIPT, /* - * Trace kinds internal to the engine. The embedding can only them if it - * implements JSTraceCallback. + * Trace kinds internal to the engine. The embedding can only see them if + * it implements JSTraceCallback. */ + JSTRACE_LAZY_SCRIPT, JSTRACE_IONCODE, JSTRACE_SHAPE, JSTRACE_BASE_SHAPE, @@ -229,6 +236,18 @@ struct Runtime namespace js { +/* + * Parallel operations in general can have one of three states. They may + * succeed, fail, or "bail", where bail indicates that the code encountered an + * unexpected condition and should be re-run sequentially. Different + * subcategories of the "bail" state are encoded as variants of TP_RETRY_*. + */ +enum ParallelResult { TP_SUCCESS, TP_RETRY_SEQUENTIALLY, TP_RETRY_AFTER_GC, TP_FATAL }; + +struct ThreadSafeContext; +struct ForkJoinSlice; +class ExclusiveContext; + class Allocator; class SkipRoot; @@ -273,18 +292,28 @@ template <> struct RootKind : SpecificRootKind struct RootKind : SpecificRootKind {}; template <> struct RootKind : SpecificRootKind {}; -struct ContextFriendFields { - JSRuntime *const runtime; +struct ContextFriendFields +{ + protected: + JSRuntime *const runtime_; /* The current compartment. */ - JSCompartment *compartment; + JSCompartment *compartment_; /* The current zone. */ JS::Zone *zone_; + public: explicit ContextFriendFields(JSRuntime *rt) - : runtime(rt), compartment(NULL), zone_(NULL) - { } + : runtime_(rt), compartment_(NULL), zone_(NULL), autoGCRooters(NULL) + { +#ifdef JSGC_TRACK_EXACT_ROOTS + mozilla::PodArrayZero(thingGCRooters); +#endif +#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) + skipGCRooters = NULL; +#endif + } static const ContextFriendFields *get(const JSContext *cx) { return reinterpret_cast(cx); @@ -294,7 +323,7 @@ struct ContextFriendFields { return reinterpret_cast(cx); } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -313,6 +342,13 @@ struct ContextFriendFields { */ SkipRoot *skipGCRooters; #endif + + /* Stack of thread-stack-allocated GC roots. */ + JS::AutoGCRooter *autoGCRooters; + + friend JSRuntime *GetRuntime(const JSContext *cx); + friend JSCompartment *GetContextCompartment(const JSContext *cx); + friend JS::Zone *GetContextZone(const JSContext *cx); }; class PerThreadData; @@ -338,7 +374,7 @@ struct PerThreadDataFriendFields PerThreadDataFriendFields(); -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -384,4 +420,4 @@ struct PerThreadDataFriendFields } /* namespace js */ -#endif /* jspubtd_h___ */ +#endif /* jspubtd_h */ diff --git a/external/spidermonkey/include/mac/jstypes.h b/external/spidermonkey/include/mac/jstypes.h index e4c02f8d8d..17f67f70e1 100644 --- a/external/spidermonkey/include/mac/jstypes.h +++ b/external/spidermonkey/include/mac/jstypes.h @@ -18,8 +18,8 @@ ** for all C files. **/ -#ifndef jstypes_h___ -#define jstypes_h___ +#ifndef jstypes_h +#define jstypes_h #include "mozilla/Attributes.h" #include "mozilla/Util.h" @@ -279,4 +279,4 @@ typedef int JSBool; # define JS_EXTENSION_(s) s #endif -#endif /* jstypes_h___ */ +#endif /* jstypes_h */ diff --git a/external/spidermonkey/include/mac/jsutil.h b/external/spidermonkey/include/mac/jsutil.h index 49e1641c61..4020822be1 100644 --- a/external/spidermonkey/include/mac/jsutil.h +++ b/external/spidermonkey/include/mac/jsutil.h @@ -8,19 +8,19 @@ * PR assertion checker. */ -#ifndef jsutil_h___ -#define jsutil_h___ +#ifndef jsutil_h +#define jsutil_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/GuardObjects.h" -#include "js/Utility.h" - #ifdef USE_ZLIB -#include "zlib.h" +#include #endif +#include "js/Utility.h" + /* Forward declarations. */ struct JSContext; @@ -204,15 +204,6 @@ UnsignedPtrDiff(const void *bigger, const void *smaller) return size_t(bigger) - size_t(smaller); } -/* - * Ordinarily, a function taking a JSContext* 'cx' parameter reports errors on - * the context. In some cases, functions optionally report and indicate this by - * taking a nullable 'maybecx' parameter. In some cases, though, a function - * always needs a 'cx', but optionally reports. This option is presented by the - * MaybeReportError. - */ -enum MaybeReportError { REPORT_ERROR = true, DONT_REPORT_ERROR = false }; - /*****************************************************************************/ /* A bit array is an array of bits represented by an array of words (size_t). */ @@ -391,4 +382,4 @@ typedef size_t jsbitmap; JS_END_MACRO #endif -#endif /* jsutil_h___ */ +#endif /* jsutil_h */ diff --git a/external/spidermonkey/include/mac/jsversion.h b/external/spidermonkey/include/mac/jsversion.h index f3169fb5d1..1780616a32 100644 --- a/external/spidermonkey/include/mac/jsversion.h +++ b/external/spidermonkey/include/mac/jsversion.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsversion_h___ -#define jsversion_h___ +#ifndef jsversion_h +#define jsversion_h /* * Deprecated JS_VERSION handler. @@ -61,7 +61,7 @@ # define NEW_OBJECT_REPRESENTATION_ONLY() ((void)0) #else # define NEW_OBJECT_REPRESENTATION_ONLY() \ - MOZ_NOT_REACHED("don't call this! to be used in the new object representation") + MOZ_ASSUME_UNREACHABLE("don't call this! to be used in the new object representation") #endif -#endif /* jsversion_h___ */ +#endif /* jsversion_h */ diff --git a/external/spidermonkey/include/mac/jswrapper.h b/external/spidermonkey/include/mac/jswrapper.h index d0c0fc625c..f78df7db60 100644 --- a/external/spidermonkey/include/mac/jswrapper.h +++ b/external/spidermonkey/include/mac/jswrapper.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jswrapper_h___ -#define jswrapper_h___ +#ifndef jswrapper_h +#define jswrapper_h #include "mozilla/Attributes.h" @@ -66,8 +66,6 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler static Wrapper singleton; static Wrapper singletonWithPrototype; - - static void *getWrapperFamily(); }; /* Base class for all cross compartment wrapper handlers. */ @@ -105,7 +103,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -139,7 +137,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base public: SecurityWrapper(unsigned flags); - virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) MOZ_OVERRIDE; @@ -185,7 +183,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -297,4 +295,4 @@ struct JS_FRIEND_API(AutoMaybeTouchDeadZones) } /* namespace js */ -#endif +#endif /* jswrapper_h */ diff --git a/external/spidermonkey/include/mac/mozilla/AllocPolicy.h b/external/spidermonkey/include/mac/mozilla/AllocPolicy.h new file mode 100644 index 0000000000..20087e93bb --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/AllocPolicy.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * An allocation policy concept, usable for structures and algorithms to + * control how memory is allocated and how failures are handled. + */ + +#ifndef mozilla_AllocPolicy_h +#define mozilla_AllocPolicy_h + +#include +#include + +namespace mozilla { + +/* + * Allocation policies are used to implement the standard allocation behaviors + * in a customizable way. Additionally, custom behaviors may be added to these + * behaviors, such as additionally reporting an error through an out-of-band + * mechanism when OOM occurs. The concept modeled here is as follows: + * + * - public copy constructor, assignment, destructor + * - void* malloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* calloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* realloc_(void*, size_t, size_t) + * Responsible for OOM reporting when null is returned. The *used* bytes + * of the previous buffer is passed in (rather than the old allocation + * size), in addition to the *new* allocation size requested. + * - void free_(void*) + * - void reportAllocOverflow() const + * Called on allocation overflow (that is, an allocation implicitly tried + * to allocate more than the available memory space -- think allocating an + * array of large-size objects, where N * size overflows) before null is + * returned. + * + * mfbt provides (and typically uses by default) only MallocAllocPolicy, which + * does nothing more than delegate to the malloc/alloc/free functions. + */ + +/* + * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no + * extra behaviors. + */ +class MallocAllocPolicy +{ + public: + void* malloc_(size_t bytes) { return malloc(bytes); } + void* calloc_(size_t bytes) { return calloc(bytes, 1); } + void* realloc_(void* p, size_t oldBytes, size_t bytes) { return realloc(p, bytes); } + void free_(void* p) { free(p); } + void reportAllocOverflow() const {} +}; + + +} // namespace mozilla + +#endif /* mozilla_AllocPolicy_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Array.h b/external/spidermonkey/include/mac/mozilla/Array.h new file mode 100644 index 0000000000..5af9aaa133 --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/Array.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A compile-time constant-length array with bounds-checking assertions. */ + +#ifndef mozilla_Array_h +#define mozilla_Array_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" + +#include + +namespace mozilla { + +template +class Array +{ + T arr[Length]; + + public: + T& operator[](size_t i) { + MOZ_ASSERT(i < Length); + return arr[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(i < Length); + return arr[i]; + } +}; + +template +class Array +{ + public: + T& operator[](size_t i) { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } + + const T& operator[](size_t i) const { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } +}; + +} /* namespace mozilla */ + +#endif /* mozilla_Array_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Assertions.h b/external/spidermonkey/include/mac/mozilla/Assertions.h index 5ead7f493e..00b7037802 100644 --- a/external/spidermonkey/include/mac/mozilla/Assertions.h +++ b/external/spidermonkey/include/mac/mozilla/Assertions.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of runtime and static assertion macros for C and C++. */ -#ifndef mozilla_Assertions_h_ -#define mozilla_Assertions_h_ +#ifndef mozilla_Assertions_h +#define mozilla_Assertions_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" @@ -39,44 +40,24 @@ #endif /* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time*. This - * can be useful when you make certain assumptions about what must hold for + * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. + * In C++11, static_assert is provided by the compiler to the same effect. + * This can be useful when you make certain assumptions about what must hold for * optimal, or even correct, behavior. For example, you might assert that the * size of a struct is a multiple of the target architecture's word size: * * struct S { ... }; + * // C * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, * "S should be a multiple of word size for efficiency"); + * // C++11 + * static_assert(sizeof(S) % sizeof(size_t) == 0, + * "S should be a multiple of word size for efficiency"); * * This macro can be used in any location where both an extern declaration and a * typedef could be used. - * - * Be aware of the gcc 4.2 concerns noted further down when writing patches that - * use this macro, particularly if a patch only bounces on OS X. */ -#ifdef __cplusplus -# if defined(__clang__) -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_extension(cxx_static_assert) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__GNUC__) -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(_MSC_VER) -# if _MSC_VER >= 1600 /* MSVC 10 */ -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__HP_aCC) -# if __HP_aCC >= 62500 && defined(_HP_CXX0x_SOURCE) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# endif -#endif -#ifndef MOZ_STATIC_ASSERT +#ifndef __cplusplus /* * Some of the definitions below create an otherwise-unused typedef. This * triggers compiler warnings with some versions of gcc, so mark the typedefs @@ -124,78 +105,23 @@ # define MOZ_STATIC_ASSERT(cond, reason) \ extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE # endif -#endif #define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) +#else +#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) +#endif #ifdef __cplusplus extern "C" { #endif -/* - * MOZ_CRASH crashes the program, plain and simple, in a Breakpad-compatible - * way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. We use TerminateProcess - * with the exit code aborting would generate because we don't want to invoke - * atexit handlers, destructors, library unload handlers, and so on when our - * process might be in a compromised state. We don't use abort() because - * it'd cause Windows to annoyingly pop up the process error dialog multiple - * times. See bug 345118 and bug 426163. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - TerminateProcess(GetCurrentProcess(), 3); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - ::abort(); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - abort(); \ - } while (0) -# endif -#endif - /* * Prints |s| as an assertion failure (using file and ln as the location of the * assertion) to the standard debug-output channel. * - * Usually you should use MOZ_ASSERT instead of this method. This method is - * primarily for internal use in this header, and only secondarily for use in - * implementing release-build assertions. + * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This + * method is primarily for internal use in this header, and only secondarily + * for use in implementing release-build assertions. */ static MOZ_ALWAYS_INLINE void MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) @@ -209,6 +135,112 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif } +static MOZ_ALWAYS_INLINE void +MOZ_ReportCrash(const char* s, const char* file, int ln) +{ +#ifdef ANDROID + __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", + "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); + fflush(stderr); +#endif +} + +/** + * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should + * call MOZ_CRASH instead. + */ +#if defined(_MSC_VER) + /* + * On MSVC use the __debugbreak compiler intrinsic, which produces an inline + * (not nested in a system function) breakpoint. This distinctively invokes + * Breakpad without requiring system library symbols on all stack-processing + * machines, as a nested breakpoint would require. + * + * We use TerminateProcess with the exit code aborting would generate + * because we don't want to invoke atexit handlers, destructors, library + * unload handlers, and so on when our process might be in a compromised + * state. + * + * We don't use abort() because it'd cause Windows to annoyingly pop up the + * process error dialog multiple times. See bug 345118 and bug 426163. + * + * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the + * compiler doesn't hassle us to provide a return statement after a + * MOZ_REALLY_CRASH() call. + * + * (Technically these are Windows requirements, not MSVC requirements. But + * practically you need MSVC for debugging, and we only ship builds created + * by MSVC, so doing it this way reduces complexity.) + */ + +__declspec(noreturn) __inline void MOZ_NoReturn() {} + +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + ::TerminateProcess(::GetCurrentProcess(), 3); \ + ::MOZ_NoReturn(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + TerminateProcess(GetCurrentProcess(), 3); \ + MOZ_NoReturn(); \ + } while (0) +# endif +#else +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + ::abort(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + abort(); \ + } while (0) +# endif +#endif + +/* + * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a + * Breakpad-compatible way, in both debug and release builds. + * + * MOZ_CRASH is a good solution for "handling" failure cases when you're + * unwilling or unable to handle them more cleanly -- for OOM, for likely memory + * corruption, and so on. It's also a good solution if you need safe behavior + * in release builds as well as debug builds. But if the failure is one that + * should be debugged and fixed, MOZ_ASSERT is generally preferable. + * + * The optional explanation-string, if provided, must be a string literal + * explaining why we're crashing. This argument is intended for use with + * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's + * obvious why we're crashing. + * + * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an + * explanation-string, we print the string to stderr. Otherwise, we don't + * print anything; this is because we want MOZ_CRASH to be 100% safe in release + * builds, and it's hard to print to stderr safely when memory might have been + * corrupted. + */ +#ifndef DEBUG +# define MOZ_CRASH(...) MOZ_REALLY_CRASH() +#else +# define MOZ_CRASH(...) \ + do { \ + MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ + MOZ_REALLY_CRASH(); \ + } while(0) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif @@ -251,7 +283,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* Now the two-argument form. */ @@ -259,7 +291,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* And now, helper macrology up the wazoo. */ @@ -310,14 +342,14 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif /* - * MOZ_NOT_REACHED_MARKER() expands to an expression which states that it is + * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that it is * undefined behavior for execution to reach this point. No guarantees are made * about what will happen if this is reached at runtime. Most code should - * probably use the higher level MOZ_NOT_REACHED, which uses this when + * probably use the higher level MOZ_ASSUME_UNREACHABLE, which uses this when * appropriate. */ #if defined(__clang__) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() #elif defined(__GNUC__) /* * __builtin_unreachable() was implemented in gcc 4.5. If we don't have @@ -325,49 +357,71 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) * in C++ in case there's another abort() visible in local scope. */ # if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() # else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif # endif #elif defined(_MSC_VER) -# define MOZ_NOT_REACHED_MARKER() __assume(0) +# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) #else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif #endif /* - * MOZ_NOT_REACHED(reason) indicates that the given point can't be reached - * during execution: simply reaching that point in execution is a bug. It takes - * as an argument an error message indicating the reason why that point should - * not have been reachable. + * MOZ_ASSUME_UNREACHABLE([reason]) tells the compiler that it can assume that + * the macro call cannot be reached during execution. This lets the compiler + * generate better-optimized code under some circumstances, at the expense of + * the program's behavior being undefined if control reaches the + * MOZ_ASSUME_UNREACHABLE. * - * // ...in a language parser... - * void handle(BooleanLiteralNode node) + * In Gecko, you probably should not use this macro outside of performance- or + * size-critical code, because it's unsafe. If you don't care about code size + * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. + * + * SpiderMonkey is a different beast, and there it's acceptable to use + * MOZ_ASSUME_UNREACHABLE more widely. + * + * Note that MOZ_ASSUME_UNREACHABLE is noreturn, so it's valid not to return a + * value following a MOZ_ASSUME_UNREACHABLE call. + * + * Example usage: + * + * enum ValueType { + * VALUE_STRING, + * VALUE_INT, + * VALUE_FLOAT + * }; + * + * int ptrToInt(ValueType type, void* value) { * { - * if (node.isTrue()) - * handleTrueLiteral(); - * else if (node.isFalse()) - * handleFalseLiteral(); - * else - * MOZ_NOT_REACHED("boolean literal that's not true or false?"); + * // We know for sure that type is either INT or FLOAT, and we want this + * // code to run as quickly as possible. + * switch (type) { + * case VALUE_INT: + * return *(int*) value; + * case VALUE_FLOAT: + * return (int) *(float*) value; + * default: + * MOZ_ASSUME_UNREACHABLE("can only handle VALUE_INT and VALUE_FLOAT"); + * } * } */ #if defined(DEBUG) -# define MOZ_NOT_REACHED(reason) \ +# define MOZ_ASSUME_UNREACHABLE(...) \ do { \ - MOZ_ASSERT(false, reason); \ - MOZ_NOT_REACHED_MARKER(); \ + MOZ_ASSERT(false, "MOZ_ASSUME_UNREACHABLE(" __VA_ARGS__ ")"); \ + MOZ_ASSUME_UNREACHABLE_MARKER(); \ } while (0) #else -# define MOZ_NOT_REACHED(reason) MOZ_NOT_REACHED_MARKER() +# define MOZ_ASSUME_UNREACHABLE(reason) MOZ_ASSUME_UNREACHABLE_MARKER() #endif /* @@ -384,4 +438,4 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) # define MOZ_ALWAYS_FALSE(expr) ((void)(expr)) #endif -#endif /* mozilla_Assertions_h_ */ +#endif /* mozilla_Assertions_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Atomics.h b/external/spidermonkey/include/mac/mozilla/Atomics.h new file mode 100644 index 0000000000..f876683c3e --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/Atomics.h @@ -0,0 +1,1014 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Implements (almost always) lock-free atomic operations. The operations here + * are a subset of that which can be found in C++11's header, with a + * different API to enforce consistent memory ordering constraints. + * + * Anyone caught using |volatile| for inter-thread memory safety needs to be + * sent a copy of this header and the C++11 standard. + */ + +#ifndef mozilla_Atomics_h +#define mozilla_Atomics_h + +#include "mozilla/Assertions.h" +#include "mozilla/TypeTraits.h" + +#include + +/* + * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK + * does not have . So be sure to check for support + * along with C++0x support. + */ +#if defined(__clang__) + /* + * clang doesn't like libstdc++'s version of before GCC 4.7, + * due to the loose typing of the __sync_* family of functions done by + * GCC. We do not have a particularly good way to detect this sort of + * case at this point, so just assume that if we're on a Linux system, + * we can't use the system's . + * + * OpenBSD uses an old libstdc++ 4.2.1 and thus doesnt have . + */ +# if !defined(__linux__) && !defined(__OpenBSD__) && \ + (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && \ + __has_include() +# define MOZ_HAVE_CXX11_ATOMICS +# endif +/* + * Android uses a different C++ standard library that does not provide + * support for . + * + * GCC 4.5.x and 4.6.x's unspecialized std::atomic template doesn't include + * inline definitions for the functions declared therein. This oversight + * leads to linking errors when using atomic enums. We therefore require + * GCC 4.7 or higher. + */ +#elif defined(__GNUC__) && !defined(__ANDROID__) +# include "mozilla/Compiler.h" +# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && \ + MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) +# define MOZ_HAVE_CXX11_ATOMICS +# endif +#elif defined(_MSC_VER) && _MSC_VER >= 1700 +# define MOZ_HAVE_CXX11_ATOMICS +#endif + +namespace mozilla { + +/** + * An enum of memory ordering possibilities for atomics. + * + * Memory ordering is the observable state of distinct values in memory. + * (It's a separate concept from atomicity, which concerns whether an + * operation can ever be observed in an intermediate state. Don't + * conflate the two!) Given a sequence of operations in source code on + * memory, it is *not* always the case that, at all times and on all + * cores, those operations will appear to have occurred in that exact + * sequence. First, the compiler might reorder that sequence, if it + * thinks another ordering will be more efficient. Second, the CPU may + * not expose so consistent a view of memory. CPUs will often perform + * their own instruction reordering, above and beyond that performed by + * the compiler. And each core has its own memory caches, and accesses + * (reads and writes both) to "memory" may only resolve to out-of-date + * cache entries -- not to the "most recently" performed operation in + * some global sense. Any access to a value that may be used by + * multiple threads, potentially across multiple cores, must therefore + * have a memory ordering imposed on it, for all code on all + * threads/cores to have a sufficiently coherent worldview. + * + * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and + * http://en.cppreference.com/w/cpp/atomic/memory_order go into more + * detail on all this, including examples of how each mode works. + * + * Note that for simplicity and practicality, not all of the modes in + * C++11 are supported. The missing C++11 modes are either subsumed by + * the modes we provide below, or not relevant for the CPUs we support + * in Gecko. These three modes are confusing enough as it is! + */ +enum MemoryOrdering { + /* + * Relaxed ordering is the simplest memory ordering: none at all. + * When the result of a write is observed, nothing may be inferred + * about other memory. Writes ostensibly performed "before" on the + * writing thread may not yet be visible. Writes performed "after" on + * the writing thread may already be visible, if the compiler or CPU + * reordered them. (The latter can happen if reads and/or writes get + * held up in per-processor caches.) Relaxed ordering means + * operations can always use cached values (as long as the actual + * updates to atomic values actually occur, correctly, eventually), so + * it's usually the fastest sort of atomic access. For this reason, + * *it's also the most dangerous kind of access*. + * + * Relaxed ordering is good for things like process-wide statistics + * counters that don't need to be consistent with anything else, so + * long as updates themselves are atomic. (And so long as any + * observations of that value can tolerate being out-of-date -- if you + * need some sort of up-to-date value, you need some sort of other + * synchronizing operation.) It's *not* good for locks, mutexes, + * reference counts, etc. that mediate access to other memory, or must + * be observably consistent with other memory. + * + * x86 architectures don't take advantage of the optimization + * opportunities that relaxed ordering permits. Thus it's possible + * that using relaxed ordering will "work" on x86 but fail elsewhere + * (ARM, say, which *does* implement non-sequentially-consistent + * relaxed ordering semantics). Be extra-careful using relaxed + * ordering if you can't easily test non-x86 architectures! + */ + Relaxed, + /* + * When an atomic value is updated with ReleaseAcquire ordering, and + * that new value is observed with ReleaseAcquire ordering, prior + * writes (atomic or not) are also observable. What ReleaseAcquire + * *doesn't* give you is any observable ordering guarantees for + * ReleaseAcquire-ordered operations on different objects. For + * example, if there are two cores that each perform ReleaseAcquire + * operations on separate objects, each core may or may not observe + * the operations made by the other core. The only way the cores can + * be synchronized with ReleaseAcquire is if they both + * ReleaseAcquire-access the same object. This implies that you can't + * necessarily describe some global total ordering of ReleaseAcquire + * operations. + * + * ReleaseAcquire ordering is good for (as the name implies) atomic + * operations on values controlling ownership of things: reference + * counts, mutexes, and the like. However, if you are thinking about + * using these to implement your own locks or mutexes, you should take + * a good, hard look at actual lock or mutex primitives first. + */ + ReleaseAcquire, + /* + * When an atomic value is updated with SequentiallyConsistent + * ordering, all writes observable when the update is observed, just + * as with ReleaseAcquire ordering. But, furthermore, a global total + * ordering of SequentiallyConsistent operations *can* be described. + * For example, if two cores perform SequentiallyConsistent operations + * on separate objects, one core will observably perform its update + * (and all previous operations will have completed), then the other + * core will observably perform its update (and all previous + * operations will have completed). (Although those previous + * operations aren't themselves ordered -- they could be intermixed, + * or ordered if they occur on atomic values with ordering + * requirements.) SequentiallyConsistent is the *simplest and safest* + * ordering of atomic operations -- it's always as if one operation + * happens, then another, then another, in some order -- and every + * core observes updates to happen in that single order. Because it + * has the most synchronization requirements, operations ordered this + * way also tend to be slowest. + * + * SequentiallyConsistent ordering can be desirable when multiple + * threads observe objects, and they all have to agree on the + * observable order of changes to them. People expect + * SequentiallyConsistent ordering, even if they shouldn't, when + * writing code, atomic or otherwise. SequentiallyConsistent is also + * the ordering of choice when designing lockless data structures. If + * you don't know what order to use, use this one. + */ + SequentiallyConsistent, +}; + +} // namespace mozilla + +// Build up the underlying intrinsics. +#ifdef MOZ_HAVE_CXX11_ATOMICS + +# include + +namespace mozilla { +namespace detail { + +/* + * We provide CompareExchangeFailureOrder to work around a bug in some + * versions of GCC's header. See bug 898491. + */ +template struct AtomicOrderConstraints; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; + static const std::memory_order LoadOrder = std::memory_order_relaxed; + static const std::memory_order StoreOrder = std::memory_order_relaxed; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_relaxed; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; + static const std::memory_order LoadOrder = std::memory_order_acquire; + static const std::memory_order StoreOrder = std::memory_order_release; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_acquire; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; + static const std::memory_order LoadOrder = std::memory_order_seq_cst; + static const std::memory_order StoreOrder = std::memory_order_seq_cst; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_seq_cst; +}; + +template +struct IntrinsicBase +{ + typedef std::atomic ValueType; + typedef AtomicOrderConstraints OrderedOp; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T load(const typename Base::ValueType& ptr) { + return ptr.load(Base::OrderedOp::LoadOrder); + } + static void store(typename Base::ValueType& ptr, T val) { + ptr.store(val, Base::OrderedOp::StoreOrder); + } + static T exchange(typename Base::ValueType& ptr, T val) { + return ptr.exchange(val, Base::OrderedOp::AtomicRMWOrder); + } + static bool compareExchange(typename Base::ValueType& ptr, T oldVal, T newVal) { + return ptr.compare_exchange_strong(oldVal, newVal, + Base::OrderedOp::AtomicRMWOrder, + Base::OrderedOp::CompareExchangeFailureOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T add(typename Base::ValueType& ptr, T val) { + return ptr.fetch_add(val, Base::OrderedOp::AtomicRMWOrder); + } + static T sub(typename Base::ValueType& ptr, T val) { + return ptr.fetch_sub(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T* add(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_add(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + static T* sub(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_sub(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + private: + /* + * GCC 4.6's header has a bug where adding X to an + * atomic is not the same as adding X to a T*. Hence the need + * for this function to provide the correct addend. + */ + static ptrdiff_t fixupAddend(ptrdiff_t val) { +#if defined(__clang__) || defined(_MSC_VER) + return val; +#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \ + !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) + return val * sizeof(T); +#else + return val; +#endif + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + typedef IntrinsicBase Base; + static T inc(typename Base::ValueType& ptr) { + return IntrinsicAddSub::add(ptr, 1); + } + static T dec(typename Base::ValueType& ptr) { + return IntrinsicAddSub::sub(ptr, 1); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + typedef IntrinsicBase Base; + static T or_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_or(val, Base::OrderedOp::AtomicRMWOrder); + } + static T xor_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_xor(val, Base::OrderedOp::AtomicRMWOrder); + } + static T and_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_and(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct AtomicIntrinsics + : public IntrinsicMemoryOps, public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(__GNUC__) + +namespace mozilla { +namespace detail { + +/* + * The __sync_* family of intrinsics is documented here: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html + * + * While these intrinsics are deprecated in favor of the newer __atomic_* + * family of intrincs: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html + * + * any GCC version that supports the __atomic_* intrinsics will also support + * the header and so will be handled above. We provide a version of + * atomics using the __sync_* intrinsics to support older versions of GCC. + * + * All __sync_* intrinsics that we use below act as full memory barriers, for + * both compiler and hardware reordering, except for __sync_lock_test_and_set, + * which is a only an acquire barrier. When we call __sync_lock_test_and_set, + * we add a barrier above it as appropriate. + */ + +template struct Barrier; + +/* + * Some processors (in particular, x86) don't require quite so many calls to + * __sync_sychronize as our specializations of Barrier produce. If + * performance turns out to be an issue, defining these specializations + * on a per-processor basis would be a good first tuning step. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() { __sync_synchronize(); } + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() { __sync_synchronize(); } +}; + +template +struct IntrinsicMemoryOps +{ + static T load(const T& ptr) { + Barrier::beforeLoad(); + T val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(T& ptr, T val) { + Barrier::beforeStore(); + ptr = val; + Barrier::afterStore(); + } + static T exchange(T& ptr, T val) { + // __sync_lock_test_and_set is only an acquire barrier; loads and stores + // can't be moved up from after to before it, but they can be moved down + // from before to after it. We may want a stricter ordering, so we need + // an explicit barrier. + + Barrier::beforeStore(); + return __sync_lock_test_and_set(&ptr, val); + } + static bool compareExchange(T& ptr, T oldVal, T newVal) { + return __sync_bool_compare_and_swap(&ptr, oldVal, newVal); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T ValueType; + static T add(T& ptr, T val) { + return __sync_fetch_and_add(&ptr, val); + } + static T sub(T& ptr, T val) { + return __sync_fetch_and_sub(&ptr, val); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T* ValueType; + /* + * The reinterpret_casts are needed so that + * __sync_fetch_and_{add,sub} will properly type-check. + * + * Also, these functions do not provide standard semantics for + * pointer types, so we need to adjust the addend. + */ + static ValueType add(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_add(&ptr, amount); + } + static ValueType sub(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_sub(&ptr, amount); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static T inc(T& ptr) { return IntrinsicAddSub::add(ptr, 1); } + static T dec(T& ptr) { return IntrinsicAddSub::sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static T or_(T& ptr, T val) { + return __sync_fetch_and_or(&ptr, val); + } + static T xor_(T& ptr, T val) { + return __sync_fetch_and_xor(&ptr, val); + } + static T and_(T& ptr, T val) { + return __sync_fetch_and_and(&ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(_MSC_VER) + +/* + * Windows comes with a full complement of atomic operations. + * Unfortunately, most of those aren't available for Windows XP (even if + * the compiler supports intrinsics for them), which is the oldest + * version of Windows we support. Therefore, we only provide operations + * on 32-bit datatypes for 32-bit Windows versions; for 64-bit Windows + * versions, we support 64-bit datatypes as well. + * + * To avoid namespace pollution issues, we declare whatever functions we + * need ourselves. + */ + +extern "C" { +long __cdecl _InterlockedExchangeAdd(long volatile* dst, long value); +long __cdecl _InterlockedOr(long volatile* dst, long value); +long __cdecl _InterlockedXor(long volatile* dst, long value); +long __cdecl _InterlockedAnd(long volatile* dst, long value); +long __cdecl _InterlockedExchange(long volatile *dst, long value); +long __cdecl _InterlockedCompareExchange(long volatile *dst, long newVal, long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd) +# pragma intrinsic(_InterlockedOr) +# pragma intrinsic(_InterlockedXor) +# pragma intrinsic(_InterlockedAnd) +# pragma intrinsic(_InterlockedExchange) +# pragma intrinsic(_InterlockedCompareExchange) + +namespace mozilla { +namespace detail { + +# if !defined(_M_IX86) && !defined(_M_X64) + /* + * The implementations below are optimized for x86ish systems. You + * will have to modify them if you are porting to Windows on a + * different architecture. + */ +# error "Unknown CPU type" +# endif + +/* + * The PrimitiveIntrinsics template should define |Type|, the datatype of size + * DataSize upon which we operate, and the following eight functions. + * + * static Type add(Type* ptr, Type val); + * static Type sub(Type* ptr, Type val); + * static Type or_(Type* ptr, Type val); + * static Type xor_(Type* ptr, Type val); + * static Type and_(Type* ptr, Type val); + * + * These functions perform the obvious operation on the value contained in + * |*ptr| combined with |val| and return the value previously stored in + * |*ptr|. + * + * static void store(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and must provide a full + * memory fence after the store to prevent compiler and hardware instruction + * reordering. It should also act as a compiler barrier to prevent reads and + * writes from moving to after the store. + * + * static Type exchange(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and returns the previous + * contents of *ptr; + * + * static bool compareExchange(Type* ptr, Type oldVal, Type newVal); + * + * This function atomically performs the following operation: + * + * if (*ptr == oldVal) { + * *ptr = newVal; + * return true; + * } else { + * return false; + * } + * + */ +template struct PrimitiveIntrinsics; + +template<> +struct PrimitiveIntrinsics<4> +{ + typedef long Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * _InterlockedExchangeSubtract isn't available before Windows 7, + * and we must support Windows XP. + */ + return _InterlockedExchangeAdd(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange(ptr, newVal, oldVal) == oldVal; + } +}; + +# if defined(_M_X64) + +extern "C" { +long long __cdecl _InterlockedExchangeAdd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedOr64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedXor64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedAnd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedExchange64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedCompareExchange64(long long volatile* dst, + long long newVal, + long long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd64) +# pragma intrinsic(_InterlockedOr64) +# pragma intrinsic(_InterlockedXor64) +# pragma intrinsic(_InterlockedAnd64) +# pragma intrinsic(_InterlockedExchange64) +# pragma intrinsic(_InterlockedCompareExchange64) + +template <> +struct PrimitiveIntrinsics<8> +{ + typedef __int64 Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd64(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * There is no _InterlockedExchangeSubtract64. + */ + return _InterlockedExchangeAdd64(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr64(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor64(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd64(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange64(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange64(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange64(ptr, newVal, oldVal) == oldVal; + } +}; + +# endif + +extern "C" { void _ReadWriteBarrier(); } + +# pragma intrinsic(_ReadWriteBarrier) + +template struct Barrier; + +/* + * We do not provide an afterStore method in Barrier, as Relaxed and + * ReleaseAcquire orderings do not require one, and the required barrier + * for SequentiallyConsistent is handled by PrimitiveIntrinsics. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template<> +struct Barrier +{ + static void beforeLoad() { _ReadWriteBarrier(); } + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T val) { return static_cast(val); } + static T fromPrimType(PrimType val) { return static_cast(val); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T* val) { return reinterpret_cast(val); } + static T* fromPrimType(PrimType val) { return reinterpret_cast(val); } +}; + +template +struct IntrinsicBase +{ + typedef T ValueType; + typedef PrimitiveIntrinsics Primitives; + typedef typename Primitives::Type PrimType; + static_assert(sizeof(PrimType) == sizeof(T), + "Selection of PrimitiveIntrinsics was wrong"); + typedef CastHelper Cast; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + static ValueType load(const ValueType& ptr) { + Barrier::beforeLoad(); + ValueType val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(ValueType& ptr, ValueType val) { + // For SequentiallyConsistent, Primitives::store() will generate the + // proper memory fence. Everything else just needs a barrier before + // the store. + if (Order == SequentiallyConsistent) { + Primitives::store(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + } else { + Barrier::beforeStore(); + ptr = val; + } + } + static ValueType exchange(ValueType& ptr, ValueType val) { + PrimType oldval = + Primitives::exchange(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + return Cast::fromPrimType(oldval); + } + static bool compareExchange(ValueType& ptr, ValueType oldVal, ValueType newVal) { + return Primitives::compareExchange(reinterpret_cast(&ptr), + Cast::toPrimType(oldVal), + Cast::toPrimType(newVal)); + } +}; + +template +struct IntrinsicApplyHelper : public IntrinsicBase +{ + typedef PrimType (*BinaryOp)(PrimType*, PrimType); + typedef PrimType (*UnaryOp)(PrimType*); + + static ValueType applyBinaryFunction(BinaryOp op, ValueType& ptr, + ValueType val) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + PrimType primTypeVal = Cast::toPrimType(val); + return Cast::fromPrimType(op(primTypePtr, primTypeVal)); + } + + static ValueType applyUnaryFunction(UnaryOp op, ValueType& ptr) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + return Cast::fromPrimType(op(primTypePtr)); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::add, ptr, val); + } + static ValueType sub(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::sub, ptr, val); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::add, ptr, + (ValueType)(amount * sizeof(ValueType))); + } + static ValueType sub(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::sub, ptr, + (ValueType)(amount * sizeof(ValueType))); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static ValueType inc(ValueType& ptr) { return add(ptr, 1); } + static ValueType dec(ValueType& ptr) { return sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static ValueType or_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::or_, ptr, val); + } + static ValueType xor_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::xor_, ptr, val); + } + static ValueType and_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::and_, ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#else +# error "Atomic compiler intrinsics are not supported on your platform" +#endif + +namespace mozilla { + +namespace detail { + +template +class AtomicBase +{ + // We only support 32-bit types on 32-bit Windows, which constrains our + // implementation elsewhere. But we support pointer-sized types everywhere. + static_assert(sizeof(T) == 4 || (sizeof(uintptr_t) == 8 && sizeof(T) == 8), + "mozilla/Atomics.h only supports 32-bit and pointer-sized types"); + + protected: + typedef typename detail::AtomicIntrinsics Intrinsics; + typename Intrinsics::ValueType mValue; + + public: + AtomicBase() : mValue() {} + AtomicBase(T aInit) { Intrinsics::store(mValue, aInit); } + + operator T() const { return Intrinsics::load(mValue); } + + T operator=(T aValue) { + Intrinsics::store(mValue, aValue); + return aValue; + } + + /** + * Performs an atomic swap operation. aValue is stored and the previous + * value of this variable is returned. + */ + T exchange(T aValue) { + return Intrinsics::exchange(mValue, aValue); + } + + /** + * Performs an atomic compare-and-swap operation and returns true if it + * succeeded. This is equivalent to atomically doing + * + * if (mValue == aOldValue) { + * mValue = aNewValue; + * return true; + * } else { + * return false; + * } + */ + bool compareExchange(T aOldValue, T aNewValue) { + return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); + } + + private: + template + AtomicBase(const AtomicBase& aCopy) MOZ_DELETE; +}; + +template +class AtomicBaseIncDec : public AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + AtomicBaseIncDec() : Base() {} + AtomicBaseIncDec(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } + T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } + T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } + T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } + + private: + template + AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) MOZ_DELETE; +}; + +} // namespace detail + +/** + * A wrapper for a type that enforces that all memory accesses are atomic. + * + * In general, where a variable |T foo| exists, |Atomic foo| can be used in + * its place. Implementations for integral and pointer types are provided + * below. + * + * Atomic accesses are sequentially consistent by default. You should + * use the default unless you are tall enough to ride the + * memory-ordering roller coaster (if you're not sure, you aren't) and + * you have a compelling reason to do otherwise. + * + * There is one exception to the case of atomic memory accesses: providing an + * initial value of the atomic value is not guaranteed to be atomic. This is a + * deliberate design choice that enables static atomic variables to be declared + * without introducing extra static constructors. + */ +template +class Atomic; + +/** + * Atomic implementation for integral types. + * + * In addition to atomic store and load operations, compound assignment and + * increment/decrement operators are implemented which perform the + * corresponding read-modify-write operation atomically. Finally, an atomic + * swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator+=(T delta) { return Base::Intrinsics::add(Base::mValue, delta) + delta; } + T operator-=(T delta) { return Base::Intrinsics::sub(Base::mValue, delta) - delta; } + T operator|=(T val) { return Base::Intrinsics::or_(Base::mValue, val) | val; } + T operator^=(T val) { return Base::Intrinsics::xor_(Base::mValue, val) ^ val; } + T operator&=(T val) { return Base::Intrinsics::and_(Base::mValue, val) & val; } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for pointer types. + * + * An atomic compare-and-swap primitive for pointer variables is provided, as + * are atomic increment and decement operators. Also provided are the compound + * assignment operators for addition and subtraction. Atomic swap (via + * exchange()) is included as well. + */ +template +class Atomic : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T* aInit) : Base(aInit) {} + + using Base::operator=; + + T* operator+=(ptrdiff_t delta) { + return Base::Intrinsics::add(Base::mValue, delta) + delta; + } + T* operator-=(ptrdiff_t delta) { + return Base::Intrinsics::sub(Base::mValue, delta) - delta; + } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for enum types. + * + * The atomic store and load operations and the atomic swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_Atomics_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Attributes.h b/external/spidermonkey/include/mac/mozilla/Attributes.h index 89f3641fc9..6ea9776fbf 100644 --- a/external/spidermonkey/include/mac/mozilla/Attributes.h +++ b/external/spidermonkey/include/mac/mozilla/Attributes.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of various class and method modifier attributes. */ -#ifndef mozilla_Attributes_h_ -#define mozilla_Attributes_h_ +#ifndef mozilla_Attributes_h +#define mozilla_Attributes_h #include "mozilla/Compiler.h" @@ -117,11 +118,18 @@ * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a * function at compile time. A constexpr function cannot examine any values * except its arguments and can have no side effects except its return value. + * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's + * value may be computed at compile time. It should be prefered to just + * marking variables as MOZ_CONSTEXPR because if the compiler does not support + * constexpr it will fall back to making the variable const, and some compilers + * do not accept variables being marked both const and constexpr. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR # define MOZ_CONSTEXPR constexpr +# define MOZ_CONSTEXPR_VAR constexpr #else # define MOZ_CONSTEXPR /* no support */ +# define MOZ_CONSTEXPR_VAR const #endif /* @@ -382,18 +390,42 @@ * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is * expected to live on the stack, so it is a compile-time error to use it, or * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). It may be a base or - * a member of another class only if both classes are marked with this - * annotation. + * a new expression (unless placement new is being used). If a member of + * another class uses this class, or if another class inherits from this + * class, then it is considered to be a stack class as well, although this + * attribute need not be provided in such cases. + * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is + * expected to live on the stack or in static storage, so it is a compile-time + * error to use it, or an array of such objects, as the type of a new + * expression (unless placement new is being used). If a member of another + * class uses this class, or if another class inherits from this class, then + * it is considered to be a non-heap class as well, although this attribute + * need not be provided in such cases. */ #ifdef MOZ_CLANG_PLUGIN # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) +# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) #else # define MOZ_MUST_OVERRIDE /* nothing */ # define MOZ_STACK_CLASS /* nothing */ +# define MOZ_NONHEAP_CLASS /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ +/* + * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that + * it's safe to use 'this' in an initializer list. + */ +#ifdef _MSC_VER +# define MOZ_THIS_IN_INITIALIZER_LIST() \ + __pragma(warning(push)) \ + __pragma(warning(disable:4355)) \ + this \ + __pragma(warning(pop)) +#else +# define MOZ_THIS_IN_INITIALIZER_LIST() this +#endif + #endif /* __cplusplus */ -#endif /* mozilla_Attributes_h_ */ +#endif /* mozilla_Attributes_h */ diff --git a/external/spidermonkey/include/mac/mozilla/BloomFilter.h b/external/spidermonkey/include/mac/mozilla/BloomFilter.h index 8680ef2907..afe4b72b80 100644 --- a/external/spidermonkey/include/mac/mozilla/BloomFilter.h +++ b/external/spidermonkey/include/mac/mozilla/BloomFilter.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * A counting Bloom filter implementation. This allows consumers to @@ -10,14 +11,14 @@ * incorrectly answer "yes" when the correct answer is "no"). */ -#ifndef mozilla_BloomFilter_h_ -#define mozilla_BloomFilter_h_ +#ifndef mozilla_BloomFilter_h +#define mozilla_BloomFilter_h #include "mozilla/Assertions.h" #include "mozilla/Likely.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Util.h" +#include #include namespace mozilla { @@ -105,7 +106,7 @@ class BloomFilter */ public: BloomFilter() { - MOZ_STATIC_ASSERT(KeySize <= keyShift, "KeySize too big"); + static_assert(KeySize <= keyShift, "KeySize too big"); // Should we have a custom operator new using calloc instead and // require that we're allocated via the operator? @@ -231,4 +232,4 @@ BloomFilter::mightContain(const T* t) const } // namespace mozilla -#endif /* mozilla_BloomFilter_h_ */ +#endif /* mozilla_BloomFilter_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Casting.h b/external/spidermonkey/include/mac/mozilla/Casting.h index b1e81c33fa..76df0ef27e 100644 --- a/external/spidermonkey/include/mac/mozilla/Casting.h +++ b/external/spidermonkey/include/mac/mozilla/Casting.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cast operations to supplement the built-in casting operations. */ -#ifndef mozilla_Casting_h_ -#define mozilla_Casting_h_ +#ifndef mozilla_Casting_h +#define mozilla_Casting_h #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" @@ -15,6 +16,27 @@ namespace mozilla { +/** + * Return a value of type |To|, containing the underlying bit pattern of |from|. + * + * |To| and |From| must be types of the same size; be careful of cross-platform + * size differences, or this might fail to compile on some but not all + * platforms. + */ +template +inline To +BitwiseCast(const From from) +{ + static_assert(sizeof(From) == sizeof(To), + "To and From must have the same size"); + union { + From from; + To to; + } u; + u.from = from; + return u.to; +} + namespace detail { enum ToSignedness { ToIsSigned, ToIsUnsigned }; @@ -43,7 +65,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return from <= From(To(-1)); } }; @@ -52,7 +74,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -61,8 +83,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedUnsignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedUnsignedCheck::checkBounds(from); } }; @@ -72,7 +94,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (from < 0) return false; if (sizeof(To) >= sizeof(From)) @@ -93,7 +115,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -102,7 +124,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); return from <= From(MaxValue); } @@ -112,8 +134,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedSignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedSignedCheck::checkBounds(from); } }; @@ -123,7 +145,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (sizeof(From) <= sizeof(To)) return true; const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); @@ -141,15 +163,15 @@ template class BoundsChecker { public: - static bool check(const From from) { return true; } + static bool checkBounds(const From from) { return true; } }; template class BoundsChecker { public: - static bool check(const From from) { - return BoundsCheckImpl::check(from); + static bool checkBounds(const From from) { + return BoundsCheckImpl::checkBounds(from); } }; @@ -157,7 +179,7 @@ template inline bool IsInBounds(const From from) { - return BoundsChecker::check(from); + return BoundsChecker::checkBounds(from); } } // namespace detail @@ -177,4 +199,4 @@ SafeCast(const From from) } // namespace mozilla -#endif /* mozilla_Casting_h_ */ +#endif /* mozilla_Casting_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Char16.h b/external/spidermonkey/include/mac/mozilla/Char16.h index c6f9f87d44..e4b184f950 100644 --- a/external/spidermonkey/include/mac/mozilla/Char16.h +++ b/external/spidermonkey/include/mac/mozilla/Char16.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implements a UTF-16 character type. */ -#ifndef mozilla_Char16_h_ -#define mozilla_Char16_h_ +#ifndef mozilla_Char16_h +#define mozilla_Char16_h #include "mozilla/Assertions.h" @@ -49,8 +50,8 @@ */ #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s) -MOZ_STATIC_ASSERT(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); +static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); +static_assert(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); +static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); -#endif /* mozilla_Char16_h_ */ +#endif /* mozilla_Char16_h */ diff --git a/external/spidermonkey/include/mac/mozilla/CheckedInt.h b/external/spidermonkey/include/mac/mozilla/CheckedInt.h index 1dc80b032b..050cef8ed8 100644 --- a/external/spidermonkey/include/mac/mozilla/CheckedInt.h +++ b/external/spidermonkey/include/mac/mozilla/CheckedInt.h @@ -1,23 +1,23 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Provides checked integers, detecting integer overflow and divide-by-0. */ -#ifndef mozilla_CheckedInt_h_ -#define mozilla_CheckedInt_h_ +#ifndef mozilla_CheckedInt_h +#define mozilla_CheckedInt_h // Enable relying of Mozilla's MFBT for possibly-available C++11 features #define MOZ_CHECKEDINT_USE_MFBT +#include + #ifdef MOZ_CHECKEDINT_USE_MFBT # include "mozilla/Assertions.h" -# include "mozilla/StandardInteger.h" #else # include -# include -# define MOZ_STATIC_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_DELETE #endif @@ -450,6 +450,44 @@ IsDivValid(T x, T y) !(IsSigned::value && x == MinValue::value && y == T(-1)); } +template::value> +struct IsModValidImpl; + +template +inline bool +IsModValid(T x, T y) +{ + return IsModValidImpl::run(x, y); +} + +/* + * Mod is pretty simple. + * For now, let's just use the ANSI C definition: + * If x or y are negative, the results are implementation defined. + * Consider these invalid. + * Undefined for y=0. + * The result will never exceed either x or y. + * + * Checking that x>=0 is a warning when T is unsigned. + */ + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + return y >= 1; + } +}; + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + if (x < 0) + return false; + + return y >= 1; + } +}; + template::value> struct NegateImpl; @@ -528,7 +566,7 @@ struct NegateImpl CheckedInt x(-1); // 1000 is of type int16_t, is found not to be in range for int8_t, // x is invalid - CheckedInt x(int16_t(1000)); + CheckedInt x(int16_t(1000)); // 3123456789 is of type uint32_t, is found not to be in range for int32_t, // x is invalid CheckedInt x(uint32_t(3123456789)); @@ -561,12 +599,12 @@ class CheckedInt template CheckedInt(U value, bool isValid) : mValue(value), mIsValid(isValid) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); } - friend class detail::NegateImpl; + friend struct detail::NegateImpl; public: /** @@ -585,16 +623,27 @@ class CheckedInt : mValue(T(value)), mIsValid(detail::IsInRange(value)) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } + + template + friend class CheckedInt; + + template + CheckedInt toChecked() const + { + CheckedInt ret(mValue); + ret.mIsValid = ret.mIsValid && mIsValid; + return ret; } /** Constructs a valid checked integer with initial value 0 */ CheckedInt() : mValue(0), mIsValid(true) { - MOZ_STATIC_ASSERT(detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value, + "This type is not supported by CheckedInt"); } /** @returns the actual value */ @@ -619,22 +668,31 @@ class CheckedInt const CheckedInt& rhs); template CheckedInt& operator +=(U rhs); + template friend CheckedInt operator -(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator -=(U rhs); + template friend CheckedInt operator *(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator *=(U rhs); + template friend CheckedInt operator /(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator /=(U rhs); + template + friend CheckedInt operator %(const CheckedInt& lhs, + const CheckedInt& rhs); + template + CheckedInt& operator %=(U rhs); + CheckedInt operator -() const { return detail::NegateImpl::negate(*this); @@ -726,6 +784,7 @@ MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) +MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) #undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR @@ -757,9 +816,9 @@ template inline typename detail::CastToCheckedIntImpl::ReturnType castToCheckedInt(U u) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); return detail::CastToCheckedIntImpl::run(u); } @@ -786,6 +845,7 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) +MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) #undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS @@ -815,4 +875,4 @@ typedef CheckedInt CheckedUint64; } // namespace mozilla -#endif /* mozilla_CheckedInt_h_ */ +#endif /* mozilla_CheckedInt_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Compiler.h b/external/spidermonkey/include/mac/mozilla/Compiler.h index 58239b0e30..d1ef1e79aa 100644 --- a/external/spidermonkey/include/mac/mozilla/Compiler.h +++ b/external/spidermonkey/include/mac/mozilla/Compiler.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various compiler checks. */ -#ifndef mozilla_Compiler_h_ -#define mozilla_Compiler_h_ +#ifndef mozilla_Compiler_h +#define mozilla_Compiler_h #if !defined(__clang__) && defined(__GNUC__) @@ -28,4 +29,4 @@ #endif -#endif /* mozilla_Compiler_h_ */ +#endif /* mozilla_Compiler_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Constants.h b/external/spidermonkey/include/mac/mozilla/Constants.h index 904b30145a..86bbb6b354 100644 --- a/external/spidermonkey/include/mac/mozilla/Constants.h +++ b/external/spidermonkey/include/mac/mozilla/Constants.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt math constants. */ -#ifndef mozilla_Constants_h_ -#define mozilla_Constants_h_ +#ifndef mozilla_Constants_h +#define mozilla_Constants_h #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -#endif /* mozilla_Constants_h_ */ +#endif /* mozilla_Constants_h */ diff --git a/external/spidermonkey/include/mac/mozilla/DebugOnly.h b/external/spidermonkey/include/mac/mozilla/DebugOnly.h index 1f78ed7989..e5f0d729b5 100644 --- a/external/spidermonkey/include/mac/mozilla/DebugOnly.h +++ b/external/spidermonkey/include/mac/mozilla/DebugOnly.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * assertions). */ -#ifndef mozilla_DebugOnly_h_ -#define mozilla_DebugOnly_h_ +#ifndef mozilla_DebugOnly_h +#define mozilla_DebugOnly_h namespace mozilla { @@ -74,4 +75,4 @@ class DebugOnly } -#endif /* mozilla_DebugOnly_h_ */ +#endif /* mozilla_DebugOnly_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Decimal.h b/external/spidermonkey/include/mac/mozilla/Decimal.h index 8032fd6e23..3c67d784c9 100644 --- a/external/spidermonkey/include/mac/mozilla/Decimal.h +++ b/external/spidermonkey/include/mac/mozilla/Decimal.h @@ -38,7 +38,7 @@ #define Decimal_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" +#include #include "mozilla/Types.h" #include diff --git a/external/spidermonkey/include/mac/mozilla/Endian.h b/external/spidermonkey/include/mac/mozilla/Endian.h index 5d2f905b41..dc6d11d3ba 100644 --- a/external/spidermonkey/include/mac/mozilla/Endian.h +++ b/external/spidermonkey/include/mac/mozilla/Endian.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -59,16 +60,16 @@ * }; */ -#ifndef mozilla_Endian_h_ -#define mozilla_Endian_h_ +#ifndef mozilla_Endian_h +#define mozilla_Endian_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/DebugOnly.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" +#include #include #if defined(_MSC_VER) && _MSC_VER >= 1300 @@ -636,4 +637,4 @@ class NativeEndian MOZ_FINAL : public detail::Endian } /* namespace mozilla */ -#endif /* mozilla_Endian_h_ */ +#endif /* mozilla_Endian_h */ diff --git a/external/spidermonkey/include/mac/mozilla/EnumSet.h b/external/spidermonkey/include/mac/mozilla/EnumSet.h index b18b005669..95c5608cf4 100644 --- a/external/spidermonkey/include/mac/mozilla/EnumSet.h +++ b/external/spidermonkey/include/mac/mozilla/EnumSet.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,7 +10,8 @@ #define mozilla_EnumSet_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" + +#include namespace mozilla { @@ -172,4 +174,4 @@ class EnumSet } // namespace mozilla -#endif // mozilla_EnumSet_h_ +#endif /* mozilla_EnumSet_h_*/ diff --git a/external/spidermonkey/include/mac/mozilla/FloatingPoint.h b/external/spidermonkey/include/mac/mozilla/FloatingPoint.h index 30af2217b1..d80f6a7234 100644 --- a/external/spidermonkey/include/mac/mozilla/FloatingPoint.h +++ b/external/spidermonkey/include/mac/mozilla/FloatingPoint.h @@ -1,16 +1,19 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various predicates and operations on IEEE-754 floating point types. */ -#ifndef mozilla_FloatingPoint_h_ -#define mozilla_FloatingPoint_h_ +#ifndef mozilla_FloatingPoint_h +#define mozilla_FloatingPoint_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" +#include "mozilla/Casting.h" + +#include namespace mozilla { @@ -35,80 +38,58 @@ namespace mozilla { * the case. But we required this in implementations of these algorithms that * preceded this header, so we shouldn't break anything if we continue doing so. */ -MOZ_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); +static_assert(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); const unsigned DoubleExponentBias = 1023; const unsigned DoubleExponentShift = 52; -namespace detail { - const uint64_t DoubleSignBit = 0x8000000000000000ULL; const uint64_t DoubleExponentBits = 0x7ff0000000000000ULL; const uint64_t DoubleSignificandBits = 0x000fffffffffffffULL; -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleExponentBits) == 0, - "sign bit doesn't overlap exponent bits"); -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleSignificandBits) == 0, - "sign bit doesn't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleExponentBits & DoubleSignificandBits) == 0, - "exponent bits don't overlap significand bits"); +static_assert((DoubleSignBit & DoubleExponentBits) == 0, + "sign bit doesn't overlap exponent bits"); +static_assert((DoubleSignBit & DoubleSignificandBits) == 0, + "sign bit doesn't overlap significand bits"); +static_assert((DoubleExponentBits & DoubleSignificandBits) == 0, + "exponent bits don't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == - ~uint64_t(0), - "all bits accounted for"); - -union DoublePun -{ - /* - * Every way to pun the bits of a double introduces an additional layer of - * complexity, across a multitude of platforms, architectures, and ABIs. - * Use *only* uint64_t to reduce complexity. Don't add new punning here - * without discussion! - */ - uint64_t u; - double d; -}; - -} /* namespace detail */ +static_assert((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == + ~uint64_t(0), + "all bits accounted for"); /** Determines whether a double is NaN. */ static MOZ_ALWAYS_INLINE bool IsNaN(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * A double is NaN if all exponent bits are 1 and the significand contains at * least one non-zero bit. */ - return (pun.u & detail::DoubleExponentBits) == detail::DoubleExponentBits && - (pun.u & detail::DoubleSignificandBits) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) == DoubleExponentBits && + (bits & DoubleSignificandBits) != 0; } /** Determines whether a double is +Infinity or -Infinity. */ static MOZ_ALWAYS_INLINE bool IsInfinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - return (pun.u & ~detail::DoubleSignBit) == detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & ~DoubleSignBit) == DoubleExponentBits; } /** Determines whether a double is not NaN or infinite. */ static MOZ_ALWAYS_INLINE bool IsFinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * NaN and Infinities are the only non-finite doubles, and both have all * exponent bits set to 1. */ - return (pun.u & detail::DoubleExponentBits) != detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) != DoubleExponentBits; } /** @@ -120,36 +101,30 @@ IsNegative(double d) { MOZ_ASSERT(!IsNaN(d), "NaN does not have a sign"); - union detail::DoublePun pun; - pun.d = d; - /* The sign bit is set if the double is negative. */ - return (pun.u & detail::DoubleSignBit) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleSignBit) != 0; } /** Determines whether a double represents -0. */ static MOZ_ALWAYS_INLINE bool IsNegativeZero(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Only the sign bit is set if the double is -0. */ - return pun.u == detail::DoubleSignBit; + uint64_t bits = BitwiseCast(d); + return bits == DoubleSignBit; } /** Returns the exponent portion of the double. */ static MOZ_ALWAYS_INLINE int_fast16_t ExponentComponent(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * The exponent component of a double is an unsigned number, biased from its * actual value. Subtract the bias to retrieve the actual exponent. */ - return int_fast16_t((pun.u & detail::DoubleExponentBits) >> DoubleExponentShift) - + uint64_t bits = BitwiseCast(d); + return int_fast16_t((bits & DoubleExponentBits) >> DoubleExponentShift) - int_fast16_t(DoubleExponentBias); } @@ -157,28 +132,22 @@ ExponentComponent(double d) static MOZ_ALWAYS_INLINE double PositiveInfinity() { - union detail::DoublePun pun; - /* * Positive infinity has all exponent bits set, sign bit set to 0, and no * significand. */ - pun.u = detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleExponentBits); } /** Returns -Infinity. */ static MOZ_ALWAYS_INLINE double NegativeInfinity() { - union detail::DoublePun pun; - /* * Negative infinity has all exponent bits set, sign bit set to 1, and no * significand. */ - pun.u = detail::DoubleSignBit | detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleSignBit | DoubleExponentBits); } /** Constructs a NaN value with the specified sign bit and significand bits. */ @@ -186,24 +155,21 @@ static MOZ_ALWAYS_INLINE double SpecificNaN(int signbit, uint64_t significand) { MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~detail::DoubleSignificandBits) == 0); - MOZ_ASSERT(significand & detail::DoubleSignificandBits); + MOZ_ASSERT((significand & ~DoubleSignificandBits) == 0); + MOZ_ASSERT(significand & DoubleSignificandBits); - union detail::DoublePun pun; - pun.u = (signbit ? detail::DoubleSignBit : 0) | - detail::DoubleExponentBits | - significand; - MOZ_ASSERT(IsNaN(pun.d)); - return pun.d; + double d = BitwiseCast((signbit ? DoubleSignBit : 0) | + DoubleExponentBits | + significand); + MOZ_ASSERT(IsNaN(d)); + return d; } /** Computes the smallest non-zero positive double value. */ static MOZ_ALWAYS_INLINE double MinDoubleValue() { - union detail::DoublePun pun; - pun.u = 1; - return pun.d; + return BitwiseCast(uint64_t(1)); } static MOZ_ALWAYS_INLINE bool @@ -224,9 +190,22 @@ DoubleIsInt32(double d, int32_t* i) static MOZ_ALWAYS_INLINE double UnspecifiedNaN() { - return mozilla::SpecificNaN(0, 0xfffffffffffffULL); + return SpecificNaN(0, 0xfffffffffffffULL); +} + +/** + * Compare two doubles for equality, *without* equating -0 to +0, and equating + * any NaN value to any other NaN value. (The normal equality operators equate + * -0 with +0, and they equate NaN to no other value.) + */ +static inline bool +DoublesAreIdentical(double d1, double d2) +{ + if (IsNaN(d1)) + return IsNaN(d2); + return BitwiseCast(d1) == BitwiseCast(d2); } } /* namespace mozilla */ -#endif /* mozilla_FloatingPoint_h_ */ +#endif /* mozilla_FloatingPoint_h */ diff --git a/external/spidermonkey/include/mac/mozilla/GuardObjects.h b/external/spidermonkey/include/mac/mozilla/GuardObjects.h index 6c2058938c..aeae7dcbc0 100644 --- a/external/spidermonkey/include/mac/mozilla/GuardObjects.h +++ b/external/spidermonkey/include/mac/mozilla/GuardObjects.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,6 +10,7 @@ #define mozilla_GuardObjects_h #include "mozilla/Assertions.h" +#include "mozilla/NullPtr.h" #include "mozilla/Types.h" #ifdef __cplusplus @@ -72,7 +74,7 @@ class MOZ_EXPORT GuardObjectNotifier bool* statementDone; public: - GuardObjectNotifier() : statementDone(NULL) { } + GuardObjectNotifier() : statementDone(nullptr) { } ~GuardObjectNotifier() { *statementDone = true; diff --git a/external/spidermonkey/include/mac/mozilla/HashFunctions.h b/external/spidermonkey/include/mac/mozilla/HashFunctions.h index 96242b629a..6d0d24e7b1 100644 --- a/external/spidermonkey/include/mac/mozilla/HashFunctions.h +++ b/external/spidermonkey/include/mac/mozilla/HashFunctions.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Utilities for hashing. */ @@ -39,17 +40,18 @@ * }; * * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKey.h. + * in nsHashKeys.h. */ -#ifndef mozilla_HashFunctions_h_ -#define mozilla_HashFunctions_h_ +#ifndef mozilla_HashFunctions_h +#define mozilla_HashFunctions_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + #ifdef __cplusplus namespace mozilla { @@ -173,8 +175,8 @@ AddToHash(uint32_t hash, A* a) * catch data pointers and couldn't handle function pointers. */ - MOZ_STATIC_ASSERT(sizeof(a) == sizeof(uintptr_t), - "Strange pointer!"); + static_assert(sizeof(a) == sizeof(uintptr_t), + "Strange pointer!"); return detail::AddUintptrToHash(hash, uintptr_t(a)); } @@ -356,4 +358,5 @@ HashBytes(const void* bytes, size_t length); } /* namespace mozilla */ #endif /* __cplusplus */ -#endif /* mozilla_HashFunctions_h_ */ + +#endif /* mozilla_HashFunctions_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Likely.h b/external/spidermonkey/include/mac/mozilla/Likely.h index 6412b4943b..4f21609295 100644 --- a/external/spidermonkey/include/mac/mozilla/Likely.h +++ b/external/spidermonkey/include/mac/mozilla/Likely.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a * boolean predicate should be branch-predicted. */ -#ifndef mozilla_Likely_h_ -#define mozilla_Likely_h_ +#ifndef mozilla_Likely_h +#define mozilla_Likely_h #if defined(__clang__) || defined(__GNUC__) # define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) @@ -19,4 +20,4 @@ # define MOZ_UNLIKELY(x) (!!(x)) #endif -#endif /* mozilla_Likely_h_ */ +#endif /* mozilla_Likely_h */ diff --git a/external/spidermonkey/include/mac/mozilla/LinkedList.h b/external/spidermonkey/include/mac/mozilla/LinkedList.h index 5cfd60e4ac..c29760b3e7 100644 --- a/external/spidermonkey/include/mac/mozilla/LinkedList.h +++ b/external/spidermonkey/include/mac/mozilla/LinkedList.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -45,18 +46,19 @@ * } * * void notifyObservers(char* topic) { - * for (Observer* o = list.getFirst(); o != NULL; o = o->getNext()) - * o->Observe(topic); + * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) + * o->observe(topic); * } * }; * */ -#ifndef mozilla_LinkedList_h_ -#define mozilla_LinkedList_h_ +#ifndef mozilla_LinkedList_h +#define mozilla_LinkedList_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #ifdef __cplusplus @@ -69,10 +71,10 @@ template class LinkedListElement { /* - * It's convenient that we return NULL when getNext() or getPrevious() hits - * the end of the list, but doing so costs an extra word of storage in each - * linked list node (to keep track of whether |this| is the sentinel node) - * and a branch on this value in getNext/getPrevious. + * It's convenient that we return nullptr when getNext() or getPrevious() + * hits the end of the list, but doing so costs an extra word of storage in + * each linked list node (to keep track of whether |this| is the sentinel + * node) and a branch on this value in getNext/getPrevious. * * We could get rid of the extra word of storage by shoving the "is * sentinel" bit into one of the pointers, although this would, of course, @@ -107,12 +109,10 @@ class LinkedListElement LinkedListElement* prev; const bool isSentinel; - LinkedListElement* thisDuringConstruction() { return this; } - public: LinkedListElement() - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(false) { } @@ -122,8 +122,8 @@ class LinkedListElement } /* - * Get the next element in the list, or NULL if this is the last element in - * the list. + * Get the next element in the list, or nullptr if this is the last element + * in the list. */ T* getNext() { return next->asT(); @@ -133,8 +133,8 @@ class LinkedListElement } /* - * Get the previous element in the list, or NULL if this is the first element - * in the list. + * Get the previous element in the list, or nullptr if this is the first + * element in the list. */ T* getPrevious() { return prev->asT(); @@ -201,24 +201,24 @@ class LinkedListElement }; LinkedListElement(NodeKind nodeKind) - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(nodeKind == NODE_KIND_SENTINEL) { } /* - * Return |this| cast to T* if we're a normal node, or return NULL if we're - * a sentinel node. + * Return |this| cast to T* if we're a normal node, or return nullptr if + * we're a sentinel node. */ T* asT() { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } const T* asT() const { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } @@ -285,7 +285,7 @@ class LinkedList } /* - * Get the first element of the list, or NULL if the list is empty. + * Get the first element of the list, or nullptr if the list is empty. */ T* getFirst() { return sentinel.getNext(); @@ -295,7 +295,7 @@ class LinkedList } /* - * Get the last element of the list, or NULL if the list is empty. + * Get the last element of the list, or nullptr if the list is empty. */ T* getLast() { return sentinel.getPrevious(); @@ -306,7 +306,7 @@ class LinkedList /* * Get and remove the first element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popFirst() { T* ret = sentinel.getNext(); @@ -317,7 +317,7 @@ class LinkedList /* * Get and remove the last element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popLast() { T* ret = sentinel.getPrevious(); @@ -415,7 +415,7 @@ class LinkedList if (elem == t) return; } - MOZ_NOT_REACHED("element wasn't found in this list!"); + MOZ_CRASH("element wasn't found in this list!"); #endif } @@ -425,5 +425,6 @@ class LinkedList } /* namespace mozilla */ -#endif /* ifdef __cplusplus */ -#endif /* ifdef mozilla_LinkedList_h_ */ +#endif /* __cplusplus */ + +#endif /* mozilla_LinkedList_h */ diff --git a/external/spidermonkey/include/mac/mozilla/MSStdInt.h b/external/spidermonkey/include/mac/mozilla/MSStdInt.h deleted file mode 100644 index 0447f2f11b..0000000000 --- a/external/spidermonkey/include/mac/mozilla/MSStdInt.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// 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. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/external/spidermonkey/include/mac/mozilla/MathAlgorithms.h b/external/spidermonkey/include/mac/mozilla/MathAlgorithms.h index 0a47810553..6d58691e06 100644 --- a/external/spidermonkey/include/mac/mozilla/MathAlgorithms.h +++ b/external/spidermonkey/include/mac/mozilla/MathAlgorithms.h @@ -1,19 +1,20 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt maths algorithms. */ -#ifndef mozilla_MathAlgorithms_h_ -#define mozilla_MathAlgorithms_h_ +#ifndef mozilla_MathAlgorithms_h +#define mozilla_MathAlgorithms_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" #include #include +#include namespace mozilla { @@ -142,6 +143,288 @@ Abs(const long double d) return std::fabs(d); } +} // namespace mozilla + +#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define MOZ_BITSCAN_WINDOWS + + extern "C" { + unsigned char _BitScanForward(unsigned long* Index, unsigned long mask); + unsigned char _BitScanReverse(unsigned long* Index, unsigned long mask); +# pragma intrinsic(_BitScanForward, _BitScanReverse) + +# if defined(_M_AMD64) || defined(_M_X64) +# define MOZ_BITSCAN_WINDOWS64 + unsigned char _BitScanForward64(unsigned long* index, unsigned __int64 mask); + unsigned char _BitScanReverse64(unsigned long* index, unsigned __int64 mask); +# pragma intrinsic(_BitScanForward64, _BitScanReverse64) +# endif + } // extern "C" + +#endif + +namespace mozilla { + +namespace detail { + +#if defined(MOZ_BITSCAN_WINDOWS) + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanReverse(&index, static_cast(u)); + return uint_fast8_t(31 - index); + } + + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanForward(&index, static_cast(u)); + return uint_fast8_t(index); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanReverse64(&index, static_cast(u)); + return uint_fast8_t(63 - index); +# else + uint32_t hi = uint32_t(u >> 32); + if (hi != 0) + return CountLeadingZeroes32(hi); + return 32 + CountLeadingZeroes32(uint32_t(u)); +# endif + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanForward64(&index, static_cast(u)); + return uint_fast8_t(index); +# else + uint32_t lo = uint32_t(u); + if (lo != 0) + return CountTrailingZeroes32(lo); + return 32 + CountTrailingZeroes32(uint32_t(u >> 32)); +# endif + } + +# ifdef MOZ_HAVE_BITSCAN64 +# undef MOZ_HAVE_BITSCAN64 +# endif + +#elif defined(__clang__) || defined(__GNUC__) + +# if defined(__clang__) +# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) +# error "A clang providing __builtin_c[lt]z is required to build" +# endif +# else + // gcc has had __builtin_clz and friends since 3.4: no need to check. +# endif + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + return __builtin_clz(u); + } + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + return __builtin_ctz(u); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { + return __builtin_clzll(u); + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { + return __builtin_ctzll(u); + } + +#else +# error "Implement these!" + inline uint_fast8_t CountLeadingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountLeadingZeroes64(uint64_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes64(uint64_t u) MOZ_DELETE; +#endif + +} // namespace detail + +/** + * Compute the number of high-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the highest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountLeadingZeroes32(0xF0FF1000) is 0; + * CountLeadingZeroes32(0x7F8F0001) is 1; + * CountLeadingZeroes32(0x3FFF0100) is 2; + * CountLeadingZeroes32(0x1FF50010) is 3; and so on. + */ +inline uint_fast8_t +CountLeadingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes32(u); +} + +/** + * Compute the number of low-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the lowest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountTrailingZeroes32(0x0100FFFF) is 0; + * CountTrailingZeroes32(0x7000FFFE) is 1; + * CountTrailingZeroes32(0x0080FFFC) is 2; + * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. + */ +inline uint_fast8_t +CountTrailingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes32(u); +} + +/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountLeadingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes64(u); +} + +/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountTrailingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes64(u); +} + +namespace detail { + +template +class CeilingLog2; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 32 - CountLeadingZeroes32(t - 1); + } +}; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 64 - CountLeadingZeroes64(t - 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the least power of 2 greater than or equal to |t|. + * + * CeilingLog2(0..1) is 0; + * CeilingLog2(2) is 1; + * CeilingLog2(3..4) is 2; + * CeilingLog2(5..8) is 3; + * CeilingLog2(9..16) is 4; and so on. + */ +template +inline uint_fast8_t +CeilingLog2(const T t) +{ + return detail::CeilingLog2::compute(t); +} + +/** A CeilingLog2 variant that accepts only size_t. */ +inline uint_fast8_t +CeilingLog2Size(size_t n) +{ + return CeilingLog2(n); +} + +namespace detail { + +template +class FloorLog2; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 31 - CountLeadingZeroes32(t | 1); + } +}; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 63 - CountLeadingZeroes64(t | 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the greatest power of 2 less than or equal to |t|. + * + * FloorLog2(0..1) is 0; + * FloorLog2(2..3) is 1; + * FloorLog2(4..7) is 2; + * FloorLog2(8..15) is 3; and so on. + */ +template +inline uint_fast8_t +FloorLog2(const T t) +{ + return detail::FloorLog2::compute(t); +} + +/** A FloorLog2 variant that accepts only size_t. */ +inline uint_fast8_t +FloorLog2Size(size_t n) +{ + return FloorLog2(n); +} + +/* + * Compute the smallest power of 2 greater than or equal to |x|. |x| must not + * be so great that the computed value would overflow |size_t|. + */ +inline size_t +RoundUpPow2(size_t x) +{ + MOZ_ASSERT(x <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), + "can't round up -- will overflow!"); + return size_t(1) << CeilingLog2(x); +} + } /* namespace mozilla */ -#endif /* mozilla_MathAlgorithms_h_ */ +#endif /* mozilla_MathAlgorithms_h */ diff --git a/external/spidermonkey/include/mac/mozilla/MemoryChecking.h b/external/spidermonkey/include/mac/mozilla/MemoryChecking.h index 3287e57ba1..2130990c6b 100644 --- a/external/spidermonkey/include/mac/mozilla/MemoryChecking.h +++ b/external/spidermonkey/include/mac/mozilla/MemoryChecking.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -19,8 +20,8 @@ * With no memory checker available, all macros expand to the empty statement. */ -#ifndef mozilla_MemoryChecking_h_ -#define mozilla_MemoryChecking_h_ +#ifndef mozilla_MemoryChecking_h +#define mozilla_MemoryChecking_h #if defined(MOZ_VALGRIND) #include "valgrind/memcheck.h" @@ -68,4 +69,4 @@ extern "C" { #endif -#endif /* mozilla_MemoryChecking_h_ */ +#endif /* mozilla_MemoryChecking_h */ diff --git a/external/spidermonkey/include/mac/mozilla/MemoryReporting.h b/external/spidermonkey/include/mac/mozilla/MemoryReporting.h new file mode 100644 index 0000000000..d2340ecf09 --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/MemoryReporting.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Memory reporting infrastructure. */ + +#ifndef mozilla_MemoryReporting_h +#define mozilla_MemoryReporting_h + +#include + +#ifdef __cplusplus + +namespace mozilla { + +/* + * This is for functions that are like malloc_usable_size. Such functions are + * used for measuring the size of data structures. + */ +typedef size_t (*MallocSizeOf)(const void* p); + +} /* namespace mozilla */ + +#endif /* __cplusplus */ + +typedef size_t (*MozMallocSizeOf)(const void* p); + +#endif /* mozilla_MemoryReporting_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Move.h b/external/spidermonkey/include/mac/mozilla/Move.h new file mode 100644 index 0000000000..97178daaa6 --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/Move.h @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* C++11-style, but C++98-usable, "move references" implementation. */ + +#ifndef mozilla_Move_h +#define mozilla_Move_h + +namespace mozilla { + +/* + * "Move" References + * + * Some types can be copied much more efficiently if we know the original's + * value need not be preserved --- that is, if we are doing a "move", not a + * "copy". For example, if we have: + * + * Vector u; + * Vector v(u); + * + * the constructor for v must apply a copy constructor to each element of u --- + * taking time linear in the length of u. However, if we know we will not need u + * any more once v has been initialized, then we could initialize v very + * efficiently simply by stealing u's dynamically allocated buffer and giving it + * to v --- a constant-time operation, regardless of the size of u. + * + * Moves often appear in container implementations. For example, when we append + * to a vector, we may need to resize its buffer. This entails moving each of + * its extant elements from the old, smaller buffer to the new, larger buffer. + * But once the elements have been migrated, we're just going to throw away the + * old buffer; we don't care if they still have their values. So if the vector's + * element type can implement "move" more efficiently than "copy", the vector + * resizing should by all means use a "move" operation. Hash tables also need to + * be resized. + * + * The details of the optimization, and whether it's worth applying, vary from + * one type to the next. And while some constructor calls are moves, many really + * are copies, and can't be optimized this way. So we need: + * + * 1) a way for a particular invocation of a copy constructor to say that it's + * really a move, and that the value of the original isn't important + * afterwards (although it must still be safe to destroy); and + * + * 2) a way for a type (like Vector) to announce that it can be moved more + * efficiently than it can be copied, and provide an implementation of that + * move operation. + * + * The Move(T&) function takes a reference to a T, and returns a MoveRef + * referring to the same value; that's 1). A MoveRef is simply a reference + * to a T, annotated to say that a copy constructor applied to it may move that + * T, instead of copying it. Finally, a constructor that accepts an MoveRef + * should perform a more efficient move, instead of a copy, providing 2). + * + * So, where we might define a copy constructor for a class C like this: + * + * C(const C& rhs) { ... copy rhs to this ... } + * + * we would declare a move constructor like this: + * + * C(MoveRef rhs) { ... move rhs to this ... } + * + * And where we might perform a copy like this: + * + * C c2(c1); + * + * we would perform a move like this: + * + * C c2(Move(c1)) + * + * Note that MoveRef implicitly converts to T&, so you can pass a MoveRef + * to an ordinary copy constructor for a type that doesn't support a special + * move constructor, and you'll just get a copy. This means that templates can + * use Move whenever they know they won't use the original value any more, even + * if they're not sure whether the type at hand has a specialized move + * constructor. If it doesn't, the MoveRef will just convert to a T&, and + * the ordinary copy constructor will apply. + * + * A class with a move constructor can also provide a move assignment operator, + * which runs this's destructor, and then applies the move constructor to + * *this's memory. A typical definition: + * + * C& operator=(MoveRef rhs) { + * this->~C(); + * new(this) C(rhs); + * return *this; + * } + * + * With that in place, one can write move assignments like this: + * + * c2 = Move(c1); + * + * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but + * destructible state. + * + * This header file defines MoveRef and Move in the mozilla namespace. It's up + * to individual containers to annotate moves as such, by calling Move; and it's + * up to individual types to define move constructors. + * + * One hint: if you're writing a move constructor where the type has members + * that should be moved themselves, it's much nicer to write this: + * + * C(MoveRef c) : x(Move(c->x)), y(Move(c->y)) { } + * + * than the equivalent: + * + * C(MoveRef c) { new(&x) X(Move(c->x)); new(&y) Y(Move(c->y)); } + * + * especially since GNU C++ fails to notice that this does indeed initialize x + * and y, which may matter if they're const. + */ +template +class MoveRef +{ + T* pointer; + + public: + explicit MoveRef(T& t) : pointer(&t) { } + T& operator*() const { return *pointer; } + T* operator->() const { return pointer; } + operator T& () const { return *pointer; } +}; + +template +inline MoveRef +Move(T& t) +{ + return MoveRef(t); +} + +template +inline MoveRef +Move(const T& t) +{ + // With some versions of gcc, for a class C, there's an (incorrect) ambiguity + // between the C(const C&) constructor and the default C(C&&) C++11 move + // constructor, when the constructor is called with a const C& argument. + // + // This ambiguity manifests with the Move implementation above when Move is + // passed const U& for some class U. Calling Move(const U&) returns a + // MoveRef, which is then commonly passed to the U constructor, + // triggering an implicit conversion to const U&. gcc doesn't know whether to + // call U(const U&) or U(U&&), so it wrongly reports a compile error. + // + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50442 has since been fixed, so + // this is no longer an issue for up-to-date compilers. But there's no harm + // in keeping it around for older compilers, so we might as well. See also + // bug 686280. + return MoveRef(const_cast(t)); +} + +/** Swap |t| and |u| using move-construction if possible. */ +template +inline void +Swap(T& t, T& u) +{ + T tmp(Move(t)); + t = Move(u); + u = Move(tmp); +} + +} // namespace mozilla + +#endif /* mozilla_Move_h */ diff --git a/external/spidermonkey/include/mac/mozilla/NullPtr.h b/external/spidermonkey/include/mac/mozilla/NullPtr.h index 7dcb03d734..14c0f07df2 100644 --- a/external/spidermonkey/include/mac/mozilla/NullPtr.h +++ b/external/spidermonkey/include/mac/mozilla/NullPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * constant. */ -#ifndef mozilla_NullPtr_h_ -#define mozilla_NullPtr_h_ +#ifndef mozilla_NullPtr_h +#define mozilla_NullPtr_h #include "mozilla/Compiler.h" @@ -45,4 +46,4 @@ # endif #endif -#endif /* mozilla_NullPtr_h_ */ +#endif /* mozilla_NullPtr_h */ diff --git a/external/spidermonkey/include/mac/mozilla/PodOperations.h b/external/spidermonkey/include/mac/mozilla/PodOperations.h index 6c6af27fc9..bec89fa928 100644 --- a/external/spidermonkey/include/mac/mozilla/PodOperations.h +++ b/external/spidermonkey/include/mac/mozilla/PodOperations.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -156,4 +157,4 @@ PodEqual(const T* one, const T* two, size_t len) } // namespace mozilla -#endif // mozilla_PodOperations_h_ +#endif /* mozilla_PodOperations_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Poison.h b/external/spidermonkey/include/mac/mozilla/Poison.h index c4adc23e71..75e0f081cd 100644 --- a/external/spidermonkey/include/mac/mozilla/Poison.h +++ b/external/spidermonkey/include/mac/mozilla/Poison.h @@ -9,13 +9,14 @@ * an address that leads to a safe crash when dereferenced. */ -#ifndef mozilla_Poison_h_ -#define mozilla_Poison_h_ +#ifndef mozilla_Poison_h +#define mozilla_Poison_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + MOZ_BEGIN_EXTERN_C extern MFBT_DATA uintptr_t gMozillaPoisonValue; @@ -36,11 +37,11 @@ inline uintptr_t mozPoisonValue() */ inline void mozWritePoison(void* aPtr, size_t aSize) { - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); const uintptr_t POISON = mozPoisonValue(); char* p = (char*)aPtr; char* limit = p + aSize; + MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); + MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); for (; p < limit; p += sizeof(uintptr_t)) { *((uintptr_t*)p) = POISON; } @@ -58,4 +59,4 @@ extern MFBT_DATA uintptr_t gMozillaPoisonSize; MOZ_END_EXTERN_C -#endif /* mozilla_Poison_h_ */ +#endif /* mozilla_Poison_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Range.h b/external/spidermonkey/include/mac/mozilla/Range.h index e14594d09d..4e02d962b5 100644 --- a/external/spidermonkey/include/mac/mozilla/Range.h +++ b/external/spidermonkey/include/mac/mozilla/Range.h @@ -1,12 +1,11 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef mozilla_Range_h_ -#define mozilla_Range_h_ +#ifndef mozilla_Range_h +#define mozilla_Range_h #include "mozilla/NullPtr.h" #include "mozilla/RangedPtr.h" @@ -40,10 +39,13 @@ class Range return mStart[offset]; } + const T& operator[](size_t offset) const { + return mStart[offset]; + } + operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; } }; } // namespace mozilla -#endif // mozilla_Range_h_ - +#endif /* mozilla_Range_h */ diff --git a/external/spidermonkey/include/mac/mozilla/RangedPtr.h b/external/spidermonkey/include/mac/mozilla/RangedPtr.h index 7ce19d071f..493fcdbaee 100644 --- a/external/spidermonkey/include/mac/mozilla/RangedPtr.h +++ b/external/spidermonkey/include/mac/mozilla/RangedPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,11 +9,12 @@ * construction. */ -#ifndef mozilla_RangedPtr_h_ -#define mozilla_RangedPtr_h_ +#ifndef mozilla_RangedPtr_h +#define mozilla_RangedPtr_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #include "mozilla/Util.h" namespace mozilla { @@ -59,7 +61,7 @@ class RangedPtr #ifdef DEBUG return RangedPtr(p, rangeStart, rangeEnd); #else - return RangedPtr(p, NULL, size_t(0)); + return RangedPtr(p, nullptr, size_t(0)); #endif } @@ -251,4 +253,4 @@ class RangedPtr } /* namespace mozilla */ -#endif /* mozilla_RangedPtr_h_ */ +#endif /* mozilla_RangedPtr_h */ diff --git a/external/spidermonkey/include/mac/mozilla/ReentrancyGuard.h b/external/spidermonkey/include/mac/mozilla/ReentrancyGuard.h new file mode 100644 index 0000000000..d589f368a2 --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/ReentrancyGuard.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Small helper class for asserting uses of a class are non-reentrant. */ + +#ifndef mozilla_ReentrancyGuard_h +#define mozilla_ReentrancyGuard_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/GuardObjects.h" + +namespace mozilla { + +/* Useful for implementing containers that assert non-reentrancy */ +class ReentrancyGuard +{ + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER +#ifdef DEBUG + bool& entered; +#endif + + public: + template +#ifdef DEBUG + ReentrancyGuard(T& obj + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : entered(obj.entered) +#else + ReentrancyGuard(T& + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) +#endif + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; +#ifdef DEBUG + MOZ_ASSERT(!entered); + entered = true; +#endif + } + ~ReentrancyGuard() + { +#ifdef DEBUG + entered = false; +#endif + } + + private: + ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE; + void operator=(const ReentrancyGuard&) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_ReentrancyGuard_h */ diff --git a/external/spidermonkey/include/mac/mozilla/RefPtr.h b/external/spidermonkey/include/mac/mozilla/RefPtr.h index 9f4163a21a..3c275afdc7 100644 --- a/external/spidermonkey/include/mac/mozilla/RefPtr.h +++ b/external/spidermonkey/include/mac/mozilla/RefPtr.h @@ -1,14 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Helpers for defining and using refcounted objects. */ -#ifndef mozilla_RefPtr_h_ -#define mozilla_RefPtr_h_ +#ifndef mozilla_RefPtr_h +#define mozilla_RefPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/TypeTraits.h" @@ -41,13 +43,19 @@ template OutParamRef byRef(RefPtr&); * state distinguishes use-before-ref (refcount==0) from * use-after-destroy (refcount==0xffffdead). */ -#ifdef DEBUG namespace detail { +#ifdef DEBUG static const int DEAD = 0xffffdead; -} #endif -template +// This is used WeakPtr.h as well as this file. +enum RefCountAtomicity +{ + AtomicRefCount, + NonAtomicRefCount +}; + +template class RefCounted { friend class RefPtr; @@ -56,8 +64,6 @@ class RefCounted RefCounted() : refCnt(0) { } ~RefCounted() { MOZ_ASSERT(refCnt == detail::DEAD); - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from RefCounted"); } public: @@ -87,7 +93,33 @@ class RefCounted } private: - int refCnt; + typename Conditional, int>::Type refCnt; +}; + +} + +template +class RefCounted : public detail::RefCounted +{ + public: + ~RefCounted() { + static_assert(IsBaseOf::value, + "T must derive from RefCounted"); + } +}; + +/** + * AtomicRefCounted is like RefCounted, with an atomically updated + * reference counter. + */ +template +class AtomicRefCounted : public detail::RefCounted +{ + public: + ~AtomicRefCounted() { + static_assert(IsBaseOf::value, + "T must derive from AtomicRefCounted"); + } }; /** @@ -259,9 +291,6 @@ byRef(RefPtr& ptr) } // namespace mozilla -#endif // mozilla_RefPtr_h_ - - #if 0 // Command line that builds these tests @@ -416,3 +445,5 @@ main(int argc, char** argv) } #endif + +#endif /* mozilla_RefPtr_h */ diff --git a/external/spidermonkey/include/mac/mozilla/SHA1.h b/external/spidermonkey/include/mac/mozilla/SHA1.h index a6604e699f..b167648540 100644 --- a/external/spidermonkey/include/mac/mozilla/SHA1.h +++ b/external/spidermonkey/include/mac/mozilla/SHA1.h @@ -1,17 +1,18 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Simple class for computing SHA1. */ -#ifndef mozilla_SHA1_h_ -#define mozilla_SHA1_h_ +#ifndef mozilla_SHA1_h +#define mozilla_SHA1_h -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" #include +#include namespace mozilla { @@ -58,4 +59,4 @@ class SHA1Sum } /* namespace mozilla */ -#endif /* mozilla_SHA1_h_ */ +#endif /* mozilla_SHA1_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Scoped.h b/external/spidermonkey/include/mac/mozilla/Scoped.h index 677a1a3797..fc48584b3e 100644 --- a/external/spidermonkey/include/mac/mozilla/Scoped.h +++ b/external/spidermonkey/include/mac/mozilla/Scoped.h @@ -1,11 +1,13 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* A number of structures to simplify scope-based RAII management. */ -#ifndef mozilla_Scoped_h_ -#define mozilla_Scoped_h_ +#ifndef mozilla_Scoped_h +#define mozilla_Scoped_h /* * Resource Acquisition Is Initialization is a programming idiom used @@ -52,6 +54,7 @@ #include "mozilla/Attributes.h" #include "mozilla/GuardObjects.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -193,7 +196,7 @@ template struct ScopedFreePtrTraits { typedef T* type; - static T* empty() { return NULL; } + static T* empty() { return nullptr; } static void release(T* ptr) { free(ptr); } }; SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits) @@ -256,7 +259,7 @@ template struct TypeSpecificScopedPointerTraits { typedef T* type; - const static type empty() { return NULL; } + const static type empty() { return nullptr; } const static void release(type value) { if (value) @@ -268,4 +271,4 @@ SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) } /* namespace mozilla */ -#endif // mozilla_Scoped_h_ +#endif /* mozilla_Scoped_h */ diff --git a/external/spidermonkey/include/mac/mozilla/SplayTree.h b/external/spidermonkey/include/mac/mozilla/SplayTree.h index f9a10d36dd..de0235aec9 100644 --- a/external/spidermonkey/include/mac/mozilla/SplayTree.h +++ b/external/spidermonkey/include/mac/mozilla/SplayTree.h @@ -1,7 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -10,8 +9,8 @@ * are faster to access again. */ -#ifndef mozilla_SplayTree_h_ -#define mozilla_SplayTree_h_ +#ifndef mozilla_SplayTree_h +#define mozilla_SplayTree_h #include "mozilla/Assertions.h" #include "mozilla/NullPtr.h" @@ -282,4 +281,4 @@ class SplayTree } /* namespace mozilla */ -#endif /* mozilla_SplayTree_h_ */ +#endif /* mozilla_SplayTree_h */ diff --git a/external/spidermonkey/include/mac/mozilla/StandardInteger.h b/external/spidermonkey/include/mac/mozilla/StandardInteger.h deleted file mode 100644 index 8e4c8578f1..0000000000 --- a/external/spidermonkey/include/mac/mozilla/StandardInteger.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implements the C99 interface for C and C++ code. */ - -#ifndef mozilla_StandardInteger_h_ -#define mozilla_StandardInteger_h_ - -/* - * The C99 standard header exposes typedefs for common fixed-width - * integer types. It would be feasible to simply #include , but - * MSVC++ versions prior to 2010 don't provide . We could solve this - * by reimplementing for MSVC++ 2008 and earlier. But then we reach - * a second problem: our custom might conflict with a - * defined by an embedder already looking to work around the MSVC++ - * absence. - * - * We address these issues in this manner: - * - * 1. If the preprocessor macro MOZ_CUSTOM_STDINT_H is defined to a path to a - * custom implementation, we will #include it. Embedders using - * a custom must define this macro to an implementation that - * will work with their embedding. - * 2. Otherwise, if we are compiling with a an MSVC++ version without - * , #include our custom reimplementation. - * 3. Otherwise, #include the standard provided by the compiler. - * - * Note that we can't call this file "stdint.h" or something case-insensitively - * equal to "stdint.h" because then MSVC (and other compilers on - * case-insensitive file systems) will include this file, rather than the system - * stdint.h, when we ask for below. - */ -#if defined(MOZ_CUSTOM_STDINT_H) -# include MOZ_CUSTOM_STDINT_H -#elif defined(_MSC_VER) && _MSC_VER < 1600 -# include "mozilla/MSStdInt.h" -#else -# include -#endif - -#endif /* mozilla_StandardInteger_h_ */ diff --git a/external/spidermonkey/include/mac/mozilla/TemplateLib.h b/external/spidermonkey/include/mac/mozilla/TemplateLib.h new file mode 100644 index 0000000000..50275fdadb --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/TemplateLib.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Reusable template meta-functions on types and compile-time values. Meta- + * functions are placed inside the 'tl' namespace to avoid conflict with non- + * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. + * mozilla::FloorLog2). + * + * When constexpr support becomes universal, we should probably use that instead + * of some of these templates, for simplicity. + */ + +#ifndef mozilla_TemplateLib_h +#define mozilla_TemplateLib_h + +#include +#include + +namespace mozilla { + +namespace tl { + +/** Compute min/max. */ +template +struct Min +{ + static const size_t value = I < J ? I : J; +}; +template +struct Max +{ + static const size_t value = I > J ? I : J; +}; + +/** Compute floor(log2(i)). */ +template +struct FloorLog2 +{ + static const size_t value = 1 + FloorLog2::value; +}; +template<> struct FloorLog2<0> { /* Error */ }; +template<> struct FloorLog2<1> { static const size_t value = 0; }; + +/** Compute ceiling(log2(i)). */ +template +struct CeilingLog2 +{ + static const size_t value = FloorLog2<2 * I - 1>::value; +}; + +/** Round up to the nearest power of 2. */ +template +struct RoundUpPow2 +{ + static const size_t value = size_t(1) << CeilingLog2::value; +}; +template<> +struct RoundUpPow2<0> +{ + static const size_t value = 1; +}; + +/** Compute the number of bits in the given unsigned type. */ +template +struct BitSize +{ + static const size_t value = sizeof(T) * CHAR_BIT; +}; + +/** + * Produce an N-bit mask, where N <= BitSize::value. Handle the + * language-undefined edge case when N = BitSize::value. + */ +template +struct NBitMask +{ + // Assert the precondition. On success this evaluates to 0. Otherwise it + // triggers divide-by-zero at compile time: a guaranteed compile error in + // C++11, and usually one in C++98. Add this value to |value| to assure + // its computation. + static const size_t checkPrecondition = 0 / size_t(N < BitSize::value); + static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; +}; +template<> +struct NBitMask::value> +{ + static const size_t value = size_t(-1); +}; + +/** + * For the unsigned integral type size_t, compute a mask M for N such that + * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) + */ +template +struct MulOverflowMask +{ + static const size_t value = + ~NBitMask::value - CeilingLog2::value>::value; +}; +template<> struct MulOverflowMask<0> { /* Error */ }; +template<> struct MulOverflowMask<1> { static const size_t value = 0; }; + +} // namespace tl + +} // namespace mozilla + +#endif /* mozilla_TemplateLib_h */ diff --git a/external/spidermonkey/include/mac/mozilla/ThreadLocal.h b/external/spidermonkey/include/mac/mozilla/ThreadLocal.h index 2b4eb30207..6df109821f 100644 --- a/external/spidermonkey/include/mac/mozilla/ThreadLocal.h +++ b/external/spidermonkey/include/mac/mozilla/ThreadLocal.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cross-platform lightweight thread local data wrappers. */ -#ifndef mozilla_ThreadLocal_h_ -#define mozilla_ThreadLocal_h_ +#ifndef mozilla_ThreadLocal_h +#define mozilla_ThreadLocal_h #if defined(XP_WIN) // This file will get included in any file that wants to add a profiler mark. @@ -28,6 +29,7 @@ __declspec(dllimport) unsigned long __stdcall TlsAlloc(); #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -98,15 +100,15 @@ template inline bool ThreadLocal::init() { - MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); + static_assert(sizeof(T) <= sizeof(void*), + "mozilla::ThreadLocal can't be used for types larger than " + "a pointer"); MOZ_ASSERT(!initialized()); #ifdef XP_WIN key = TlsAlloc(); inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES #else - inited = !pthread_key_create(&key, NULL); + inited = !pthread_key_create(&key, nullptr); #endif return inited; } @@ -144,4 +146,4 @@ ThreadLocal::set(const T value) } // namespace mozilla -#endif // mozilla_ThreadLocal_h_ +#endif /* mozilla_ThreadLocal_h */ diff --git a/external/spidermonkey/include/mac/mozilla/TypeTraits.h b/external/spidermonkey/include/mac/mozilla/TypeTraits.h index 656bc775f8..53c0b5c2f6 100644 --- a/external/spidermonkey/include/mac/mozilla/TypeTraits.h +++ b/external/spidermonkey/include/mac/mozilla/TypeTraits.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Template-based metaprogramming and type-testing facilities. */ -#ifndef mozilla_TypeTraits_h_ -#define mozilla_TypeTraits_h_ +#ifndef mozilla_TypeTraits_h +#define mozilla_TypeTraits_h /* * These traits are approximate copies of the traits and semantics from C++11's @@ -126,6 +127,28 @@ struct IsPointer : FalseType {}; template struct IsPointer : TrueType {}; +namespace detail { + +// __is_enum is a supported extension across all of our supported compilers. +template +struct IsEnumHelper + : IntegralConstant +{}; + +} // namespace detail + +/** + * IsEnum determines whether a type is an enum type. + * + * mozilla::IsEnum::value is true; + * mozilla::IsEnum::value is false; + * mozilla::IsEnum::value is false; + */ +template +struct IsEnum + : detail::IsEnumHelper::Type> +{}; + /* 20.9.4.2 Composite type traits [meta.unary.comp] */ /** @@ -197,8 +220,24 @@ template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; template struct IsPod : TrueType {}; +namespace detail { + +template::value> +struct IsSignedHelper; + +template +struct IsSignedHelper : TrueType {}; + +template +struct IsSignedHelper + : IntegralConstant::value && T(-1) < T(1)> +{}; + +} // namespace detail + /** - * IsSigned determines whether a type is a signed arithmetic type. + * IsSigned determines whether a type is a signed arithmetic type. |char| is + * considered a signed type if it has the same representation as |signed char|. * * Don't use this if the type might be user-defined! You might or might not get * a compile error, depending. @@ -209,10 +248,26 @@ template struct IsPod : TrueType {}; * mozilla::IsSigned::value is true. */ template -struct IsSigned - : IntegralConstant::value && T(-1) < T(0)> +struct IsSigned : detail::IsSignedHelper {}; + +namespace detail { + +template::value> +struct IsUnsignedHelper; + +template +struct IsUnsignedHelper : FalseType {}; + +template +struct IsUnsignedHelper + : IntegralConstant::value && + (IsSame::Type, bool>::value || + T(1) < T(-1))> {}; +} // namespace detail + /** * IsUnsigned determines whether a type is an unsigned arithmetic type. * @@ -225,9 +280,7 @@ struct IsSigned * mozilla::IsUnsigned::value is false. */ template -struct IsUnsigned - : IntegralConstant::value && T(0) < T(-1)> -{}; +struct IsUnsigned : detail::IsUnsignedHelper {}; /* 20.9.5 Type property queries [meta.unary.prop.query] */ @@ -427,6 +480,160 @@ struct RemoveCV /* 20.9.7.3 Sign modifications [meta.trans.sign] */ +template +struct EnableIf; + +template +struct Conditional; + +namespace detail { + +template +struct WithC : Conditional +{}; + +template +struct WithV : Conditional +{}; + + +template +struct WithCV : WithC::Type> +{}; + +template +struct CorrespondingSigned; + +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef short Type; }; +template<> +struct CorrespondingSigned { typedef int Type; }; +template<> +struct CorrespondingSigned { typedef long Type; }; +template<> +struct CorrespondingSigned { typedef long long Type; }; + +template::Type, + bool IsSignedIntegerType = IsSigned::value && + !IsSame::value> +struct MakeSigned; + +template +struct MakeSigned +{ + typedef T Type; +}; + +template +struct MakeSigned + : WithCV::value, IsVolatile::value, + typename CorrespondingSigned::Type> +{}; + +} // namespace detail + +/** + * MakeSigned produces the corresponding signed integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already a signed integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an unsigned integer type, the signed variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the integral type of the same size as T, with the lowest rank, + * with T's const/volatile qualifiers, is produced. (This basically only acts + * to produce signed char when T = char.) + * + * mozilla::MakeSigned::Type is signed long; + * mozilla::MakeSigned::Type is volatile int; + * mozilla::MakeSigned::Type is const signed short; + * mozilla::MakeSigned::Type is const signed char; + * mozilla::MakeSigned is an error; + * mozilla::MakeSigned is an error. + */ +template +struct MakeSigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeSigned + >::Type +{}; + +namespace detail { + +template +struct CorrespondingUnsigned; + +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned short Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned int Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long long Type; }; + + +template::Type, + bool IsUnsignedIntegerType = IsUnsigned::value && + !IsSame::value> +struct MakeUnsigned; + +template +struct MakeUnsigned +{ + typedef T Type; +}; + +template +struct MakeUnsigned + : WithCV::value, IsVolatile::value, + typename CorrespondingUnsigned::Type> +{}; + +} // namespace detail + +/** + * MakeUnsigned produces the corresponding unsigned integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already an unsigned integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an signed integer type, the unsigned variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the unsigned integral type of the same size as T, with the lowest + * rank, with T's const/volatile qualifiers, is produced. (This basically only + * acts to produce unsigned char when T = char.) + * + * mozilla::MakeUnsigned::Type is unsigned long; + * mozilla::MakeUnsigned::Type is volatile unsigned int; + * mozilla::MakeUnsigned::Type is const unsigned short; + * mozilla::MakeUnsigned::Type is const unsigned char; + * mozilla::MakeUnsigned is an error; + * mozilla::MakeUnsigned is an error. + */ +template +struct MakeUnsigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeUnsigned + >::Type +{}; + /* 20.9.7.4 Array modifications [meta.trans.arr] */ /* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ @@ -451,7 +658,7 @@ struct RemoveCV * ... * }; */ -template +template struct EnableIf {}; @@ -481,4 +688,4 @@ struct Conditional } /* namespace mozilla */ -#endif /* mozilla_TypeTraits_h_ */ +#endif /* mozilla_TypeTraits_h */ diff --git a/external/spidermonkey/include/mac/mozilla/TypedEnum.h b/external/spidermonkey/include/mac/mozilla/TypedEnum.h index 889960a32d..6f595cb4c5 100644 --- a/external/spidermonkey/include/mac/mozilla/TypedEnum.h +++ b/external/spidermonkey/include/mac/mozilla/TypedEnum.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Macros to emulate C++11 typed enums and enum classes. */ -#ifndef mozilla_TypedEnum_h_ -#define mozilla_TypedEnum_h_ +#ifndef mozilla_TypedEnum_h +#define mozilla_TypedEnum_h #include "mozilla/Attributes.h" @@ -91,16 +92,33 @@ * mandatory. As with MOZ_ENUM_TYPE(), it will do nothing on compilers that do * not support it. * - * Note that the workaround implemented here is not compatible with enums - * nested inside a class. + * MOZ_{BEGIN,END}_ENUM_CLASS doesn't work for defining enum classes nested + * inside classes. To define an enum class nested inside another class, use + * MOZ_{BEGIN,END}_NESTED_ENUM_CLASS, and place a MOZ_FINISH_NESTED_ENUM_CLASS + * in namespace scope to handle bits that can only be implemented with + * namespace-scoped code. For example: + * + * class FooBar { + * + * MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t) + * A, + * B = 6 + * MOZ_END_NESTED_ENUM_CLASS(Enum) + * + * }; + * + * MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum) */ #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) /* * All compilers that support strong enums also support an explicit * underlying type, so no extra check is needed. */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) enum class Name : type { -# define MOZ_END_ENUM_CLASS(Name) }; +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ + enum class Name : type { +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) /* nothing */ #else /** * We need Name to both name a type, and scope the provided enumerator @@ -136,14 +154,14 @@ * { * return Enum::A; * } - */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) \ + */\ +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ class Name \ { \ public: \ enum Enum MOZ_ENUM_TYPE(type) \ { -# define MOZ_END_ENUM_CLASS(Name) \ +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; \ Name() {} \ Name(Enum aEnum) : mEnum(aEnum) {} \ @@ -151,7 +169,8 @@ operator Enum() const { return mEnum; } \ private: \ Enum mEnum; \ - }; \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) \ inline int operator+(const int&, const Name::Enum&) MOZ_DELETE; \ inline int operator+(const Name::Enum&, const int&) MOZ_DELETE; \ inline int operator-(const int&, const Name::Enum&) MOZ_DELETE; \ @@ -207,7 +226,11 @@ inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \ inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE; #endif +# define MOZ_BEGIN_ENUM_CLASS(Name, type) MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) +# define MOZ_END_ENUM_CLASS(Name) \ + MOZ_END_NESTED_ENUM_CLASS(Name) \ + MOZ_FINISH_NESTED_ENUM_CLASS(Name) #endif /* __cplusplus */ -#endif /* mozilla_TypedEnum_h_ */ +#endif /* mozilla_TypedEnum_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Types.h b/external/spidermonkey/include/mac/mozilla/Types.h index 56e5cb82fb..5340b2b600 100644 --- a/external/spidermonkey/include/mac/mozilla/Types.h +++ b/external/spidermonkey/include/mac/mozilla/Types.h @@ -1,28 +1,22 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt foundational types and macros. */ -#ifndef mozilla_Types_h_ -#define mozilla_Types_h_ +#ifndef mozilla_Types_h +#define mozilla_Types_h /* * This header must be valid C and C++, includable by code embedding either * SpiderMonkey or Gecko. */ -/* - * Expose all the integer types defined in C99's (and the integer - * limit and constant macros, if compiling C code or if compiling C++ code and - * the right __STDC_*_MACRO has been defined for each). These are all usable - * throughout mfbt code, and throughout Mozilla code more generally. - */ -#include "mozilla/StandardInteger.h" - -/* Also expose size_t. */ +/* Expose all types and size_t. */ #include +#include /* Implement compiler and linker macros needed for APIs. */ @@ -133,4 +127,12 @@ # define MOZ_END_EXTERN_C #endif -#endif /* mozilla_Types_h_ */ +/* + * GCC's typeof is available when decltype is not. + */ +#if defined(__GNUC__) && defined(__cplusplus) && \ + !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +# define decltype __typeof__ +#endif + +#endif /* mozilla_Types_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Util.h b/external/spidermonkey/include/mac/mozilla/Util.h index 097c5478eb..4f1c634a59 100644 --- a/external/spidermonkey/include/mac/mozilla/Util.h +++ b/external/spidermonkey/include/mac/mozilla/Util.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * new headers, or to other appropriate existing headers, not here. */ -#ifndef mozilla_Util_h_ -#define mozilla_Util_h_ +#ifndef mozilla_Util_h +#define mozilla_Util_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" @@ -196,6 +197,58 @@ class Maybe constructed = true; } + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); + constructed = true; + } + T* addr() { MOZ_ASSERT(constructed); return &asT(); @@ -271,7 +324,7 @@ ArrayEnd(T (&arr)[N]) /* * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for MOZ_STATIC_ASSERT() calls that + * that can't use C++ template functions and for static_assert() calls that * can't call ArrayLength() when it is not a C++11 constexpr function. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR @@ -280,4 +333,4 @@ ArrayEnd(T (&arr)[N]) # define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) #endif -#endif /* mozilla_Util_h_ */ +#endif /* mozilla_Util_h */ diff --git a/external/spidermonkey/include/mac/mozilla/Vector.h b/external/spidermonkey/include/mac/mozilla/Vector.h new file mode 100644 index 0000000000..8759df8c06 --- /dev/null +++ b/external/spidermonkey/include/mac/mozilla/Vector.h @@ -0,0 +1,1190 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A type/length-parametrized vector class. */ + +#ifndef mozilla_Vector_h +#define mozilla_Vector_h + +#include "mozilla/AllocPolicy.h" +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" +#include "mozilla/NullPtr.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" +#include "mozilla/TypeTraits.h" +#include "mozilla/Util.h" + +#include // for placement new + +/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4345) +#endif + +namespace mozilla { + +template +class VectorBase; + +namespace detail { + +/* + * Check that the given capacity wastes the minimal amount of space if + * allocated on the heap. This means that cap*sizeof(T) is as close to a + * power-of-two as possible. growStorageBy() is responsible for ensuring + * this. + */ +template +static bool CapacityHasExcessSpace(size_t cap) +{ + size_t size = cap * sizeof(T); + return RoundUpPow2(size) - size >= sizeof(T); +} + +/* + * This template class provides a default implementation for vector operations + * when the element type is not known to be a POD, as judged by IsPod. + */ +template +struct VectorImpl +{ + /* Destroys constructed objects in the range [begin, end). */ + static inline void destroy(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + p->~T(); + } + + /* Constructs objects in the uninitialized range [begin, end). */ + static inline void initialize(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + /* + * Copy-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(*p); + } + + /* + * Move-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(Move(*p)); + } + + /* + * Copy-constructs objects in the uninitialized range [dst, dst+n) from the + * same object u. + */ + template + static inline void copyConstructN(T* dst, size_t n, const U& u) { + for (T* end = dst + n; dst < end; ++dst) + new(dst) T(u); + } + + /* + * Grows the given buffer to have capacity newCap, preserving the objects + * constructed in the range [begin, end) and updating v. Assumes that (1) + * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will + * not overflow. + */ + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + T* newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); + if (!newbuf) + return false; + T* dst = newbuf; + T* src = v.beginNoCheck(); + for (; src < v.endNoCheck(); ++dst, ++src) + new(dst) T(Move(*src)); + VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); + v.free_(v.mBegin); + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +/* + * This partial template specialization provides a default implementation for + * vector operations when the element type is known to be a POD, as judged by + * IsPod. + */ +template +struct VectorImpl +{ + static inline void destroy(T*, T*) {} + + static inline void initialize(T* begin, T* end) { + /* + * You would think that memset would be a big win (or even break even) + * when we know T is a POD. But currently it's not. This is probably + * because |append| tends to be given small ranges and memset requires + * a function call that doesn't get inlined. + * + * memset(begin, 0, sizeof(T) * (end-begin)); + */ + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + /* + * See above memset comment. Also, notice that copyConstruct is + * currently templated (T != U), so memcpy won't work without + * requiring T == U. + * + * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); + */ + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + *dst = *p; + } + + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + copyConstruct(dst, srcbeg, srcend); + } + + static inline void copyConstructN(T* dst, size_t n, const T& t) { + for (T* end = dst + n; dst < end; ++dst) + *dst = t; + } + + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + size_t oldSize = sizeof(T) * v.mCapacity; + size_t newSize = sizeof(T) * newCap; + T* newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); + if (!newbuf) + return false; + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +} // namespace detail + +/* + * A CRTP base class for vector-like classes. Unless you really really want + * your own vector class -- and you almost certainly don't -- you should use + * mozilla::Vector instead! + * + * See mozilla::Vector for interface requirements. + */ +template +class VectorBase : private AllocPolicy +{ + /* utilities */ + + static const bool sElemIsPod = IsPod::value; + typedef detail::VectorImpl Impl; + friend struct detail::VectorImpl; + + bool growStorageBy(size_t incr); + bool convertToHeapStorage(size_t newCap); + + /* magic constants */ + + static const int sMaxInlineBytes = 1024; + + /* compute constants */ + + /* + * Consider element size to be 1 for buffer sizing if there are 0 inline + * elements. This allows us to compile when the definition of the element + * type is not visible here. + * + * Explicit specialization is only allowed at namespace scope, so in order + * to keep everything here, we use a dummy template parameter with partial + * specialization. + */ + template + struct ElemSize + { + static const size_t value = sizeof(T); + }; + template + struct ElemSize<0, Dummy> + { + static const size_t value = 1; + }; + + static const size_t sInlineCapacity = + tl::Min::value>::value; + + /* Calculate inline buffer size; avoid 0-sized array. */ + static const size_t sInlineBytes = + tl::Max<1, sInlineCapacity * ElemSize::value>::value; + + /* member data */ + + /* + * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, + * mBegin + mLength) hold valid constructed T objects. The range [mBegin + + * mLength, mBegin + mCapacity) holds uninitialized memory. The range + * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory + * previously allocated by a call to reserve(). + */ + T* mBegin; + + /* Number of elements in the vector. */ + size_t mLength; + + /* Max number of elements storable in the vector without resizing. */ + size_t mCapacity; + +#ifdef DEBUG + /* Max elements of reserved or used space in this vector. */ + size_t mReserved; +#endif + + /* Memory used for inline storage. */ + AlignedStorage storage; + +#ifdef DEBUG + friend class ReentrancyGuard; + bool entered; +#endif + + /* private accessors */ + + bool usingInlineStorage() const { + return mBegin == const_cast(this)->inlineStorage(); + } + + T* inlineStorage() { + return static_cast(storage.addr()); + } + + T* beginNoCheck() const { + return mBegin; + } + + T* endNoCheck() { + return mBegin + mLength; + } + + const T* endNoCheck() const { + return mBegin + mLength; + } + +#ifdef DEBUG + size_t reserved() const { + MOZ_ASSERT(mReserved <= mCapacity); + MOZ_ASSERT(mLength <= mReserved); + return mReserved; + } +#endif + + /* Append operations guaranteed to succeed due to pre-reserved space. */ + template void internalAppend(const U& u); + template + void internalAppendAll(const VectorBase& u); + void internalAppendN(const T& t, size_t n); + template void internalAppend(const U* begin, size_t length); + + public: + static const size_t sMaxInlineStorage = N; + + typedef T ElementType; + + VectorBase(AllocPolicy = AllocPolicy()); + VectorBase(MoveRef); /* Move constructor. */ + ThisVector& operator=(MoveRef); /* Move assignment. */ + ~VectorBase(); + + /* accessors */ + + const AllocPolicy& allocPolicy() const { + return *this; + } + + AllocPolicy& allocPolicy() { + return *this; + } + + enum { InlineLength = N }; + + size_t length() const { + return mLength; + } + + bool empty() const { + return mLength == 0; + } + + size_t capacity() const { + return mCapacity; + } + + T* begin() { + MOZ_ASSERT(!entered); + return mBegin; + } + + const T* begin() const { + MOZ_ASSERT(!entered); + return mBegin; + } + + T* end() { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + const T* end() const { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + T& operator[](size_t i) { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + T& back() { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + const T& back() const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + class Range + { + friend class VectorBase; + T* cur_; + T* end_; + Range(T* cur, T* end) : cur_(cur), end_(end) {} + + public: + Range() {} + bool empty() const { return cur_ == end_; } + size_t remain() const { return end_ - cur_; } + T& front() const { return *cur_; } + void popFront() { MOZ_ASSERT(!empty()); ++cur_; } + T popCopyFront() { MOZ_ASSERT(!empty()); return *cur_++; } + }; + + Range all() { + return Range(begin(), end()); + } + + /* mutators */ + + /** + * Given that the vector is empty and has no inline storage, grow to + * |capacity|. + */ + bool initCapacity(size_t request); + + /** + * If reserve(length() + N) succeeds, the N next appends are guaranteed to + * succeed. + */ + bool reserve(size_t request); + + /** + * Destroy elements in the range [end() - incr, end()). Does not deallocate + * or unreserve storage for those elements. + */ + void shrinkBy(size_t incr); + + /** Grow the vector by incr elements. */ + bool growBy(size_t incr); + + /** Call shrinkBy or growBy based on whether newSize > length(). */ + bool resize(size_t newLength); + + /** + * Increase the length of the vector, but don't initialize the new elements + * -- leave them as uninitialized memory. + */ + bool growByUninitialized(size_t incr); + bool resizeUninitialized(size_t newLength); + + /** Shorthand for shrinkBy(length()). */ + void clear(); + + /** Clears and releases any heap-allocated storage. */ + void clearAndFree(); + + /** + * If true, appending |needed| elements won't reallocate elements storage. + * This *doesn't* mean that infallibleAppend may be used! You still must + * reserve the extra space, even if this method indicates that appends won't + * need to reallocate elements storage. + */ + bool canAppendWithoutRealloc(size_t needed) const; + + /** + * Potentially fallible append operations. + * + * The function templates that take an unspecified type U require a const T& + * or a MoveRef. The MoveRef variants move their operands into the + * vector, instead of copying them. If they fail, the operand is left + * unmoved. + */ + template bool append(const U& u); + template + bool appendAll(const VectorBase& u); + bool appendN(const T& t, size_t n); + template bool append(const U* begin, const U* end); + template bool append(const U* begin, size_t length); + + /* + * Guaranteed-infallible append operations for use upon vectors whose + * memory has been pre-reserved. Don't use this if you haven't reserved the + * memory! + */ + template void infallibleAppend(const U& u) { + internalAppend(u); + } + void infallibleAppendN(const T& t, size_t n) { + internalAppendN(t, n); + } + template void infallibleAppend(const U* aBegin, const U* aEnd) { + internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); + } + template void infallibleAppend(const U* aBegin, size_t aLength) { + internalAppend(aBegin, aLength); + } + + void popBack(); + + T popCopy(); + + /** + * Transfers ownership of the internal buffer used by this vector to the + * caller. (It's the caller's responsibility to properly deallocate this + * buffer, in accordance with this vector's AllocPolicy.) After this call, + * the vector is empty. Since the returned buffer may need to be allocated + * (if the elements are currently stored in-place), the call can fail, + * returning nullptr. + * + * N.B. Although a T*, only the range [0, length()) is constructed. + */ + T* extractRawBuffer(); + + /** + * Transfer ownership of an array of objects into the vector. The caller + * must have allocated the array in accordance with this vector's + * AllocPolicy. + * + * N.B. This call assumes that there are no uninitialized elements in the + * passed array. + */ + void replaceRawBuffer(T* p, size_t length); + + /** + * Places |val| at position |p|, shifting existing elements from |p| onward + * one position higher. On success, |p| should not be reused because it'll + * be a dangling pointer if reallocation of the vector storage occurred; the + * return value should be used instead. On failure, nullptr is returned. + * + * Example usage: + * + * if (!(p = vec.insert(p, val))) + * + * + * + * This is inherently a linear-time operation. Be careful! + */ + T* insert(T* p, const T& val); + + /** + * Removes the element |t|, which must fall in the bounds [begin, end), + * shifting existing elements from |t + 1| onward one position lower. + */ + void erase(T* t); + + /** + * Measure the size of the vector's heap-allocated storage. + */ + size_t sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const; + + /** + * Like sizeOfExcludingThis, but also measures the size of the vector + * object (which must be heap-allocated) itself. + */ + size_t sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const; + + void swap(ThisVector& other); + + private: + VectorBase(const ThisVector&) MOZ_DELETE; + void operator=(const ThisVector&) MOZ_DELETE; +}; + +/* This does the re-entrancy check plus several other sanity checks. */ +#define MOZ_REENTRANCY_GUARD_ET_AL \ + ReentrancyGuard g(*this); \ + MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ + MOZ_ASSERT(reserved() <= mCapacity); \ + MOZ_ASSERT(mLength <= reserved()); \ + MOZ_ASSERT(mLength <= mCapacity) + +/* Vector Implementation */ + +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(AP ap) + : AP(ap), + mBegin(static_cast(storage.addr())), + mLength(0), + mCapacity(sInlineCapacity) +#ifdef DEBUG + , mReserved(sInlineCapacity), + entered(false) +#endif +{} + +/* Move constructor. */ +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(MoveRef rhs) + : AllocPolicy(rhs) +#ifdef DEBUG + , entered(false) +#endif +{ + mLength = rhs->mLength; + mCapacity = rhs->mCapacity; +#ifdef DEBUG + mReserved = rhs->mReserved; +#endif + + if (rhs->usingInlineStorage()) { + /* We can't move the buffer over in this case, so copy elements. */ + mBegin = static_cast(storage.addr()); + Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); + /* + * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. + * The elements in its in-line storage still need to be destroyed. + */ + } else { + /* + * Take src's buffer, and turn src into an empty vector using + * in-line storage. + */ + mBegin = rhs->mBegin; + rhs->mBegin = static_cast(rhs->storage.addr()); + rhs->mCapacity = sInlineCapacity; + rhs->mLength = 0; +#ifdef DEBUG + rhs->mReserved = sInlineCapacity; +#endif + } +} + +/* Move assignment. */ +template +MOZ_ALWAYS_INLINE +TV& +VectorBase::operator=(MoveRef rhs) +{ + TV* tv = static_cast(this); + tv->~TV(); + new(tv) TV(rhs); + return *tv; +} + +template +MOZ_ALWAYS_INLINE +VectorBase::~VectorBase() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); +} + +/* + * This function will create a new heap buffer with capacity newCap, + * move all elements in the inline buffer to this new buffer, + * and fail on OOM. + */ +template +inline bool +VectorBase::convertToHeapStorage(size_t newCap) +{ + MOZ_ASSERT(usingInlineStorage()); + + /* Allocate buffer. */ + MOZ_ASSERT(!detail::CapacityHasExcessSpace(newCap)); + T* newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); + if (!newBuf) + return false; + + /* Copy inline elements into heap buffer. */ + Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + + /* Switch in heap buffer. */ + mBegin = newBuf; + /* mLength is unchanged. */ + mCapacity = newCap; + return true; +} + +template +MOZ_NEVER_INLINE bool +VectorBase::growStorageBy(size_t incr) +{ + MOZ_ASSERT(mLength + incr > mCapacity); + MOZ_ASSERT_IF(!usingInlineStorage(), + !detail::CapacityHasExcessSpace(mCapacity)); + + /* + * When choosing a new capacity, its size should is as close to 2**N bytes + * as possible. 2**N-sized requests are best because they are unlikely to + * be rounded up by the allocator. Asking for a 2**N number of elements + * isn't as good, because if sizeof(T) is not a power-of-two that would + * result in a non-2**N request size. + */ + + size_t newCap; + + if (incr == 1) { + if (usingInlineStorage()) { + /* This case occurs in ~70--80% of the calls to this function. */ + size_t newSize = + tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::value; + newCap = newSize / sizeof(T); + goto convert; + } + + if (mLength == 0) { + /* This case occurs in ~0--10% of the calls to this function. */ + newCap = 1; + goto grow; + } + + /* This case occurs in ~15--20% of the calls to this function. */ + + /* + * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector + * to 1GB of memory on a 32-bit system, which is a reasonable limit. It + * also ensures that + * + * static_cast(end()) - static_cast(begin()) + * + * doesn't overflow ptrdiff_t (see bug 510319). + */ + if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::value) { + this->reportAllocOverflow(); + return false; + } + + /* + * If we reach here, the existing capacity will have a size that is already + * as close to 2^N as sizeof(T) will allow. Just double the capacity, and + * then there might be space for one more element. + */ + newCap = mLength * 2; + if (detail::CapacityHasExcessSpace(newCap)) + newCap += 1; + } else { + /* This case occurs in ~2% of the calls to this function. */ + size_t newMinCap = mLength + incr; + + /* Did mLength + incr overflow? Will newCap * sizeof(T) overflow? */ + if (newMinCap < mLength || + newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value) + { + this->reportAllocOverflow(); + return false; + } + + size_t newMinSize = newMinCap * sizeof(T); + size_t newSize = RoundUpPow2(newMinSize); + newCap = newSize / sizeof(T); + } + + if (usingInlineStorage()) { + convert: + return convertToHeapStorage(newCap); + } + +grow: + return Impl::growTo(*this, newCap); +} + +template +inline bool +VectorBase::initCapacity(size_t request) +{ + MOZ_ASSERT(empty()); + MOZ_ASSERT(usingInlineStorage()); + if (request == 0) + return true; + T* newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); + if (!newbuf) + return false; + mBegin = newbuf; + mCapacity = request; +#ifdef DEBUG + mReserved = request; +#endif + return true; +} + +template +inline bool +VectorBase::reserve(size_t request) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (request > mCapacity && !growStorageBy(request - mLength)) + return false; + +#ifdef DEBUG + if (request > mReserved) + mReserved = request; + MOZ_ASSERT(mLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); +#endif + return true; +} + +template +inline void +VectorBase::shrinkBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(incr <= mLength); + Impl::destroy(endNoCheck() - incr, endNoCheck()); + mLength -= incr; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + T* newend = endNoCheck() + incr; + Impl::initialize(endNoCheck(), newend); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growByUninitialized(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +inline bool +VectorBase::resize(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growBy(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::resizeUninitialized(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growByUninitialized(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +inline void +VectorBase::clear() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + mLength = 0; +} + +template +inline void +VectorBase::clearAndFree() +{ + clear(); + + if (usingInlineStorage()) + return; + + this->free_(beginNoCheck()); + mBegin = static_cast(storage.addr()); + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif +} + +template +inline bool +VectorBase::canAppendWithoutRealloc(size_t needed) const +{ + return mLength + needed <= mCapacity; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendAll(const VectorBase& other) +{ + internalAppend(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U& u) +{ + MOZ_ASSERT(mLength + 1 <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + new(endNoCheck()) T(u); + ++mLength; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendN(const T& t, size_t needed) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppendN(t, needed); + return true; +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendN(const T& t, size_t needed) +{ + MOZ_ASSERT(mLength + needed <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstructN(endNoCheck(), needed, t); + mLength += needed; +} + +template +inline T* +VectorBase::insert(T* p, const T& val) +{ + MOZ_ASSERT(begin() <= p); + MOZ_ASSERT(p <= end()); + size_t pos = p - begin(); + MOZ_ASSERT(pos <= mLength); + size_t oldLength = mLength; + if (pos == oldLength) { + if (!append(val)) + return nullptr; + } else { + T oldBack = back(); + if (!append(oldBack)) /* Dup the last element. */ + return nullptr; + for (size_t i = oldLength; i > pos; --i) + (*this)[i] = (*this)[i - 1]; + (*this)[pos] = val; + } + return begin() + pos; +} + +template +inline void +VectorBase::erase(T* it) +{ + MOZ_ASSERT(begin() <= it); + MOZ_ASSERT(it < end()); + while (it + 1 < end()) { + *it = *(it + 1); + ++it; + } + popBack(); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U* insBegin, const U* insEnd) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + size_t needed = PointerRangeSize(insBegin, insEnd); + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppend(insBegin, needed); + return true; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U* insBegin, size_t insLength) +{ + MOZ_ASSERT(mLength + insLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); + mLength += insLength; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U& u) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength == mCapacity && !growStorageBy(1)) + return false; + +#ifdef DEBUG + if (mLength + 1 > mReserved) + mReserved = mLength + 1; +#endif + internalAppend(u); + return true; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendAll(const VectorBase& other) +{ + return append(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U *insBegin, size_t insLength) +{ + return append(insBegin, insBegin + insLength); +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::popBack() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(!empty()); + --mLength; + endNoCheck()->~T(); +} + +template +MOZ_ALWAYS_INLINE T +VectorBase::popCopy() +{ + T ret = back(); + popBack(); + return ret; +} + +template +inline T* +VectorBase::extractRawBuffer() +{ + T* ret; + if (usingInlineStorage()) { + ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); + if (!ret) + return nullptr; + Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + /* mBegin, mCapacity are unchanged. */ + mLength = 0; + } else { + ret = mBegin; + mBegin = static_cast(storage.addr()); + mLength = 0; + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif + } + return ret; +} + +template +inline void +VectorBase::replaceRawBuffer(T* p, size_t aLength) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + + /* Destroy what we have. */ + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); + + /* Take in the new buffer. */ + if (aLength <= sInlineCapacity) { + /* + * We convert to inline storage if possible, even though p might + * otherwise be acceptable. Maybe this behaviour should be + * specifiable with an argument to this function. + */ + mBegin = static_cast(storage.addr()); + mLength = aLength; + mCapacity = sInlineCapacity; + Impl::moveConstruct(mBegin, p, p + aLength); + Impl::destroy(p, p + aLength); + this->free_(p); + } else { + mBegin = p; + mLength = aLength; + mCapacity = aLength; + } +#ifdef DEBUG + mReserved = aLength; +#endif +} + +template +inline size_t +VectorBase::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const +{ + return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); +} + +template +inline size_t +VectorBase::sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const +{ + return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); +} + +template +inline void +VectorBase::swap(TV& other) +{ + static_assert(N == 0, + "still need to implement this for N != 0"); + + // This only works when inline storage is always empty. + if (!usingInlineStorage() && other.usingInlineStorage()) { + other.mBegin = mBegin; + mBegin = inlineStorage(); + } else if (usingInlineStorage() && !other.usingInlineStorage()) { + mBegin = other.mBegin; + other.mBegin = other.inlineStorage(); + } else if (!usingInlineStorage() && !other.usingInlineStorage()) { + Swap(mBegin, other.mBegin); + } else { + // This case is a no-op, since we'd set both to use their inline storage. + } + + Swap(mLength, other.mLength); + Swap(mCapacity, other.mCapacity); +#ifdef DEBUG + Swap(mReserved, other.mReserved); +#endif +} + +/* + * STL-like container providing a short-lived, dynamic buffer. Vector calls the + * constructors/destructors of all elements stored in its internal buffer, so + * non-PODs may be safely used. Additionally, Vector will store the first N + * elements in-place before resorting to dynamic allocation. + * + * T requirements: + * - default and copy constructible, assignable, destructible + * - operations do not throw + * N requirements: + * - any value, however, N is clamped to min/max values + * AllocPolicy: + * - see "Allocation policies" in AllocPolicy.h (defaults to + * mozilla::MallocAllocPolicy) + * + * Vector is not reentrant: T member functions called during Vector member + * functions must not call back into the same object! + */ +template +class Vector + : public VectorBase > +{ + typedef VectorBase Base; + + public: + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector& operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); + } +}; + +} // namespace mozilla + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif /* mozilla_Vector_h */ diff --git a/external/spidermonkey/include/mac/mozilla/WeakPtr.h b/external/spidermonkey/include/mac/mozilla/WeakPtr.h index d61b0b37d3..c714ebf565 100644 --- a/external/spidermonkey/include/mac/mozilla/WeakPtr.h +++ b/external/spidermonkey/include/mac/mozilla/WeakPtr.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Weak pointer functionality, implemented as a mixin for use with any class. */ @@ -13,6 +14,9 @@ * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime * of 'Foo'. * + * AtomicSupportsWeakPtr can be used for a variant with an atomically updated + * reference counter. + * * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional * dereference, and an additional heap allocated pointer sized object shared * between all of the WeakPtrs. @@ -55,10 +59,11 @@ * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h */ -#ifndef mozilla_WeakPtr_h_ -#define mozilla_WeakPtr_h_ +#ifndef mozilla_WeakPtr_h +#define mozilla_WeakPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/NullPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/TypeTraits.h" @@ -71,8 +76,8 @@ template class SupportsWeakPtrBase; namespace detail { // This can live beyond the lifetime of the class derived from SupportsWeakPtrBase. -template -class WeakReference : public RefCounted > +template +class WeakReference : public RefCounted, Atomicity> { public: explicit WeakReference(T* p) : ptr(p) {} @@ -81,8 +86,8 @@ class WeakReference : public RefCounted > } private: - friend class WeakPtrBase >; - friend class SupportsWeakPtrBase >; + friend class WeakPtrBase; + friend class SupportsWeakPtrBase; void detach() { ptr = nullptr; } @@ -103,8 +108,8 @@ class SupportsWeakPtrBase protected: ~SupportsWeakPtrBase() { - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from SupportsWeakPtrBase"); + static_assert(IsBaseOf, T>::value, + "T must derive from SupportsWeakPtrBase"); if (weakRef) weakRef->detach(); } @@ -116,10 +121,30 @@ class SupportsWeakPtrBase }; template -class SupportsWeakPtr : public SupportsWeakPtrBase > +class SupportsWeakPtr + : public SupportsWeakPtrBase > { }; +template +class AtomicSupportsWeakPtr + : public SupportsWeakPtrBase > +{ +}; + +namespace detail { + +template +struct WeakReferenceCount +{ + static const RefCountAtomicity atomicity = + IsBaseOf, T>::value + ? AtomicRefCount + : NonAtomicRefCount; +}; + +} + template class WeakPtrBase { @@ -152,9 +177,9 @@ class WeakPtrBase }; template -class WeakPtr : public WeakPtrBase > +class WeakPtr : public WeakPtrBase::atomicity> > { - typedef WeakPtrBase > Base; + typedef WeakPtrBase::atomicity> > Base; public: WeakPtr(const WeakPtr& o) : Base(o) {} WeakPtr(const Base& o) : Base(o) {} @@ -163,4 +188,4 @@ class WeakPtr : public WeakPtrBase > } // namespace mozilla -#endif /* ifdef mozilla_WeakPtr_h_ */ +#endif /* mozilla_WeakPtr_h */ diff --git a/external/spidermonkey/include/win32/js-config.h b/external/spidermonkey/include/win32/js-config.h index 38c5df91b4..a581835270 100644 --- a/external/spidermonkey/include/win32/js-config.h +++ b/external/spidermonkey/include/win32/js-config.h @@ -38,8 +38,8 @@ JS_HAVE_STDINT_H. */ /* #undef JS_BYTES_PER_WORD */ -/* Some mozilla code uses JS-friend APIs that depend on JS_METHODJIT being - correct. */ -#define JS_METHODJIT 1 +/* MOZILLA JSAPI version number components */ +#define MOZJS_MAJOR_VERSION 25 +#define MOZJS_MINOR_VERSION 0 #endif /* js_config_h___ */ diff --git a/external/spidermonkey/include/win32/js.msg b/external/spidermonkey/include/win32/js.msg index 3e57bdf174..3f665d8d54 100644 --- a/external/spidermonkey/include/win32/js.msg +++ b/external/spidermonkey/include/win32/js.msg @@ -184,7 +184,7 @@ MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} oper MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id") MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error") -MSG_DEF(JSMSG_UNUSED134, 134, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 134, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent") MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory") @@ -193,10 +193,10 @@ MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many paren MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment") MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_UNUSED143, 143, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 143, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_UNUSED146, 146, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 146, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses") @@ -220,7 +220,7 @@ MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot ind MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals") MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_UNUSED170, 170, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 170, 0, JSEXN_RANGEERR, "repeat count must be non-negative") MSG_DEF(JSMSG_UNUSED171, 171, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED172, 172, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED173, 173, 0, JSEXN_NONE, "") @@ -286,7 +286,7 @@ MSG_DEF(JSMSG_DEPRECATED_OCTAL, 232, 0, JSEXN_SYNTAXERR, "octal literals a MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated") +MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "can't assign to {0} in strict mode") MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 238, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 239, 1, JSEXN_TYPEERR, "{0} is not extensible") @@ -313,16 +313,16 @@ MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 259, 0, JSEXN_TYPEERR, "can't change ob MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 260, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 261, 0, JSEXN_TYPEERR, "unsupported type for structured data") MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive object") -MSG_DEF(JSMSG_UNUSED263, 263, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 263, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee") MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version") MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_UNUSED266, 266, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 266, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function") MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer") MSG_DEF(JSMSG_CLEARED_SCOPE, 269, 0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope") MSG_DEF(JSMSG_MALFORMED_ESCAPE, 270, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") MSG_DEF(JSMSG_BAD_GENEXP_BODY, 271, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_UNUSED272, 272, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_YIELD_WITHOUT_OPERAND, 272, 0, JSEXN_SYNTAXERR, "yield without a value is deprecated, and illegal in ES6 (use 'yield undefined' instead)") MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 273, 0, JSEXN_SYNTAXERR, "function statement requires a name") MSG_DEF(JSMSG_CCW_REQUIRED, 274, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 275, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") @@ -391,12 +391,21 @@ MSG_DEF(JSMSG_DATE_NOT_FINITE, 337, 0, JSEXN_RANGEERR, "date value is not MSG_DEF(JSMSG_MODULE_STATEMENT, 338, 0, JSEXN_SYNTAXERR, "module declarations may only appear at the top level of a program or module body") MSG_DEF(JSMSG_CURLY_BEFORE_MODULE, 339, 0, JSEXN_SYNTAXERR, "missing { before module body") MSG_DEF(JSMSG_CURLY_AFTER_MODULE, 340, 0, JSEXN_SYNTAXERR, "missing } after module body") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "'use asm' directive only works on function code") +MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 341, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 342, 1, JSEXN_TYPEERR, "asm.js type error: {0}") MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 343, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 0, JSEXN_ERR, "successfully compiled asm.js code") +MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 344, 1, JSEXN_ERR, "successfully compiled asm.js code ({0})") MSG_DEF(JSMSG_BAD_ARROW_ARGS, 345, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") MSG_DEF(JSMSG_YIELD_IN_ARROW, 346, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") MSG_DEF(JSMSG_WRONG_VALUE, 347, 2, JSEXN_ERR, "expected {0} but found {1}") MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, 348, 1, JSEXN_ERR, "target for index {0} is not an integer") MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME,349, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") +MSG_DEF(JSMSG_DEPRECATED_SOURCE_MAP, 350, 0, JSEXN_SYNTAXERR, "Using //@ to indicate source map URL pragmas is deprecated. Use //# instead") +MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN, 351, 1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment") +MSG_DEF(JSMSG_BINARYDATA_ARRAYTYPE_BAD_ARGS, 352, 0, JSEXN_ERR, "Invalid arguments") +MSG_DEF(JSMSG_BINARYDATA_BINARYARRAY_BAD_INDEX, 353, 0, JSEXN_RANGEERR, "invalid or out-of-range index") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_ARGS, 354, 0, JSEXN_RANGEERR, "invalid field descriptor") +MSG_DEF(JSMSG_BINARYDATA_NOT_BINARYSTRUCT, 355, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct") +MSG_DEF(JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty") +MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor") diff --git a/external/spidermonkey/include/win32/js/Anchor.h b/external/spidermonkey/include/win32/js/Anchor.h index d0c2476cf7..0d458e6fb6 100644 --- a/external/spidermonkey/include/win32/js/Anchor.h +++ b/external/spidermonkey/include/win32/js/Anchor.h @@ -6,8 +6,8 @@ /* JS::Anchor implementation. */ -#ifndef js_Anchor_h___ -#define js_Anchor_h___ +#ifndef js_Anchor_h +#define js_Anchor_h #include "mozilla/Attributes.h" @@ -159,4 +159,4 @@ inline Anchor::~Anchor() } // namespace JS -#endif /* js_Anchor_h___ */ +#endif /* js_Anchor_h */ diff --git a/external/spidermonkey/include/win32/js/CallArgs.h b/external/spidermonkey/include/win32/js/CallArgs.h index af78fde0a0..8027ffc71a 100644 --- a/external/spidermonkey/include/win32/js/CallArgs.h +++ b/external/spidermonkey/include/win32/js/CallArgs.h @@ -26,11 +26,12 @@ * methods' implementations, potentially under time pressure. */ -#ifndef js_CallArgs_h___ -#define js_CallArgs_h___ +#ifndef js_CallArgs_h +#define js_CallArgs_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/TypeTraits.h" #include "jstypes.h" @@ -44,6 +45,29 @@ class JSObject; typedef JSBool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp); +/* Typedef for native functions that may be called in parallel. */ +typedef js::ParallelResult +(* JSParallelNative)(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + +/* + * Typedef for native functions that may be called either in parallel or + * sequential execution. + */ +typedef JSBool +(* JSThreadSafeNative)(js::ThreadSafeContext *cx, unsigned argc, JS::Value *vp); + +/* + * Convenience wrappers for passing in ThreadSafeNative to places that expect + * a JSNative or a JSParallelNative. + */ +template +inline JSBool +JSNativeThreadSafeWrapper(JSContext *cx, unsigned argc, JS::Value *vp); + +template +inline js::ParallelResult +JSParallelNativeThreadSafeWrapper(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); + /* * Compute |this| for the |vp| inside a JSNative, either boxing primitives or * replacing with the global object as necessary. @@ -58,6 +82,8 @@ JS_ComputeThis(JSContext *cx, JS::Value *vp); namespace JS { +extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; + /* * JS::CallReceiver encapsulates access to the callee, |this|, and eventual * return value for a function call. The principal way to create a @@ -92,30 +118,55 @@ namespace JS { * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallReceiver + +namespace detail { + +#ifdef DEBUG +extern JS_PUBLIC_API(void) +CheckIsValidConstructible(Value v); +#endif + +enum UsedRval { IncludeUsedRval, NoUsedRval }; + +template +class MOZ_STACK_CLASS UsedRvalBase; + +template<> +class MOZ_STACK_CLASS UsedRvalBase { protected: -#ifdef DEBUG mutable bool usedRval_; void setUsedRval() const { usedRval_ = true; } void clearUsedRval() const { usedRval_ = false; } -#else +}; + +template<> +class MOZ_STACK_CLASS UsedRvalBase +{ + protected: void setUsedRval() const {} void clearUsedRval() const {} +}; + +template +class MOZ_STACK_CLASS CallReceiverBase : public UsedRvalBase< +#ifdef DEBUG + WantUsedRval +#else + NoUsedRval #endif - + > +{ + protected: Value *argv_; - friend CallReceiver CallReceiverFromVp(Value *vp); - friend CallReceiver CallReceiverFromArgv(Value *argv); - public: /* * Returns the function being called, as an object. Must not be called * after rval() has been used! */ JSObject &callee() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return argv_[-2].toObject(); } @@ -124,7 +175,7 @@ class MOZ_STACK_CLASS CallReceiver * rval() has been used! */ HandleValue calleev() const { - MOZ_ASSERT(!usedRval_); + MOZ_ASSERT(!this->usedRval_); return HandleValue::fromMarkedLocation(&argv_[-2]); } @@ -148,6 +199,14 @@ class MOZ_STACK_CLASS CallReceiver return JS_ComputeThis(cx, base()); } + bool isConstructing() const { +#ifdef DEBUG + if (this->usedRval_) + CheckIsValidConstructible(calleev()); +#endif + return argv_[-1].isMagic(); + } + /* * Returns the currently-set return value. The initial contents of this * value are unspecified. Once this method has been called, callee() and @@ -160,7 +219,7 @@ class MOZ_STACK_CLASS CallReceiver * fails. */ MutableHandleValue rval() const { - setUsedRval(); + this->setUsedRval(); return MutableHandleValue::fromMarkedLocation(&argv_[-2]); } @@ -171,7 +230,7 @@ class MOZ_STACK_CLASS CallReceiver Value *base() const { return argv_ - 2; } Value *spAfterCall() const { - setUsedRval(); + this->setUsedRval(); return argv_ - 1; } @@ -181,7 +240,7 @@ class MOZ_STACK_CLASS CallReceiver // it. You probably don't want to use these! void setCallee(Value aCalleev) const { - clearUsedRval(); + this->clearUsedRval(); argv_[-2] = aCalleev; } @@ -194,6 +253,15 @@ class MOZ_STACK_CLASS CallReceiver } }; +} // namespace detail + +class MOZ_STACK_CLASS CallReceiver : public detail::CallReceiverBase +{ + private: + friend CallReceiver CallReceiverFromVp(Value *vp); + friend CallReceiver CallReceiverFromArgv(Value *argv); +}; + MOZ_ALWAYS_INLINE CallReceiver CallReceiverFromArgv(Value *argv) { @@ -233,11 +301,59 @@ CallReceiverFromVp(Value *vp) * public interface are meant to be used by embedders! See inline comments to * for details. */ -class MOZ_STACK_CLASS CallArgs : public CallReceiver +namespace detail { + +template +class MOZ_STACK_CLASS CallArgsBase : + public mozilla::Conditional >::Type { protected: unsigned argc_; + public: + /* Returns the number of arguments. */ + unsigned length() const { return argc_; } + + /* Returns the i-th zero-indexed argument. */ + MutableHandleValue operator[](unsigned i) const { + MOZ_ASSERT(i < argc_); + return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); + } + + /* + * Returns the i-th zero-indexed argument, or |undefined| if there's no + * such argument. + */ + HandleValue get(unsigned i) const { + return i < length() + ? HandleValue::fromMarkedLocation(&this->argv_[i]) + : UndefinedHandleValue; + } + + /* + * Returns true if the i-th zero-indexed argument is present and is not + * |undefined|. + */ + bool hasDefined(unsigned i) const { + return i < argc_ && !this->argv_[i].isUndefined(); + } + + public: + // These methods are publicly exposed, but we're less sure of the interface + // here than we'd like (because they're hackish and drop assertions). Try + // to avoid using these if you can. + + Value *array() const { return this->argv_; } + Value *end() const { return this->argv_ + argc_; } +}; + +} // namespace detail + +class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase +{ + private: friend CallArgs CallArgsFromVp(unsigned argc, Value *vp); friend CallArgs CallArgsFromSp(unsigned argc, Value *sp); @@ -249,45 +365,6 @@ class MOZ_STACK_CLASS CallArgs : public CallReceiver return args; } - public: - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - Value &operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return argv_[i]; - } - - /* Returns a mutable handle for the i-th zero-indexed argument. */ - MutableHandleValue handleAt(unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - Value get(unsigned i) const { - return i < length() ? argv_[i] : UndefinedValue(); - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !argv_[i].isUndefined(); - } - - public: - // These methods are publicly exposed, but we're less sure of the interface - // here than we'd like (because they're hackish and drop assertions). Try - // to avoid using these if you can. - - Value *array() const { return argv_; } - Value *end() const { return argv_ + argc_; } }; MOZ_ALWAYS_INLINE CallArgs @@ -345,4 +422,4 @@ JS_THIS(JSContext *cx, JS::Value *vp) */ #define JS_THIS_VALUE(cx,vp) ((vp)[1]) -#endif /* js_CallArgs_h___ */ +#endif /* js_CallArgs_h */ diff --git a/external/spidermonkey/include/win32/js/CharacterEncoding.h b/external/spidermonkey/include/win32/js/CharacterEncoding.h index 63e5cc6650..e88e08e1be 100644 --- a/external/spidermonkey/include/win32/js/CharacterEncoding.h +++ b/external/spidermonkey/include/win32/js/CharacterEncoding.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_CharacterEncoding_h___ -#define js_CharacterEncoding_h___ +#ifndef js_CharacterEncoding_h +#define js_CharacterEncoding_h #include "mozilla/Range.h" @@ -58,6 +58,20 @@ class Latin1CharsZ : public mozilla::RangedPtr char *c_str() { return reinterpret_cast(get()); } }; +class UTF8Chars : public mozilla::Range +{ + typedef mozilla::Range Base; + + public: + UTF8Chars() : Base() {} + UTF8Chars(char *aBytes, size_t aLength) + : Base(reinterpret_cast(aBytes), aLength) + {} + UTF8Chars(const char *aBytes, size_t aLength) + : Base(reinterpret_cast(const_cast(aBytes)), aLength) + {} +}; + /* * SpiderMonkey also deals directly with UTF-8 encoded text in some places. */ @@ -124,10 +138,12 @@ class TwoByteCharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: + TwoByteCharsZ() : Base(NULL, 0) {} + TwoByteCharsZ(jschar *chars, size_t length) : Base(chars, length) { - JS_ASSERT(chars[length] = '\0'); + JS_ASSERT(chars[length] == '\0'); } }; @@ -142,14 +158,34 @@ class TwoByteCharsZ : public mozilla::RangedPtr * This method cannot trigger GC. */ extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars); +LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); extern UTF8CharsZ -TwoByteCharsToNewUTF8CharsZ(JSContext *cx, TwoByteChars tbchars); +TwoByteCharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); + +uint32_t +Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length); + +/* + * Inflate bytes in UTF-8 encoding to jschars. + * - On error, returns an empty TwoByteCharsZ. + * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold + * its length; the length value excludes the trailing null. + */ +extern TwoByteCharsZ +UTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); + +/* + * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters + * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 + * input. + */ +extern TwoByteCharsZ +LossyUTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen); } // namespace JS inline void JS_free(JS::Latin1CharsZ &ptr) { js_free((void*)ptr.get()); } inline void JS_free(JS::UTF8CharsZ &ptr) { js_free((void*)ptr.get()); } -#endif // js_CharacterEncoding_h___ +#endif /* js_CharacterEncoding_h */ diff --git a/external/spidermonkey/include/win32/js/Date.h b/external/spidermonkey/include/win32/js/Date.h index 7ca961e30a..6199f9eca5 100644 --- a/external/spidermonkey/include/win32/js/Date.h +++ b/external/spidermonkey/include/win32/js/Date.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_Date_h___ -#define js_Date_h___ +#ifndef js_Date_h +#define js_Date_h #include "jstypes.h" @@ -32,4 +32,4 @@ DayFromTime(double time); } // namespace JS -#endif /* js_Date_h___ */ +#endif /* js_Date_h */ diff --git a/external/spidermonkey/include/win32/js/GCAPI.h b/external/spidermonkey/include/win32/js/GCAPI.h index 1b0036116c..a9bef77c09 100644 --- a/external/spidermonkey/include/win32/js/GCAPI.h +++ b/external/spidermonkey/include/win32/js/GCAPI.h @@ -4,10 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_gc_api_h___ -#define js_gc_api_h___ +#ifndef js_GCAPI_h +#define js_GCAPI_h -#include "HeapAPI.h" +#include "js/HeapAPI.h" namespace JS { @@ -181,6 +181,9 @@ DisableIncrementalGC(JSRuntime *rt); extern JS_FRIEND_API(void) DisableGenerationalGC(JSRuntime *rt); +extern JS_FRIEND_API(void) +EnableGenerationalGC(JSRuntime *rt); + extern JS_FRIEND_API(bool) IsIncrementalBarrierNeeded(JSRuntime *rt); @@ -205,7 +208,7 @@ WasIncrementalGC(JSRuntime *rt); class ObjectPtr { - JSObject *value; + Heap value; public: ObjectPtr() : value(NULL) {} @@ -240,7 +243,7 @@ class ObjectPtr } void trace(JSTracer *trc, const char *name) { - JS_CallObjectTracer(trc, &value, name); + JS_CallHeapObjectTracer(trc, &value, name); } JSObject &operator*() const { return *value; } @@ -291,4 +294,4 @@ ExposeValueToActiveJS(const Value &v) } /* namespace JS */ -#endif /* js_gc_api_h___ */ +#endif /* js_GCAPI_h */ diff --git a/external/spidermonkey/include/win32/js/HashTable.h b/external/spidermonkey/include/win32/js/HashTable.h index 3402bfbff4..aa05b71472 100644 --- a/external/spidermonkey/include/win32/js/HashTable.h +++ b/external/spidermonkey/include/win32/js/HashTable.h @@ -4,17 +4,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_HashTable_h__ -#define js_HashTable_h__ +#ifndef js_HashTable_h +#define js_HashTable_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" #include "mozilla/PodOperations.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" #include "mozilla/Util.h" -#include "js/TemplateLib.h" #include "js/Utility.h" namespace js { @@ -68,15 +72,7 @@ class HashMap // HashMap construction is fallible (due to OOM); thus the user must call // init after constructing a HashMap and check the return value. - HashMap(AllocPolicy a = AllocPolicy()) - : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Key type must be relocatable"); - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Value type must be relocatable"); - } - + HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -142,18 +138,18 @@ class HashMap template bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } bool add(AddPtr &p, const Key &k) { Entry e(k, Value()); - return impl.add(p, Move(e)); + return impl.add(p, mozilla::Move(e)); } template bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.relookupOrAdd(p, k, Move(e)); + return impl.relookupOrAdd(p, k, mozilla::Move(e)); } // |all()| returns a Range containing |count()| elements. E.g.: @@ -203,10 +199,10 @@ class HashMap // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -235,7 +231,7 @@ class HashMap template bool putNew(const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.putNew(k, Move(e)); + return impl.putNew(k, mozilla::Move(e)); } // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. @@ -253,9 +249,17 @@ class HashMap remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const Key &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashMap is movable - HashMap(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashMap(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashMap is not copyable or assignable @@ -303,11 +307,7 @@ class HashSet // HashSet construction is fallible (due to OOM); thus the user must call // init after constructing a HashSet and check the return value. - HashSet(AllocPolicy a = AllocPolicy()) : impl(a) - { - MOZ_STATIC_ASSERT(tl::IsRelocatableHeapType::result, - "Set element type must be relocatable"); - } + HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} bool init(uint32_t len = 16) { return impl.init(len); } bool initialized() const { return impl.initialized(); } @@ -411,10 +411,10 @@ class HashSet // Don't just call |impl.sizeOfExcludingThis()| because there's no // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const { + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); } @@ -448,9 +448,17 @@ class HashSet remove(p); } + // Infallibly rekey one entry, if present. + void rekey(const Lookup &old_key, const T &new_key) { + if (old_key != new_key) { + if (Ptr p = lookup(old_key)) + impl.rekey(p, new_key, new_key); + } + } + // HashSet is movable - HashSet(MoveRef rhs) : impl(Move(rhs->impl)) {} - void operator=(MoveRef rhs) { impl = Move(rhs->impl); } + HashSet(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } private: // HashSet is not copyable or assignable @@ -532,7 +540,7 @@ struct DefaultHasher // Specialize hashing policy for pointer types. It assumes that the type is // at least word-aligned. For types with smaller size use PointerHasher. template -struct DefaultHasher : PointerHasher::result> +struct DefaultHasher : PointerHasher::value> {}; // For doubles, we can xor the two uint32s. @@ -542,18 +550,11 @@ struct DefaultHasher typedef double Lookup; static HashNumber hash(double d) { JS_STATIC_ASSERT(sizeof(HashNumber) == 4); - union { - struct { - uint32_t lo; - uint32_t hi; - } s; - double d; - } u; - u.d = d; - return u.s.lo ^ u.s.hi; + uint64_t u = mozilla::BitwiseCast(d); + return HashNumber(u ^ (u >> 32)); } static bool match(double lhs, double rhs) { - return lhs == rhs; + return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); } }; @@ -577,8 +578,8 @@ class HashMapEntry template HashMapEntry(const KeyInput &k, const ValueInput &v) : key(k), value(v) {} - HashMapEntry(MoveRef rhs) - : key(Move(rhs->key)), value(Move(rhs->value)) { } + HashMapEntry(mozilla::MoveRef rhs) + : key(mozilla::Move(rhs->key)), value(mozilla::Move(rhs->value)) { } typedef Key KeyType; typedef Value ValueType; @@ -647,8 +648,8 @@ class HashTableEntry } void swap(HashTableEntry *other) { - Swap(keyHash, other->keyHash); - Swap(mem, other->mem); + mozilla::Swap(keyHash, other->keyHash); + mozilla::Swap(mem, other->mem); } T &get() { JS_ASSERT(isLive()); return *mem.addr(); } @@ -807,10 +808,7 @@ class HashTable : private AllocPolicy // a new key at the new Lookup position. |front()| is invalid after // this operation until the next call to |popFront()|. void rekeyFront(const Lookup &l, const Key &k) { - typename HashTableEntry::NonConstT t(Move(this->cur->get())); - HashPolicy::setKey(t, const_cast(k)); - table.remove(*this->cur); - table.putNewInfallible(l, Move(t)); + table.rekey(*this->cur, l, k); rekeyed = true; this->validEntry = false; } @@ -832,13 +830,13 @@ class HashTable : private AllocPolicy }; // HashTable is movable - HashTable(MoveRef rhs) + HashTable(mozilla::MoveRef rhs) : AllocPolicy(*rhs) { mozilla::PodAssign(this, &*rhs); rhs->table = NULL; } - void operator=(MoveRef rhs) { + void operator=(mozilla::MoveRef rhs) { if (table) destroyTable(*this, table, capacity()); mozilla::PodAssign(this, &*rhs); @@ -882,7 +880,7 @@ class HashTable : private AllocPolicy # define METER(x) #endif - friend class js::ReentrancyGuard; + friend class mozilla::ReentrancyGuard; mutable mozilla::DebugOnly entered; mozilla::DebugOnly mutationCount; @@ -892,7 +890,7 @@ class HashTable : private AllocPolicy static const unsigned sMinCapacity = 1 << sMinCapacityLog2; static const unsigned sMaxInit = JS_BIT(23); static const unsigned sMaxCapacity = JS_BIT(24); - static const unsigned sHashBits = tl::BitSize::result; + static const unsigned sHashBits = mozilla::tl::BitSize::value; static const uint8_t sMinAlphaFrac = 64; // (0x100 * .25) static const uint8_t sMaxAlphaFrac = 192; // (0x100 * .75) static const uint8_t sInvMaxAlpha = 171; // (ceil(0x100 / .75) >> 1) @@ -1165,7 +1163,7 @@ class HashTable : private AllocPolicy for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) { if (src->isLive()) { HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive(hn, Move(src->get())); + findFreeEntry(hn).setLive(hn, mozilla::Move(src->get())); src->destroy(); } } @@ -1346,19 +1344,19 @@ class HashTable : private AllocPolicy return gen; } - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(table); } - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); } Ptr lookup(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); return Ptr(lookup(l, keyHash, 0)); } @@ -1371,7 +1369,7 @@ class HashTable : private AllocPolicy AddPtr lookupForAdd(const Lookup &l) const { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); HashNumber keyHash = prepareHash(l); Entry &entry = lookup(l, keyHash, sCollisionBit); AddPtr p(entry, keyHash); @@ -1382,7 +1380,7 @@ class HashTable : private AllocPolicy template bool add(AddPtr &p, const U &rhs) { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(mutationCount == p.mutationCount); JS_ASSERT(table); JS_ASSERT(!p.found()); @@ -1443,7 +1441,7 @@ class HashTable : private AllocPolicy { p.mutationCount = mutationCount; { - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); p.entry_ = &lookup(l, p.keyHash, sCollisionBit); } return p.found() || add(p, u); @@ -1452,17 +1450,27 @@ class HashTable : private AllocPolicy void remove(Ptr p) { JS_ASSERT(table); - ReentrancyGuard g(*this); + mozilla::ReentrancyGuard g(*this); JS_ASSERT(p.found()); remove(*p.entry_); checkUnderloaded(); } + void rekey(Ptr p, const Lookup &l, const Key &k) + { + JS_ASSERT(table); + mozilla::ReentrancyGuard g(*this); + JS_ASSERT(p.found()); + typename HashTableEntry::NonConstT t(mozilla::Move(*p)); + HashPolicy::setKey(t, const_cast(k)); + remove(*p.entry_); + putNewInfallible(l, mozilla::Move(t)); + } + #undef METER }; } // namespace detail } // namespace js -#endif // js_HashTable_h__ - +#endif /* js_HashTable_h */ diff --git a/external/spidermonkey/include/win32/js/HeapAPI.h b/external/spidermonkey/include/win32/js/HeapAPI.h index f0f4411ac9..4d739304bc 100644 --- a/external/spidermonkey/include/win32/js/HeapAPI.h +++ b/external/spidermonkey/include/win32/js/HeapAPI.h @@ -4,33 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_heap_api_h___ -#define js_heap_api_h___ +#ifndef js_HeapAPI_h +#define js_HeapAPI_h #include "jspubtd.h" +#include "js/Utility.h" + /* These values are private to the JS engine. */ namespace js { namespace gc { -/* - * Page size must be static to support our arena pointer optimizations, so we - * are forced to support each platform with non-4096 pages as a special case. - * Note: The freelist supports a maximum arena shift of 15. - * Note: Do not use JS_CPU_SPARC here, this header is used outside JS. - */ -#if (defined(SOLARIS) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ - (defined(__sparc) || defined(__sparcv9) || defined(__ia64)) -const size_t PageShift = 13; -const size_t ArenaShift = PageShift; -#elif defined(__powerpc64__) -const size_t PageShift = 16; const size_t ArenaShift = 12; -#else -const size_t PageShift = 12; -const size_t ArenaShift = PageShift; -#endif -const size_t PageSize = size_t(1) << PageShift; const size_t ArenaSize = size_t(1) << ArenaShift; const size_t ArenaMask = ArenaSize - 1; @@ -67,7 +52,7 @@ namespace shadow { struct ArenaHeader { - js::Zone *zone; + JS::Zone *zone; }; struct Zone @@ -153,10 +138,10 @@ IsIncrementalBarrierNeededOnGCThing(shadow::Runtime *rt, void *thing, JSGCTraceK { if (!rt->needsBarrier_) return false; - js::Zone *zone = GetGCThingZone(thing); + JS::Zone *zone = GetGCThingZone(thing); return reinterpret_cast(zone)->needsBarrier_; } } /* namespace JS */ -#endif /* js_heap_api_h___ */ +#endif /* js_HeapAPI_h */ diff --git a/external/spidermonkey/include/win32/js/LegacyIntTypes.h b/external/spidermonkey/include/win32/js/LegacyIntTypes.h index 387a68b9e9..2c8498c89e 100644 --- a/external/spidermonkey/include/win32/js/LegacyIntTypes.h +++ b/external/spidermonkey/include/win32/js/LegacyIntTypes.h @@ -17,13 +17,12 @@ * Indeed, if you use this header and third-party code defining these * types, *expect* to encounter either compile errors or link errors, * depending how these types are used and on the order of inclusion. - * It is safest to use only the JSAPI -style types, - * customizing those types using MOZ_CUSTOM_STDINT_H if necessary. + * It is safest to use only the types. */ -#ifndef PROTYPES_H -#define PROTYPES_H +#ifndef js_LegacyIntTypes_h +#define js_LegacyIntTypes_h -#include "mozilla/StandardInteger.h" +#include #include "js-config.h" @@ -57,4 +56,4 @@ typedef int16_t JSInt16; typedef int32_t JSInt32; typedef int64_t JSInt64; -#endif /* !defined(PROTYPES_H) */ +#endif /* js_LegacyIntTypes_h */ diff --git a/external/spidermonkey/include/win32/js/MemoryMetrics.h b/external/spidermonkey/include/win32/js/MemoryMetrics.h index 7e84f2ae11..ed61e1c427 100644 --- a/external/spidermonkey/include/win32/js/MemoryMetrics.h +++ b/external/spidermonkey/include/win32/js/MemoryMetrics.h @@ -10,6 +10,8 @@ // These declarations are not within jsapi.h because they are highly likely to // change in the future. Depend on them at your own risk. +#include "mozilla/MemoryReporting.h" + #include #include "jsalloc.h" @@ -91,7 +93,6 @@ struct TypeInferenceSizes // Data for tracking JIT-code memory usage. struct CodeSizes { - size_t jaeger; size_t ion; size_t asmJS; size_t baseline; @@ -136,7 +137,7 @@ struct RuntimeSizes size_t dtoa; size_t temporary; size_t regexpData; - size_t stack; + size_t interpreterStack; size_t gcMarker; size_t mathCache; size_t scriptData; @@ -153,9 +154,11 @@ struct ZoneStats gcHeapUnusedGcThings(0), gcHeapStringsNormal(0), gcHeapStringsShort(0), + gcHeapLazyScripts(0), gcHeapTypeObjects(0), gcHeapIonCodes(0), stringCharsNonHuge(0), + lazyScripts(0), typeObjects(0), typePool(0), hugeStrings() @@ -167,14 +170,16 @@ struct ZoneStats gcHeapUnusedGcThings(other.gcHeapUnusedGcThings), gcHeapStringsNormal(other.gcHeapStringsNormal), gcHeapStringsShort(other.gcHeapStringsShort), + gcHeapLazyScripts(other.gcHeapLazyScripts), gcHeapTypeObjects(other.gcHeapTypeObjects), gcHeapIonCodes(other.gcHeapIonCodes), stringCharsNonHuge(other.stringCharsNonHuge), + lazyScripts(other.lazyScripts), typeObjects(other.typeObjects), typePool(other.typePool), hugeStrings() { - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // Add other's numbers to this object's numbers. @@ -186,16 +191,18 @@ struct ZoneStats ADD(gcHeapStringsNormal); ADD(gcHeapStringsShort); + ADD(gcHeapLazyScripts); ADD(gcHeapTypeObjects); ADD(gcHeapIonCodes); ADD(stringCharsNonHuge); + ADD(lazyScripts); ADD(typeObjects); ADD(typePool); #undef ADD - hugeStrings.append(other.hugeStrings); + hugeStrings.appendAll(other.hugeStrings); } // This field can be used by embedders. @@ -207,10 +214,12 @@ struct ZoneStats size_t gcHeapStringsNormal; size_t gcHeapStringsShort; + size_t gcHeapLazyScripts; size_t gcHeapTypeObjects; size_t gcHeapIonCodes; size_t stringCharsNonHuge; + size_t lazyScripts; size_t typeObjects; size_t typePool; @@ -241,7 +250,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(0), shapesCompartmentTables(0), scriptData(0), - jaegerData(0), baselineData(0), baselineStubsFallback(0), baselineStubsOptimized(0), @@ -271,7 +279,6 @@ struct CompartmentStats shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids), shapesCompartmentTables(other.shapesCompartmentTables), scriptData(other.scriptData), - jaegerData(other.jaegerData), baselineData(other.baselineData), baselineStubsFallback(other.baselineStubsFallback), baselineStubsOptimized(other.baselineStubsOptimized), @@ -306,7 +313,6 @@ struct CompartmentStats size_t shapesExtraTreeShapeKids; size_t shapesCompartmentTables; size_t scriptData; - size_t jaegerData; size_t baselineData; size_t baselineStubsFallback; size_t baselineStubsOptimized; @@ -339,7 +345,6 @@ struct CompartmentStats ADD(shapesExtraTreeShapeKids); ADD(shapesCompartmentTables); ADD(scriptData); - ADD(jaegerData); ADD(baselineData); ADD(baselineStubsFallback); ADD(baselineStubsOptimized); @@ -360,7 +365,7 @@ struct CompartmentStats struct RuntimeStats { - RuntimeStats(JSMallocSizeOfFun mallocSizeOf) + RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) : runtime(), gcHeapChunkTotal(0), gcHeapDecommittedArenas(0), @@ -417,7 +422,7 @@ struct RuntimeStats ZoneStats *currZoneStats; - JSMallocSizeOfFun mallocSizeOf_; + mozilla::MallocSizeOf mallocSizeOf_; virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0; virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0; @@ -454,4 +459,4 @@ PeakSizeOfTemporary(const JSRuntime *rt); } // namespace JS -#endif // js_MemoryMetrics_h +#endif /* js_MemoryMetrics_h */ diff --git a/external/spidermonkey/include/win32/js/PropertyKey.h b/external/spidermonkey/include/win32/js/PropertyKey.h index 53158c26f3..c949db13a5 100644 --- a/external/spidermonkey/include/win32/js/PropertyKey.h +++ b/external/spidermonkey/include/win32/js/PropertyKey.h @@ -6,8 +6,8 @@ /* JS::PropertyKey implementation. */ -#ifndef js_PropertyKey_h___ -#define js_PropertyKey_h___ +#ifndef js_PropertyKey_h +#define js_PropertyKey_h #include "mozilla/Attributes.h" @@ -95,4 +95,4 @@ ToPropertyKey(JSContext *cx, HandleValue v, PropertyKey *key) } // namespace JS -#endif /* js_PropertyKey_h___ */ +#endif /* js_PropertyKey_h */ diff --git a/external/spidermonkey/include/win32/js/RequiredDefines.h b/external/spidermonkey/include/win32/js/RequiredDefines.h index 2be2efbf9a..6af9ca871b 100644 --- a/external/spidermonkey/include/win32/js/RequiredDefines.h +++ b/external/spidermonkey/include/win32/js/RequiredDefines.h @@ -10,8 +10,8 @@ * or SpiderMonkey public headers may not work correctly. */ -#ifndef js_RequiredDefines_h___ -#define js_RequiredDefines_h___ +#ifndef js_RequiredDefines_h +#define js_RequiredDefines_h /* * The c99 defining the limit macros (UINT32_MAX for example), says: @@ -20,4 +20,4 @@ */ #define __STDC_LIMIT_MACROS -#endif /* js_RequiredDefines_h___ */ +#endif /* js_RequiredDefines_h */ diff --git a/external/spidermonkey/include/win32/js/RootingAPI.h b/external/spidermonkey/include/win32/js/RootingAPI.h index 3e2e0d2a7c..99295f1238 100644 --- a/external/spidermonkey/include/win32/js/RootingAPI.h +++ b/external/spidermonkey/include/win32/js/RootingAPI.h @@ -4,14 +4,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsgc_root_h__ -#define jsgc_root_h__ +#ifndef js_RootingAPI_h +#define js_RootingAPI_h #include "mozilla/GuardObjects.h" #include "mozilla/TypeTraits.h" #include "js/Utility.h" -#include "js/TemplateLib.h" #include "jspubtd.h" @@ -99,9 +98,10 @@ namespace js { class Module; +class ScriptSourceObject; template -struct RootMethods {}; +struct GCMethods {}; template class RootedBase {}; @@ -112,6 +112,9 @@ class HandleBase {}; template class MutableHandleBase {}; +template +class HeapBase {}; + /* * js::NullPtr acts like a NULL pointer in contexts that require a Handle. * @@ -130,6 +133,10 @@ struct NullPtr static void * const constNullValue; }; +namespace gc { +struct Cell; +} /* namespace gc */ + } /* namespace js */ namespace JS { @@ -161,6 +168,204 @@ struct JS_PUBLIC_API(NullPtr) static void * const constNullValue; }; +/* + * The Heap class is a C/C++ heap-stored reference to a JS GC thing. All + * members of heap classes that refer to GC thing should use Heap (or + * possibly TenuredHeap, described below). + * + * Heap wraps the complex mechanisms required to ensure GC safety for the + * contained reference into a C++ class that behaves similarly to a normal + * pointer. + * + * GC references stored on the C/C++ stack must use Rooted/Handle/MutableHandle + * instead. + * + * Requirements for type T: + * - Must be one of: Value, jsid, JSObject*, JSString*, JSScript* + */ +template +class Heap : public js::HeapBase +{ + public: + Heap() { + static_assert(sizeof(T) == sizeof(Heap), + "Heap must be binary compatible with T."); + init(js::GCMethods::initial()); + } + explicit Heap(T p) { init(p); } + explicit Heap(const Heap &p) { init(p.ptr); } + + ~Heap() { + if (js::GCMethods::needsPostBarrier(ptr)) + relocate(); + } + + bool operator==(const Heap &other) { return ptr == other.ptr; } + bool operator!=(const Heap &other) { return ptr != other.ptr; } + + bool operator==(const T &other) const { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + + operator T() const { return ptr; } + T operator->() const { return ptr; } + const T *address() const { return &ptr; } + const T &get() const { return ptr; } + + T *unsafeGet() { return &ptr; } + + Heap &operator=(T p) { + set(p); + return *this; + } + + void set(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (js::GCMethods::needsPostBarrier(newPtr)) { + ptr = newPtr; + post(); + } else if (js::GCMethods::needsPostBarrier(ptr)) { + relocate(); /* Called before overwriting ptr. */ + ptr = newPtr; + } else { + ptr = newPtr; + } + } + + private: + void init(T newPtr) { + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + ptr = newPtr; + if (js::GCMethods::needsPostBarrier(ptr)) + post(); + } + + void post() { +#ifdef JSGC_GENERATIONAL + JS_ASSERT(js::GCMethods::needsPostBarrier(ptr)); + js::GCMethods::postBarrier(&ptr); +#endif + } + + void relocate() { +#ifdef JSGC_GENERATIONAL + js::GCMethods::relocate(&ptr); +#endif + } + + T ptr; +}; + +#ifdef DEBUG +/* + * For generational GC, assert that an object is in the tenured generation as + * opposed to being in the nursery. + */ +extern JS_FRIEND_API(void) +AssertGCThingMustBeTenured(JSObject* obj); +#else +inline void +AssertGCThingMustBeTenured(JSObject *obj) {} +#endif + +/* + * The TenuredHeap class is similar to the Heap class above in that it + * encapsulates the GC concerns of an on-heap reference to a JS object. However, + * it has two important differences: + * + * 1) Pointers which are statically known to only reference "tenured" objects + * can avoid the extra overhead of SpiderMonkey's write barriers. + * + * 2) Objects in the "tenured" heap have stronger alignment restrictions than + * those in the "nursery", so it is possible to store flags in the lower + * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged + * pointer with a nice API for accessing the flag bits and adds various + * assertions to ensure that it is not mis-used. + * + * GC things are said to be "tenured" when they are located in the long-lived + * heap: e.g. they have gained tenure as an object by surviving past at least + * one GC. For performance, SpiderMonkey allocates some things which are known + * to normally be long lived directly into the tenured generation; for example, + * global objects. Additionally, SpiderMonkey does not visit individual objects + * when deleting non-tenured objects, so object with finalizers are also always + * tenured; for instance, this includes most DOM objects. + * + * The considerations to keep in mind when using a TenuredHeap vs a normal + * Heap are: + * + * - It is invalid for a TenuredHeap to refer to a non-tenured thing. + * - It is however valid for a Heap to refer to a tenured thing. + * - It is not possible to store flag bits in a Heap. + */ +template +class TenuredHeap : public js::HeapBase +{ + public: + TenuredHeap() : bits(0) { + static_assert(sizeof(T) == sizeof(TenuredHeap), + "TenuredHeap must be binary compatible with T."); + } + explicit TenuredHeap(T p) : bits(0) { setPtr(p); } + explicit TenuredHeap(const TenuredHeap &p) : bits(0) { setPtr(p.ptr); } + + bool operator==(const TenuredHeap &other) { return bits == other.bits; } + bool operator!=(const TenuredHeap &other) { return bits != other.bits; } + + void setPtr(T newPtr) { + JS_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); + JS_ASSERT(!js::GCMethods::poisoned(newPtr)); + if (newPtr) + AssertGCThingMustBeTenured(newPtr); + bits = (bits & flagsMask) | reinterpret_cast(newPtr); + } + + void setFlags(uintptr_t flagsToSet) { + JS_ASSERT((flagsToSet & ~flagsMask) == 0); + bits |= flagsToSet; + } + + void unsetFlags(uintptr_t flagsToUnset) { + JS_ASSERT((flagsToUnset & ~flagsMask) == 0); + bits &= ~flagsToUnset; + } + + bool hasFlag(uintptr_t flag) const { + JS_ASSERT((flag & ~flagsMask) == 0); + return (bits & flag) != 0; + } + + T getPtr() const { return reinterpret_cast(bits & ~flagsMask); } + uintptr_t getFlags() const { return bits & flagsMask; } + + operator T() const { return getPtr(); } + T operator->() const { return getPtr(); } + + TenuredHeap &operator=(T p) { + setPtr(p); + return *this; + } + + /* + * Set the pointer to a value which will cause a crash if it is + * dereferenced. + */ + void setToCrashOnTouch() { + bits = (bits & flagsMask) | crashOnTouchPointer; + } + + bool isSetToCrashOnTouch() { + return (bits & ~flagsMask) == crashOnTouchPointer; + } + + private: + enum { + maskBits = 3, + flagsMask = (1 << maskBits) - 1, + crashOnTouchPointer = 1 << maskBits + }; + + uintptr_t bits; +}; + /* * Reference to a T that has been rooted elsewhere. This is most useful * as a parameter type, which guarantees that the T lvalue is properly @@ -170,7 +375,7 @@ struct JS_PUBLIC_API(NullPtr) * specialization, define a HandleBase specialization containing them. */ template -class MOZ_STACK_CLASS Handle : public js::HandleBase +class MOZ_NONHEAP_CLASS Handle : public js::HandleBase { friend class MutableHandle; @@ -180,20 +385,22 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase Handle(Handle handle, typename mozilla::EnableIf::value, int>::Type dummy = 0) { + static_assert(sizeof(Handle) == sizeof(T *), + "Handle must be binary compatible with T*."); ptr = reinterpret_cast(handle.address()); } /* Create a handle for a NULL pointer. */ Handle(js::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "js::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "js::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&js::NullPtr::constNullValue); } /* Create a handle for a NULL pointer. */ Handle(JS::NullPtr) { - MOZ_STATIC_ASSERT(mozilla::IsPointer::value, - "JS::NullPtr overload not valid for non-pointer types"); + static_assert(mozilla::IsPointer::value, + "JS::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&JS::NullPtr::constNullValue); } @@ -202,11 +409,19 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase } /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. + * Take care when calling this method! * - * Create a Handle from a raw location of a T. + * This creates a Handle from the raw location of a T. + * + * It should be called only if the following conditions hold: + * + * 1) the location of the T is guaranteed to be marked (for some reason + * other than being a Rooted), e.g., if it is guaranteed to be reachable + * from an implicit root. + * + * 2) the contents of the location are immutable, or at least cannot change + * for the lifetime of the handle, as its users may not expect its value + * to change underneath them. */ static Handle fromMarkedLocation(const T *p) { Handle h; @@ -230,13 +445,17 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase typename mozilla::EnableIf::value, int>::Type dummy = 0); const T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a Handle to something that + * takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } - bool operator!=(const T &other) { return *ptr != other; } - bool operator==(const T &other) { return *ptr == other; } + bool operator!=(const T &other) const { return *ptr != other; } + bool operator==(const T &other) const { return *ptr == other; } private: Handle() {} @@ -247,13 +466,14 @@ class MOZ_STACK_CLASS Handle : public js::HandleBase void operator=(S v) MOZ_DELETE; }; -typedef Handle HandleObject; -typedef Handle HandleModule; -typedef Handle HandleFunction; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleId; -typedef Handle HandleValue; +typedef Handle HandleObject; +typedef Handle HandleModule; +typedef Handle HandleScriptSource; +typedef Handle HandleFunction; +typedef Handle HandleScript; +typedef Handle HandleString; +typedef Handle HandleId; +typedef Handle HandleValue; /* * Similar to a handle, but the underlying storage can be changed. This is @@ -270,7 +490,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase inline MutableHandle(Rooted *root); void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -288,9 +508,13 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase } T *address() const { return ptr; } - T get() const { return *ptr; } + const T& get() const { return *ptr; } - operator T() const { return get(); } + /* + * Return a reference so passing a MutableHandle to something that takes + * a |const T&| is not a GC hazard. + */ + operator const T&() const { return get(); } T operator->() const { return get(); } private: @@ -298,8 +522,8 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase T *ptr; - template - void operator=(S v) MOZ_DELETE; + template void operator=(S v) MOZ_DELETE; + void operator=(MutableHandle other) MOZ_DELETE; }; typedef MutableHandle MutableHandleObject; @@ -309,6 +533,11 @@ typedef MutableHandle MutableHandleString; typedef MutableHandle MutableHandleId; typedef MutableHandle MutableHandleValue; +#ifdef JSGC_GENERATIONAL +JS_PUBLIC_API(void) HeapCellPostBarrier(js::gc::Cell **cellp); +JS_PUBLIC_API(void) HeapCellRelocate(js::gc::Cell **cellp); +#endif + } /* namespace JS */ namespace js { @@ -383,13 +612,28 @@ struct RootKind }; template -struct RootMethods +struct GCMethods { static T *initial() { return NULL; } static ThingRootKind kind() { return RootKind::rootKind(); } static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); } + static bool needsPostBarrier(T *v) { return v; } +#ifdef JSGC_GENERATIONAL + static void postBarrier(T **vp) { + JS::HeapCellPostBarrier(reinterpret_cast(vp)); + } + static void relocate(T **vp) { + JS::HeapCellRelocate(reinterpret_cast(vp)); + } +#endif }; +#if defined(DEBUG) +/* This helper allows us to assert that Rooted is scoped within a request. */ +extern JS_PUBLIC_API(bool) +IsInRequest(JSContext *cx); +#endif + } /* namespace js */ namespace JS { @@ -405,46 +649,63 @@ namespace JS { template class MOZ_STACK_CLASS Rooted : public js::RootedBase { - void init(JSContext *cxArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ContextFriendFields *cx = js::ContextFriendFields::get(cxArg); - commonInit(cx->thingGCRooters); -#endif - } + /* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */ + template + void init(CX *cx) { +#ifdef JSGC_TRACK_EXACT_ROOTS + js::ThingRootKind kind = js::GCMethods::kind(); + this->stack = &cx->thingGCRooters[kind]; + this->prev = *stack; + *stack = reinterpret_cast*>(this); - void init(js::PerThreadData *ptArg) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::PerThreadDataFriendFields *pt = js::PerThreadDataFriendFields::get(ptArg); - commonInit(pt->thingGCRooters); + JS_ASSERT(!js::GCMethods::poisoned(ptr)); #endif } public: Rooted(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - init(cx); + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); } Rooted(JSContext *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + MOZ_ASSERT(js::IsInRequest(cx)); + init(js::ContextFriendFields::get(cx)); + } + + Rooted(js::ContextFriendFields *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(cx); } - Rooted(js::PerThreadData *pt + Rooted(js::ContextFriendFields *cx, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(js::RootMethods::initial()) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(cx); + } + + Rooted(js::PerThreadDataFriendFields *pt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; init(pt); } - Rooted(js::PerThreadData *pt, T initial + Rooted(js::PerThreadDataFriendFields *pt, T initial MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { @@ -452,18 +713,38 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase init(pt); } + Rooted(JSRuntime *rt + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(js::GCMethods::initial()) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + + Rooted(JSRuntime *rt, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(initial) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + init(js::PerThreadDataFriendFields::getMainThread(rt)); + } + ~Rooted() { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS JS_ASSERT(*stack == reinterpret_cast*>(this)); *stack = prev; #endif } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted *previous() { return prev; } #endif - operator T() const { return ptr; } + /* + * Important: Return a reference here so passing a Rooted to + * something that takes a |const T&| is not a GC hazard. + */ + operator const T&() const { return ptr; } T operator->() const { return ptr; } T *address() { return &ptr; } const T *address() const { return &ptr; } @@ -471,7 +752,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!js::RootMethods::poisoned(value)); + JS_ASSERT(!js::GCMethods::poisoned(value)); ptr = value; return ptr; } @@ -481,28 +762,25 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } - - private: - void commonInit(Rooted **thingGCRooters) { -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) - js::ThingRootKind kind = js::RootMethods::kind(); - this->stack = &thingGCRooters[kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - - JS_ASSERT(!js::RootMethods::poisoned(ptr)); -#endif + void set(T value) { + JS_ASSERT(!js::GCMethods::poisoned(value)); + ptr = value; } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } + + private: +#ifdef JSGC_TRACK_EXACT_ROOTS Rooted **stack, *prev; #endif #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) /* Has the rooting analysis ever scanned this Rooted's stack location? */ friend void JS::CheckStackRoots(JSContext*); +#endif + +#ifdef JSGC_ROOT_ANALYSIS bool scanned; #endif @@ -523,13 +801,14 @@ template <> class Rooted; #endif -typedef Rooted RootedObject; -typedef Rooted RootedModule; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedId; -typedef Rooted RootedValue; +typedef Rooted RootedObject; +typedef Rooted RootedModule; +typedef Rooted RootedScriptSource; +typedef Rooted RootedFunction; +typedef Rooted RootedScript; +typedef Rooted RootedString; +typedef Rooted RootedId; +typedef Rooted RootedValue; } /* namespace JS */ @@ -549,8 +828,9 @@ class SkipRoot const uint8_t *start; const uint8_t *end; - template - void init(SkipRoot **head, const T *ptr, size_t count) { + template + void init(CX *cx, const T *ptr, size_t count) { + SkipRoot **head = &cx->skipGCRooters; this->stack = head; this->prev = *stack; *stack = this; @@ -559,23 +839,6 @@ class SkipRoot } public: - template - SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(&ContextFriendFields::get(cx)->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - template - SkipRoot(js::PerThreadData *ptd, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - PerThreadDataFriendFields *ptff = PerThreadDataFriendFields::get(ptd); - init(&ptff->skipGCRooters, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~SkipRoot() { JS_ASSERT(*stack == this); *stack = prev; @@ -589,22 +852,36 @@ class SkipRoot #else /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {} + public: + +#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(ContextFriendFields::get(cx), ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } template - SkipRoot(PerThreadData *ptd, const T *ptr, size_t count = 1 + SkipRoot(ContextFriendFields *cx, const T *ptr, size_t count = 1 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { + init(cx, ptr, count); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } -#endif /* DEBUG && JSGC_ROOT_ANALYSIS */ + template + SkipRoot(PerThreadData *pt, const T *ptr, size_t count = 1 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + { + init(PerThreadDataFriendFields::get(pt), ptr, count); + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -614,15 +891,17 @@ template class FakeRooted : public RootedBase { public: - FakeRooted(JSContext *cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : ptr(RootMethods::initial()) + template + FakeRooted(CX *cx + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : ptr(GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } - FakeRooted(JSContext *cx, T initial - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + template + FakeRooted(CX *cx, T initial + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : ptr(initial) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; @@ -636,13 +915,13 @@ class FakeRooted : public RootedBase const T &get() const { return ptr; } T &operator=(T value) { - JS_ASSERT(!RootMethods::poisoned(value)); + JS_ASSERT(!GCMethods::poisoned(value)); ptr = value; return ptr; } - bool operator!=(const T &other) { return ptr != other; } - bool operator==(const T &other) { return ptr == other; } + bool operator!=(const T &other) const { return ptr != other; } + bool operator==(const T &other) const { return ptr == other; } private: T ptr; @@ -666,7 +945,7 @@ class FakeMutableHandle : public js::MutableHandleBase } void set(T v) { - JS_ASSERT(!js::RootMethods::poisoned(v)); + JS_ASSERT(!js::GCMethods::poisoned(v)); *ptr = v; } @@ -727,13 +1006,11 @@ template class MaybeRooted typedef FakeMutableHandle MutableHandleType; static inline JS::Handle toHandle(HandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::Handle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - JS_NOT_REACHED("Bad conversion"); - return JS::MutableHandle::fromMarkedLocation(NULL); + MOZ_ASSUME_UNREACHABLE("Bad conversion"); } }; @@ -761,6 +1038,8 @@ template inline MutableHandle::MutableHandle(Rooted *root) { + static_assert(sizeof(MutableHandle) == sizeof(T *), + "MutableHandle must be binary compatible with T*."); ptr = root->address(); } @@ -779,10 +1058,6 @@ inline void MaybeCheckStackRoots(JSContext *cx) #endif } -namespace gc { -struct Cell; -} /* namespace gc */ - /* Base class for automatic read-only object rooting during compilation. */ class CompilerRootNode { @@ -801,4 +1076,4 @@ class CompilerRootNode } /* namespace js */ -#endif /* jsgc_root_h___ */ +#endif /* js_RootingAPI_h */ diff --git a/external/spidermonkey/include/win32/js/TemplateLib.h b/external/spidermonkey/include/win32/js/TemplateLib.h deleted file mode 100644 index a4ff682912..0000000000 --- a/external/spidermonkey/include/win32/js/TemplateLib.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_template_lib_h__ -#define js_template_lib_h__ - -#include "jstypes.h" - -/* - * Library of reusable template meta-functions (that is, functions on types and - * compile-time values). Meta-functions are placed inside the 'tl' namespace to - * avoid conflict with non-meta functions that logically have the same name - * (e.g., js::tl::Min vs. js::Min). - */ - -namespace js { -namespace tl { - -/* Compute min/max/clamp. */ -template struct Min { - static const size_t result = i < j ? i : j; -}; -template struct Max { - static const size_t result = i > j ? i : j; -}; -template struct Clamp { - static const size_t result = i < min ? min : (i > max ? max : i); -}; - -/* Compute x^y. */ -template struct Pow { - static const size_t result = x * Pow::result; -}; -template struct Pow { - static const size_t result = 1; -}; - -/* Compute floor(log2(i)). */ -template struct FloorLog2 { - static const size_t result = 1 + FloorLog2::result; -}; -template <> struct FloorLog2<0> { /* Error */ }; -template <> struct FloorLog2<1> { static const size_t result = 0; }; - -/* Compute ceiling(log2(i)). */ -template struct CeilingLog2 { - static const size_t result = FloorLog2<2 * i - 1>::result; -}; - -/* Round up to the nearest power of 2. */ -template struct RoundUpPow2 { - static const size_t result = size_t(1) << CeilingLog2::result; -}; -template <> struct RoundUpPow2<0> { - static const size_t result = 1; -}; - -/* Compute the number of bits in the given unsigned type. */ -template struct BitSize { - static const size_t result = sizeof(T) * JS_BITS_PER_BYTE; -}; - -/* - * Produce an N-bit mask, where N <= BitSize::result. Handle the - * language-undefined edge case when N = BitSize::result. - */ -template struct NBitMask { - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |result| to assure - // its computation. - static const size_t checkPrecondition = 0 / size_t(N < BitSize::result); - static const size_t result = (size_t(1) << N) - 1 + checkPrecondition; -}; -template <> struct NBitMask::result> { - static const size_t result = size_t(-1); -}; - -/* - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template struct MulOverflowMask { - static const size_t result = - ~NBitMask::result - CeilingLog2::result>::result; -}; -template <> struct MulOverflowMask<0> { /* Error */ }; -template <> struct MulOverflowMask<1> { static const size_t result = 0; }; - -/* - * Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized - * array of T's is big enough to cause a ptrdiff_t overflow when subtracting - * a pointer to the end of the array from the beginning. - */ -template struct UnsafeRangeSizeMask { - /* - * The '2' factor means the top bit is clear, sizeof(T) converts from - * units of elements to bytes. - */ - static const size_t result = MulOverflowMask<2 * sizeof(T)>::result; -}; - -template struct If { static const T result = v1; }; -template struct If { static const T result = v2; }; - -/* - * Traits class for identifying types that are implicitly barriered. - */ -template struct IsRelocatableHeapType { static const bool result = true; }; - -} /* namespace tl */ -} /* namespace js */ - -#endif /* js_template_lib_h__ */ diff --git a/external/spidermonkey/include/win32/js/Utility.h b/external/spidermonkey/include/win32/js/Utility.h index c4ebf7ced6..9d391e5c8a 100644 --- a/external/spidermonkey/include/win32/js/Utility.h +++ b/external/spidermonkey/include/win32/js/Utility.h @@ -4,13 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_utility_h__ -#define js_utility_h__ +#ifndef js_Utility_h +#define js_Utility_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" +#include "mozilla/Move.h" #include "mozilla/Scoped.h" +#include "mozilla/TemplateLib.h" #include #include @@ -22,8 +24,6 @@ #include "jstypes.h" -#include "js/TemplateLib.h" - /* The public JS engine namespace. */ namespace JS {} @@ -41,7 +41,6 @@ namespace js {} #define JS_ASSERT(expr) MOZ_ASSERT(expr) #define JS_ASSERT_IF(cond, expr) MOZ_ASSERT_IF(cond, expr) -#define JS_NOT_REACHED(reason) MOZ_NOT_REACHED(reason) #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr) #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr) @@ -63,7 +62,7 @@ namespace js {} # define JS_DIAGNOSTICS_ASSERT(expr) ((void) 0) #endif -#define JS_STATIC_ASSERT(cond) MOZ_STATIC_ASSERT(cond, "JS_STATIC_ASSERT") +#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") #define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") extern MOZ_NORETURN JS_PUBLIC_API(void) @@ -84,10 +83,11 @@ extern JS_PUBLIC_API(void) JS_Abort(void); #else # ifdef DEBUG /* - * In order to test OOM conditions, when the shell command-line option - * |-A NUM| is passed, we fail continuously after the NUM'th allocation. + * In order to test OOM conditions, when the testing function + * oomAfterAllocations COUNT is passed, we fail continuously after the NUM'th + * allocation from now. */ -extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set from shell/js.cpp */ +extern JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations; /* set in builtins/TestingFunctions.cpp */ extern JS_PUBLIC_DATA(uint32_t) OOM_counter; /* data race, who cares. */ #ifdef JS_OOM_DO_BACKTRACES @@ -157,6 +157,12 @@ static JS_INLINE void* js_calloc(size_t bytes) return calloc(bytes, 1); } +static JS_INLINE void* js_calloc(size_t nmemb, size_t size) +{ + JS_OOM_POSSIBLY_FAIL(); + return calloc(nmemb, size); +} + static JS_INLINE void* js_realloc(void* p, size_t bytes) { JS_OOM_POSSIBLY_FAIL(); @@ -169,205 +175,6 @@ static JS_INLINE void js_free(void* p) } #endif/* JS_USE_CUSTOM_ALLOCATOR */ -JS_BEGIN_EXTERN_C - -/* - * Replace bit-scanning code sequences with CPU-specific instructions to - * speedup calculations of ceiling/floor log2. - * - * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129. - * - * SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856. - */ -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) - -unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); -unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward,_BitScanReverse) - -__forceinline static int -__BitScanForward32(unsigned int val) -{ - unsigned long idx; - - _BitScanForward(&idx, (unsigned long)val); - return (int)idx; -} -__forceinline static int -__BitScanReverse32(unsigned int val) -{ - unsigned long idx; - - _BitScanReverse(&idx, (unsigned long)val); - return (int)(31-idx); -} -# define js_bitscan_ctz32(val) __BitScanForward32(val) -# define js_bitscan_clz32(val) __BitScanReverse32(val) -# define JS_HAS_BUILTIN_BITSCAN32 - -#if defined(_M_AMD64) || defined(_M_X64) -unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask); -unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask); -# pragma intrinsic(_BitScanForward64,_BitScanReverse64) - -__forceinline static int -__BitScanForward64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanForward64(&idx, val); - return (int)idx; -} -__forceinline static int -__BitScanReverse64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanReverse64(&idx, val); - return (int)(63-idx); -} -# define js_bitscan_ctz64(val) __BitScanForward64(val) -# define js_bitscan_clz64(val) __BitScanReverse64(val) -# define JS_HAS_BUILTIN_BITSCAN64 -#endif -#elif MOZ_IS_GCC - -#if MOZ_GCC_VERSION_AT_LEAST(3, 4, 0) -# define USE_BUILTIN_CTZ -#endif - -#elif defined(__clang__) - -#if __has_builtin(__builtin_ctz) -# define USE_BUILTIN_CTZ -#endif - -#endif - -#if defined(USE_BUILTIN_CTZ) -# define js_bitscan_ctz32(val) __builtin_ctz(val) -# define js_bitscan_clz32(val) __builtin_clz(val) -# define JS_HAS_BUILTIN_BITSCAN32 -# if (JS_BYTES_PER_WORD == 8) -# define js_bitscan_ctz64(val) __builtin_ctzll(val) -# define js_bitscan_clz64(val) __builtin_clzll(val) -# define JS_HAS_BUILTIN_BITSCAN64 -# endif - -# undef USE_BUILTIN_CTZ - -#endif - -/* -** Macro version of JS_CeilingLog2: Compute the log of the least power of -** 2 greater than or equal to _n. The result is returned in _log2. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)). - * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is - * undefined. - */ -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - unsigned int j_ = (unsigned int)(_n); \ - (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \ - JS_END_MACRO -#else -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) & ((j_)-1)) \ - (_log2) += 1; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -/* -** Macro version of JS_FloorLog2: Compute the log of the greatest power of -** 2 less than or equal to _n. The result is returned in _log2. -** -** This is equivalent to finding the highest set bit in the word. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)). - * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1 - * to ensure 0 result when _n == 0. - */ -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \ - JS_END_MACRO -#else -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - uint32_t j_ = (uint32_t)(_n); \ - (_log2) = 0; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -#if JS_BYTES_PER_WORD == 4 -# ifdef JS_HAS_BUILTIN_BITSCAN32 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#elif JS_BYTES_PER_WORD == 8 -# ifdef JS_HAS_BUILTIN_BITSCAN64 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) -# else -JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); -# endif -#else -# error "NOT SUPPORTED" -#endif - -JS_END_EXTERN_C - -/* - * Internal function. - * Compute the log of the least power of 2 greater than or equal to n. This is - * a version of JS_CeilingLog2 that operates on unsigned integers with - * CPU-dependant size. - */ -#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) - -/* - * Internal function. - * Compute the log of the greatest power of 2 less than or equal to n. - * This is a version of JS_FloorLog2 that operates on unsigned integers with - * CPU-dependant size and requires that n != 0. - */ -static MOZ_ALWAYS_INLINE size_t -JS_FLOOR_LOG2W(size_t n) -{ - JS_ASSERT(n != 0); - return js_FloorLog2wImpl(n); -} - /* * JS_ROTATE_LEFT32 * @@ -552,7 +359,7 @@ template static JS_ALWAYS_INLINE T * js_pod_malloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_malloc(numElems * sizeof(T)); } @@ -561,7 +368,7 @@ template static JS_ALWAYS_INLINE T * js_pod_calloc(size_t numElems) { - if (numElems & js::tl::MulOverflowMask::result) + if (numElems & mozilla::tl::MulOverflowMask::value) return NULL; return (T *)js_calloc(numElems * sizeof(T)); } @@ -595,175 +402,6 @@ SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) namespace js { -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables also need to - * be resized. - * - * The details of the optimization, and whether it's worth applying, vary from - * one type to the next. And while some constructor calls are moves, many really - * are copies, and can't be optimized this way. So we need: - * - * 1) a way for a particular invocation of a copy constructor to say that it's - * really a move, and that the value of the original isn't important - * afterwards (althought it must still be safe to destroy); and - * - * 2) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation. - * - * The Move(T &) function takes a reference to a T, and returns an MoveRef - * referring to the same value; that's 1). An MoveRef is simply a reference - * to a T, annotated to say that a copy constructor applied to it may move that - * T, instead of copying it. Finally, a constructor that accepts an MoveRef - * should perform a more efficient move, instead of a copy, providing 2). - * - * So, where we might define a copy constructor for a class C like this: - * - * C(const C &rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(MoveRef rhs) { ... move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)) - * - * Note that MoveRef implicitly converts to T &, so you can pass an - * MoveRef to an ordinary copy constructor for a type that doesn't support a - * special move constructor, and you'll just get a copy. This means that - * templates can use Move whenever they know they won't use the original value - * any more, even if they're not sure whether the type at hand has a specialized - * move constructor. If it doesn't, the MoveRef will just convert to a T &, - * and the ordinary copy constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator, - * which runs this's destructor, and then applies the move constructor to - * *this's memory. A typical definition: - * - * C &operator=(MoveRef rhs) { - * this->~C(); - * new(this) C(rhs); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * This header file defines MoveRef and Move in the js namespace. It's up to - * individual containers to annotate moves as such, by calling Move; and it's up - * to individual types to define move constructors. - * - * One hint: if you're writing a move constructor where the type has members - * that should be moved themselves, it's much nicer to write this: - * - * C(MoveRef c) : x(c->x), y(c->y) { } - * - * than the equivalent: - * - * C(MoveRef c) { new(&x) X(c->x); new(&y) Y(c->y); } - * - * especially since GNU C++ fails to notice that this does indeed initialize x - * and y, which may matter if they're const. - */ -template -class MoveRef { - public: - typedef T Referent; - explicit MoveRef(T &t) : pointer(&t) { } - T &operator*() const { return *pointer; } - T *operator->() const { return pointer; } - operator T& () const { return *pointer; } - private: - T *pointer; -}; - -template -MoveRef Move(T &t) { return MoveRef(t); } - -template -MoveRef Move(const T &t) { return MoveRef(const_cast(t)); } - -/* Useful for implementing containers that assert non-reentrancy */ -class ReentrancyGuard -{ - /* ReentrancyGuard is not copyable. */ - ReentrancyGuard(const ReentrancyGuard &); - void operator=(const ReentrancyGuard &); - -#ifdef DEBUG - bool &entered; -#endif - public: - template -#ifdef DEBUG - ReentrancyGuard(T &obj) - : entered(obj.entered) -#else - ReentrancyGuard(T &/*obj*/) -#endif - { -#ifdef DEBUG - JS_ASSERT(!entered); - entered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - entered = false; -#endif - } -}; - -template -JS_ALWAYS_INLINE static void -Swap(T &t, T &u) -{ - T tmp(Move(t)); - t = Move(u); - u = Move(tmp); -} - -/* - * Round x up to the nearest power of 2. This function assumes that the most - * significant bit of x is not set, which would lead to overflow. - */ -JS_ALWAYS_INLINE size_t -RoundUpPow2(size_t x) -{ - return size_t(1) << JS_CEILING_LOG2W(x); -} - /* Integral types for all hash functions. */ typedef uint32_t HashNumber; const unsigned HashNumberSizeBits = 32; @@ -845,11 +483,6 @@ inline bool IsPoisonedPtr(T *v) } -/* - * This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|. - */ -typedef size_t(*JSMallocSizeOfFun)(const void *p); - /* sixgill annotation defines */ #ifndef HAVE_STATIC_ANNOTATIONS # define HAVE_STATIC_ANNOTATIONS @@ -891,4 +524,4 @@ typedef size_t(*JSMallocSizeOfFun)(const void *p); # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) #endif /* HAVE_STATIC_ANNOTATIONS */ -#endif /* js_utility_h__ */ +#endif /* js_Utility_h */ diff --git a/external/spidermonkey/include/win32/js/Value.h b/external/spidermonkey/include/win32/js/Value.h index 2c7fa1a600..9b2c5dd6f9 100644 --- a/external/spidermonkey/include/win32/js/Value.h +++ b/external/spidermonkey/include/win32/js/Value.h @@ -6,8 +6,8 @@ /* JS::Value implementation. */ -#ifndef js_Value_h___ -#define js_Value_h___ +#ifndef js_Value_h +#define js_Value_h #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" @@ -53,7 +53,7 @@ namespace JS { class Value; } * nice symbolic type tags, however we can only do this when we can force the * underlying type of the enum to be the desired size. */ -#if defined(__cplusplus) && !defined(__SUNPRO_CC) && !defined(__xlC__) +#if !defined(__SUNPRO_CC) && !defined(__xlC__) #if defined(_MSC_VER) # define JS_ENUM_HEADER(id, type) enum id : type @@ -132,7 +132,7 @@ JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64_t)); #endif -#else /* defined(__cplusplus) */ +#else /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ typedef uint8_t JSValueType; #define JSVAL_TYPE_DOUBLE ((uint8_t)0x00) @@ -180,7 +180,7 @@ typedef uint64_t JSValueShiftedTag; #define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) #endif /* JS_BITS_PER_WORD */ -#endif /* defined(__cplusplus) && !defined(__SUNPRO_CC) */ +#endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT @@ -265,7 +265,7 @@ typedef union jsval_layout typedef union jsval_layout { uint64_t asBits; -#if (!defined(_WIN64) && defined(__cplusplus)) +#if !defined(_WIN64) /* MSVC does not pack these correctly :-( */ struct { uint64_t payload47 : 47; @@ -321,7 +321,6 @@ typedef union jsval_layout int32_t i32; uint32_t u32; JSWhyMagic why; - uintptr_t word; } payload; } s; double asDouble; @@ -803,22 +802,31 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) #endif /* JS_BITS_PER_WORD */ -static inline double -JS_CANONICALIZE_NAN(double d) -{ - if (MOZ_UNLIKELY(d != d)) { - jsval_layout l; - l.asBits = 0x7FF8000000000000LL; - return l.asDouble; - } - return d; -} - static inline jsval_layout JSVAL_TO_IMPL(JS::Value v); static inline JS::Value IMPL_TO_JSVAL(jsval_layout l); namespace JS { +/** + * Returns a generic quiet NaN value, with all payload bits set to zero. + * + * Among other properties, this NaN's bit pattern conforms to JS::Value's + * bit pattern restrictions. + */ +static MOZ_ALWAYS_INLINE double +GenericNaN() +{ + return mozilla::SpecificNaN(0, 0x8000000000000ULL); +} + +static inline double +CanonicalizeNaN(double d) +{ + if (MOZ_UNLIKELY(mozilla::IsNaN(d))) + return GenericNaN(); + return d; +} + /* * JS::Value is the interface for a single JavaScript Engine value. A few * general notes on JS::Value: @@ -1393,22 +1401,35 @@ SameType(const Value &lhs, const Value &rhs) /************************************************************************/ +#ifdef JSGC_GENERATIONAL +namespace JS { +JS_PUBLIC_API(void) HeapValuePostBarrier(Value *valuep); +JS_PUBLIC_API(void) HeapValueRelocate(Value *valuep); +} +#endif + namespace js { -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } }; -template <> struct RootMethods +template <> struct GCMethods { static JS::Value initial() { return JS::UndefinedValue(); } static ThingRootKind kind() { return THING_ROOT_VALUE; } static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); } + static bool needsPostBarrier(const JS::Value &v) { return v.isMarkable(); } +#ifdef JSGC_GENERATIONAL + static void postBarrier(JS::Value *v) { JS::HeapValuePostBarrier(v); } + static void relocate(JS::Value *v) { JS::HeapValueRelocate(v); } +#endif }; +template class UnbarrieredMutableValueOperations; template class MutableValueOperations; /* @@ -1420,7 +1441,9 @@ template class MutableValueOperations; template class ValueOperations { + friend class UnbarrieredMutableValueOperations; friend class MutableValueOperations; + const JS::Value * value() const { return static_cast(this)->extract(); } public: @@ -1453,19 +1476,22 @@ class ValueOperations void *toGCThing() const { return value()->toGCThing(); } JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); } + uint32_t toPrivateUint32() const { return value()->toPrivateUint32(); } JSWhyMagic whyMagic() const { return value()->whyMagic(); } }; /* - * A class designed for CRTP use in implementing the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible extractMutable() and extract() - * methods returning the const Value* and Value* abstracted by Outer. + * A class designed for CRTP use in implementing the mutating parts of the Value + * interface in Value-like classes that don't need post barriers. Outer must be + * a class inheriting UnbarrieredMutableValueOperations with visible + * extractMutable() and extract() methods returning the const Value* and Value* + * abstracted by Outer. */ template -class MutableValueOperations : public ValueOperations +class UnbarrieredMutableValueOperations : public ValueOperations { + friend class MutableValueOperations; JS::Value * value() { return static_cast(this)->extractMutable(); } public: @@ -1473,14 +1499,66 @@ class MutableValueOperations : public ValueOperations void setUndefined() { value()->setUndefined(); } void setInt32(int32_t i) { value()->setInt32(i); } void setDouble(double d) { value()->setDouble(d); } - void setString(JSString *str) { value()->setString(str); } - void setString(const JS::Anchor &str) { value()->setString(str); } - void setObject(JSObject &obj) { value()->setObject(obj); } void setBoolean(bool b) { value()->setBoolean(b); } void setMagic(JSWhyMagic why) { value()->setMagic(why); } bool setNumber(uint32_t ui) { return value()->setNumber(ui); } bool setNumber(double d) { return value()->setNumber(d); } - void setObjectOrNull(JSObject *arg) { value()->setObjectOrNull(arg); } +}; + +/* + * A class designed for CRTP use in implementing all the mutating parts of the + * Value interface in Value-like classes. Outer must be a class inheriting + * MutableValueOperations with visible extractMutable() and extract() + * methods returning the const Value* and Value* abstracted by Outer. + */ +template +class MutableValueOperations : public UnbarrieredMutableValueOperations +{ + public: + void setString(JSString *str) { this->value()->setString(str); } + void setString(const JS::Anchor &str) { this->value()->setString(str); } + void setObject(JSObject &obj) { this->value()->setObject(obj); } + void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); } +}; + +/* + * Augment the generic Heap interface when T = Value with + * type-querying, value-extracting, and mutating operations. + */ +template <> +class HeapBase : public UnbarrieredMutableValueOperations > +{ + typedef JS::Heap Outer; + + friend class ValueOperations; + friend class UnbarrieredMutableValueOperations; + + const JS::Value * extract() const { return static_cast(this)->address(); } + JS::Value * extractMutable() { return static_cast(this)->unsafeGet(); } + + /* + * Setters that potentially change the value to a GC thing from a non-GC + * thing must call JS::Heap::set() to trigger the post barrier. + * + * Changing from a GC thing to a non-GC thing value will leave the heap + * value in the store buffer, but it will be ingored so this is not a + * problem. + */ + void setBarriered(const JS::Value &v) { + static_cast *>(this)->set(v); + } + + public: + void setString(JSString *str) { setBarriered(JS::StringValue(str)); } + void setString(const JS::Anchor &str) { setBarriered(JS::StringValue(str.get())); } + void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); } + + void setObjectOrNull(JSObject *arg) { + if (arg) + setObject(*arg); + else + setNull(); + } }; /* @@ -1508,6 +1586,7 @@ class MutableHandleBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1526,6 +1605,7 @@ class RootedBase : public MutableValueOperations*>(this)->address(); } + friend class UnbarrieredMutableValueOperations >; friend class MutableValueOperations >; JS::Value * extractMutable() { return static_cast*>(this)->address(); @@ -1574,12 +1654,12 @@ inline Anchor::~Anchor() namespace detail { struct ValueAlignmentTester { char c; JS::Value v; }; -MOZ_STATIC_ASSERT(sizeof(ValueAlignmentTester) == 16, - "JS::Value must be 16-byte-aligned"); +static_assert(sizeof(ValueAlignmentTester) == 16, + "JS::Value must be 16-byte-aligned"); struct LayoutAlignmentTester { char c; jsval_layout l; }; -MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, - "jsval_layout must be 16-byte-aligned"); +static_assert(sizeof(LayoutAlignmentTester) == 16, + "jsval_layout must be 16-byte-aligned"); } // namespace detail #endif /* DEBUG */ @@ -1593,8 +1673,8 @@ MOZ_STATIC_ASSERT(sizeof(LayoutAlignmentTester) == 16, */ typedef JS::Value jsval; -MOZ_STATIC_ASSERT(sizeof(jsval_layout) == sizeof(JS::Value), - "jsval_layout and JS::Value must have identical layouts"); +static_assert(sizeof(jsval_layout) == sizeof(JS::Value), + "jsval_layout and JS::Value must have identical layouts"); /************************************************************************/ @@ -1762,4 +1842,4 @@ JSVAL_TO_PRIVATE(jsval v) return JSVAL_TO_PRIVATE_PTR_IMPL(JSVAL_TO_IMPL(v)); } -#endif /* js_Value_h___ */ +#endif /* js_Value_h */ diff --git a/external/spidermonkey/include/win32/js/Vector.h b/external/spidermonkey/include/win32/js/Vector.h index 5f40dd634b..b14d75c758 100644 --- a/external/spidermonkey/include/win32/js/Vector.h +++ b/external/spidermonkey/include/win32/js/Vector.h @@ -4,14 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsvector_h_ -#define jsvector_h_ +#ifndef js_Vector_h +#define js_Vector_h -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "TemplateLib.h" -#include "Utility.h" +#include "mozilla/Vector.h" /* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ #ifdef _MSC_VER @@ -23,1085 +19,48 @@ namespace js { class TempAllocPolicy; -template +// using Vector = mozilla::Vector; +// +// ...and get rid of all the CRTP madness in mozilla::Vector(Base). But we +// can't because compiler support's not up to snuff. (Template aliases are in +// gcc 4.7 and clang 3.0 and are expected to be in MSVC 2013.) Instead, have a +// completely separate class inheriting from mozilla::Vector, and throw CRTP at +// the problem til things work. +// +// This workaround presents a couple issues. First, because js::Vector is a +// distinct type from mozilla::Vector, overload resolution, method calls, etc. +// are affected. *Hopefully* this won't be too bad in practice. (A bunch of +// places had to be fixed when mozilla::Vector was introduced, but it wasn't a +// crazy number.) Second, mozilla::Vector's interface has to be made subclass- +// ready via CRTP -- or rather, via mozilla::VectorBase, which basically no one +// should use. :-) Third, we have to redefine the constructors and the non- +// inherited operators. Blech. Happily there aren't too many of these, so it +// isn't the end of the world. + +template -class Vector; - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that cap*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring - * this. - */ -template -static bool CapacityHasExcessSpace(size_t cap) +class Vector + : public mozilla::VectorBase > { - size_t size = cap * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* Destroys constructed objects in the range [begin, end). */ - static inline void destroy(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - p->~T(); - } - - /* Constructs objects in the uninitialized range [begin, end). */ - static inline void initialize(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - /* - * Copy-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(*p); - } - - /* - * Move-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(Move(*p)); - } - - /* - * Copy-constructs objects in the uninitialized range [dst, dst+n) from the - * same object u. - */ - template - static inline void copyConstructN(T *dst, size_t n, const U &u) { - for (T *end = dst + n; dst != end; ++dst) - new(dst) T(u); - } - - /* - * Grows the given buffer to have capacity newCap, preserving the objects - * constructed in the range [begin, end) and updating v. Assumes that (1) - * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will - * not overflow. - */ - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); - if (!newbuf) - return false; - for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src) - new(dst) T(Move(*src)); - VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); - v.free_(v.mBegin); - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - static inline void destroy(T *, T *) {} - - static inline void initialize(T *begin, T *end) { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(begin, 0, sizeof(T) * (end-begin)); - */ - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); - */ - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - *dst = *p; - } - - template - static inline void moveConstruct(T *dst, const U *srcbeg, const U *srcend) { - copyConstruct(dst, srcbeg, srcend); - } - - static inline void copyConstructN(T *dst, size_t n, const T &t) { - for (T *p = dst, *end = dst + n; p != end; ++p) - *p = t; - } - - static inline bool growTo(Vector &v, size_t newCap) { - JS_ASSERT(!v.usingInlineStorage()); - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - size_t oldSize = sizeof(T) * v.mCapacity; - size_t newSize = sizeof(T) * newCap; - T *newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); - if (!newbuf) - return false; - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newCap; - return true; - } -}; - -/* - * JS-friendly, STL-like container providing a short-lived, dynamic buffer. - * Vector calls the constructors/destructors of all elements stored in - * its internal buffer, so non-PODs may be safely used. Additionally, - * Vector will store the first N elements in-place before resorting to - * dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * N requirements: - * - any value, however, N is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in jsalloc.h (default js::TempAllocPolicy) - * - * N.B: Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object. - */ -template -class Vector : private AllocPolicy -{ - // typedef typename tl::StaticAssert::result>::result _; - - /* utilities */ - - static const bool sElemIsPod = mozilla::IsPod::value; - typedef VectorImpl Impl; - friend struct VectorImpl; - - bool growStorageBy(size_t incr); - bool convertToHeapStorage(size_t newCap); - - template inline bool growByImpl(size_t inc); - - /* magic constants */ - - static const int sMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are - * 0 inline elements. This allows us to compile when the definition - * of the element type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so - * in order to keep everything here, we use a dummy template - * parameter with partial specialization. - */ - template - struct ElemSize { - static const size_t result = sizeof(T); - }; - template - struct ElemSize<0, Dummy> { - static const size_t result = 1; - }; - - static const size_t sInlineCapacity = - tl::Min::result>::result; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t sInlineBytes = - tl::Max<1, sInlineCapacity * ElemSize::result>::result; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T *mBegin; - size_t mLength; /* Number of elements in the Vector. */ - size_t mCapacity; /* Max number of elements storable in the Vector without resizing. */ -#ifdef DEBUG - size_t mReserved; /* Max elements of reserved or used space in this vector. */ -#endif - - mozilla::AlignedStorage storage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool entered; -#endif - - Vector(const Vector &) MOZ_DELETE; - Vector &operator=(const Vector &) MOZ_DELETE; - - /* private accessors */ - - bool usingInlineStorage() const { - return mBegin == inlineStorage(); - } - - T *inlineStorage() const { - return (T *)storage.addr(); - } - - T *beginNoCheck() const { - return mBegin; - } - - T *endNoCheck() { - return mBegin + mLength; - } - - const T *endNoCheck() const { - return mBegin + mLength; - } - -#ifdef DEBUG - size_t reserved() const { - JS_ASSERT(mReserved <= mCapacity); - JS_ASSERT(mLength <= mReserved); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U u); - void internalAppendN(const T &t, size_t n); - template void internalAppend(const U *begin, size_t length); - template void internalAppend(const Vector &other); + typedef typename mozilla::VectorBase Base; public: - static const size_t sMaxInlineStorage = N; - - typedef T ElementType; - - Vector(AllocPolicy = AllocPolicy()); - Vector(MoveRef); /* Move constructor. */ - Vector &operator=(MoveRef); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy &allocPolicy() const { - return *this; + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector &operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); } - - AllocPolicy &allocPolicy() { - return *this; - } - - enum { InlineLength = N }; - - size_t length() const { - return mLength; - } - - bool empty() const { - return mLength == 0; - } - - size_t capacity() const { - return mCapacity; - } - - T *begin() { - JS_ASSERT(!entered); - return mBegin; - } - - const T *begin() const { - JS_ASSERT(!entered); - return mBegin; - } - - T *end() { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - const T *end() const { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - T &operator[](size_t i) { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - const T &operator[](size_t i) const { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - T &back() { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - const T &back() const { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - class Range { - friend class Vector; - T *cur_, *end_; - Range(T *cur, T *end) : cur_(cur), end_(end) {} - public: - Range() {} - bool empty() const { return cur_ == end_; } - size_t remain() const { return end_ - cur_; } - T &front() const { return *cur_; } - void popFront() { JS_ASSERT(!empty()); ++cur_; } - T popCopyFront() { JS_ASSERT(!empty()); return *cur_++; } - }; - - Range all() { - return Range(begin(), end()); - } - - /* mutators */ - - /* Given that the Vector is empty and has no inline storage, grow to |capacity|. */ - bool initCapacity(size_t request); - - /* If reserve(length() + N) succeeds, the N next appends are guaranteed to succeed. */ - bool reserve(size_t request); - - /* - * Destroy elements in the range [end() - incr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t incr); - - /* Grow the vector by incr elements. */ - bool growBy(size_t incr); - - /* Call shrinkBy or growBy based on whether newSize > length(). */ - bool resize(size_t newLength); - - /* Leave new elements as uninitialized memory. */ - bool growByUninitialized(size_t incr); - bool resizeUninitialized(size_t newLength); - - /* Shorthand for shrinkBy(length()). */ - void clear(); - - /* Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /* If true, appending |needed| elements will not call realloc(). */ - bool canAppendWithoutRealloc(size_t needed) const; - - /* - * Potentially fallible append operations. - * - * The function templates that take an unspecified type U require a - * const T & or a MoveRef. The MoveRef variants move their - * operands into the vector, instead of copying them. If they fail, the - * operand is left unmoved. - */ - template bool append(U t); - bool appendN(const T &t, size_t n); - template bool append(const U *begin, const U *end); - template bool append(const U *begin, size_t length); - template bool append(const Vector &other); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. - */ - template void infallibleAppend(const U &u) { - internalAppend(u); - } - void infallibleAppendN(const T &t, size_t n) { - internalAppendN(t, n); - } - template void infallibleAppend(const U *aBegin, const U *aEnd) { - internalAppend(aBegin, mozilla::PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U *aBegin, size_t aLength) { - internalAppend(aBegin, aLength); - } - template void infallibleAppend(const Vector &other) { - internalAppend(other); - } - - void popBack(); - - T popCopy(); - - /* - * Transfers ownership of the internal buffer used by Vector to the caller. - * After this call, the Vector is empty. Since the returned buffer may need - * to be allocated (if the elements are currently stored in-place), the - * call can fail, returning NULL. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - T *extractRawBuffer(); - - /* - * Transfer ownership of an array of objects into the Vector. - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T *p, size_t length); - - /* - * Places |val| at position |p|, shifting existing elements from |p| - * onward one position higher. On success, |p| should not be reused - * because it will be a dangling pointer if reallocation of the vector - * storage occurred; the return value should be used instead. On failure, - * NULL is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) - * - * - */ - T *insert(T *p, const T &val); - - /* - * Removes the element |t|, which must fall in the bounds [begin, end), - * shifting existing elements from |t + 1| onward one position lower. - */ - void erase(T *t); - - /* - * Measure the size of the Vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - /* - * Like sizeOfExcludingThis, but also measures the size of the Vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const; - - void swap(Vector &other); }; -/* This does the re-entrancy check plus several other sanity checks. */ -#define REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - JS_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ - JS_ASSERT(reserved() <= mCapacity); \ - JS_ASSERT(mLength <= reserved()); \ - JS_ASSERT(mLength <= mCapacity) +} // namespace js -/* Vector Implementation */ - -template -JS_ALWAYS_INLINE -Vector::Vector(AllocPolicy ap) - : AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0), - mCapacity(sInlineCapacity) -#ifdef DEBUG - , mReserved(sInlineCapacity), entered(false) -#endif -{} - -/* Move constructor. */ -template -JS_ALWAYS_INLINE -Vector::Vector(MoveRef rhs) - : AllocPolicy(rhs) -#ifdef DEBUG - , entered(false) -#endif -{ - mLength = rhs->mLength; - mCapacity = rhs->mCapacity; -#ifdef DEBUG - mReserved = rhs->mReserved; -#endif - - if (rhs->usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = (T *)storage.addr(); - Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); - /* - * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = rhs->mBegin; - rhs->mBegin = (T *) rhs->storage.addr(); - rhs->mCapacity = sInlineCapacity; - rhs->mLength = 0; -#ifdef DEBUG - rhs->mReserved = sInlineCapacity; -#endif - } -} - -/* Move assignment. */ -template -JS_ALWAYS_INLINE -Vector & -Vector::operator=(MoveRef rhs) -{ - this->~Vector(); - new(this) Vector(rhs); - return *this; -} - -template -JS_ALWAYS_INLINE -Vector::~Vector() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); -} - -/* - * This function will create a new heap buffer with capacity newCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t newCap) -{ - JS_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - JS_ASSERT(!CapacityHasExcessSpace(newCap)); - T *newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); - if (!newBuf) - return false; - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = newCap; - return true; -} - -template -JS_NEVER_INLINE bool -Vector::growStorageBy(size_t incr) -{ - JS_ASSERT(mLength + incr > mCapacity); - JS_ASSERT_IF(!usingInlineStorage(), !CapacityHasExcessSpace(mCapacity)); - - /* - * When choosing a new capacity, its size should is as close to 2^N bytes - * as possible. 2^N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2^N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2^N request size. - */ - - size_t newCap; - - if (incr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::result; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength*4*sizeof(T) overflow? This condition limits a Vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. - * It also ensures that the ((char *)end() - (char *)begin()) does not - * overflow ptrdiff_t (see Bug 510319). - */ - if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::result) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is - * already as close to 2^N as sizeof(T) will allow. Just double the - * capacity, and then there might be space for one more element. - */ - newCap = mLength * 2; - if (CapacityHasExcessSpace(newCap)) - newCap += 1; - - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + incr; - - /* Did mLength+incr overflow? Will newCap*sizeof(T) overflow? */ - if (newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { - convert: - return convertToHeapStorage(newCap); - } - - grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t request) -{ - JS_ASSERT(empty()); - JS_ASSERT(usingInlineStorage()); - if (request == 0) - return true; - T *newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); - if (!newbuf) - return false; - mBegin = newbuf; - mCapacity = request; -#ifdef DEBUG - mReserved = request; -#endif - return true; -} - -template -inline bool -Vector::reserve(size_t request) -{ - REENTRANCY_GUARD_ET_AL; - if (request > mCapacity && !growStorageBy(request - mLength)) - return false; - -#ifdef DEBUG - if (request > mReserved) - mReserved = request; - JS_ASSERT(mLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(incr <= mLength); - Impl::destroy(endNoCheck() - incr, endNoCheck()); - mLength -= incr; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::growByImpl(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - if (incr > mCapacity - mLength && !growStorageBy(incr)) - return false; - - JS_ASSERT(mLength + incr <= mCapacity); - T *newend = endNoCheck() + incr; - if (InitNewElems) - Impl::initialize(endNoCheck(), newend); - mLength += incr; -#ifdef DEBUG - if (mLength > mReserved) - mReserved = mLength; -#endif - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::growBy(size_t incr) -{ - return growByImpl(incr); -} - -template -JS_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t incr) -{ - return growByImpl(incr); -} - -template -STATIC_POSTCONDITION(!return || ubound(this->begin()) >= newLength) -inline bool -Vector::resize(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growBy(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growByUninitialized(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -inline void -Vector::clear() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) - return; - - this->free_(beginNoCheck()); - mBegin = (T *)storage.addr(); - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t needed) const -{ - return mLength + needed <= mCapacity; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(U t) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity && !growStorageBy(1)) - return false; - -#ifdef DEBUG - if (mLength + 1 > mReserved) - mReserved = mLength + 1; -#endif - internalAppend(t); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(U u) -{ - JS_ASSERT(mLength + 1 <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - new(endNoCheck()) T(u); - ++mLength; -} - -template -JS_ALWAYS_INLINE bool -Vector::appendN(const T &t, size_t needed) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppendN(t, needed); - return true; -} - -template -JS_ALWAYS_INLINE void -Vector::internalAppendN(const T &t, size_t needed) -{ - JS_ASSERT(mLength + needed <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), needed, t); - mLength += needed; -} - -template -inline T * -Vector::insert(T *p, const T &val) -{ - JS_ASSERT(begin() <= p && p <= end()); - size_t pos = p - begin(); - JS_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(val)) - return NULL; - } else { - T oldBack = back(); - if (!append(oldBack)) /* Dup the last element. */ - return NULL; - for (size_t i = oldLength; i > pos; --i) - (*this)[i] = (*this)[i - 1]; - (*this)[pos] = val; - } - return begin() + pos; -} - -template -inline void -Vector::erase(T *it) -{ - JS_ASSERT(begin() <= it && it < end()); - while (it + 1 != end()) { - *it = *(it + 1); - ++it; - } - popBack(); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, const U *insEnd) -{ - REENTRANCY_GUARD_ET_AL; - size_t needed = mozilla::PointerRangeSize(insBegin, insEnd); - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - -#ifdef DEBUG - if (mLength + needed > mReserved) - mReserved = mLength + needed; -#endif - internalAppend(insBegin, needed); - return true; -} - -template -template -JS_ALWAYS_INLINE void -Vector::internalAppend(const U *insBegin, size_t insLength) -{ - JS_ASSERT(mLength + insLength <= mReserved); - JS_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); - mLength += insLength; -} - -template -template -inline bool -Vector::append(const Vector &other) -{ - return append(other.begin(), other.end()); -} - -template -template -inline void -Vector::internalAppend(const Vector &other) -{ - internalAppend(other.begin(), other.length()); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, size_t insLength) -{ - return this->append(insBegin, insBegin + insLength); -} - -template -JS_ALWAYS_INLINE void -Vector::popBack() -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -JS_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T * -Vector::extractRawBuffer() -{ - T *ret; - if (usingInlineStorage()) { - ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); - if (!ret) - return NULL; - Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - /* mBegin, mCapacity are unchanged. */ - mLength = 0; - } else { - ret = mBegin; - mBegin = (T *)storage.addr(); - mLength = 0; - mCapacity = sInlineCapacity; -#ifdef DEBUG - mReserved = sInlineCapacity; -#endif - } - return ret; -} - -template -inline void -Vector::replaceRawBuffer(T *p, size_t aLength) -{ - REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free_(beginNoCheck()); - - /* Take in the new buffer. */ - if (aLength <= sInlineCapacity) { - /* - * We convert to inline storage if possible, even though p might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = (T *)storage.addr(); - mLength = aLength; - mCapacity = sInlineCapacity; - Impl::moveConstruct(mBegin, p, p + aLength); - Impl::destroy(p, p + aLength); - this->free_(p); - } else { - mBegin = p; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const -{ - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); -} - -template -inline void -Vector::swap(Vector &other) -{ - // TODO Implement N != 0 - JS_STATIC_ASSERT(N == 0); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && other.usingInlineStorage()) { - other.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !other.usingInlineStorage()) { - mBegin = other.mBegin; - other.mBegin = other.inlineStorage(); - } else if (!usingInlineStorage() && !other.usingInlineStorage()) { - Swap(mBegin, other.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, other.mLength); - Swap(mCapacity, other.mCapacity); -#ifdef DEBUG - Swap(mReserved, other.mReserved); -#endif -} - -} /* namespace js */ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* jsvector_h_ */ +#endif /* js_Vector_h */ diff --git a/external/spidermonkey/include/win32/jsalloc.h b/external/spidermonkey/include/win32/jsalloc.h index e7e64fc540..3abc4966d1 100644 --- a/external/spidermonkey/include/win32/jsalloc.h +++ b/external/spidermonkey/include/win32/jsalloc.h @@ -4,32 +4,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsalloc_h_ -#define jsalloc_h_ +/* JS allocation policies. */ + +#ifndef jsalloc_h +#define jsalloc_h + +#include "mozilla/AllocPolicy.h" #include "js/Utility.h" -#include "jstypes.h" struct JSContext; namespace js { -/* - * Allocation policies. These model the concept: - * - public copy constructor, assignment, destructor - * - void *malloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *calloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *realloc_(size_t) - * Responsible for OOM reporting on NULL return value. - * The *used* bytes of the previous buffer is passed in - * (rather than the old allocation size), in addition to - * the *new* allocation size requested. - * - void free_(void *) - * - reportAllocOverflow() - * Called on overflow before the container returns NULL. - */ +class ContextFriendFields; /* Policy for using system memory functions and doing no error reporting. */ class SystemAllocPolicy @@ -53,7 +41,7 @@ class SystemAllocPolicy */ class TempAllocPolicy { - JSContext *const cx_; + ContextFriendFields *const cx_; /* * Non-inline helper to call JSRuntime::onOutOfMemory with minimal @@ -62,11 +50,8 @@ class TempAllocPolicy JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes); public: - TempAllocPolicy(JSContext *cx) : cx_(cx) {} - - JSContext *context() const { - return cx_; - } + TempAllocPolicy(JSContext *cx) : cx_((ContextFriendFields *) cx) {} // :( + TempAllocPolicy(ContextFriendFields *cx) : cx_(cx) {} void *malloc_(size_t bytes) { void *p = js_malloc(bytes); @@ -98,4 +83,4 @@ class TempAllocPolicy } /* namespace js */ -#endif /* jsalloc_h_ */ +#endif /* jsalloc_h */ diff --git a/external/spidermonkey/include/win32/jsapi.h.REMOVED.git-id b/external/spidermonkey/include/win32/jsapi.h.REMOVED.git-id index db9dbac6b4..27b6bbed78 100644 --- a/external/spidermonkey/include/win32/jsapi.h.REMOVED.git-id +++ b/external/spidermonkey/include/win32/jsapi.h.REMOVED.git-id @@ -1 +1 @@ -0ec74a6f5f2aa9bbaa6a8cbf6e2ae95ec7c4ee43 \ No newline at end of file +e14ea931f699b1808c06886e55e977c9819f3774 \ No newline at end of file diff --git a/external/spidermonkey/include/win32/jsclass.h b/external/spidermonkey/include/win32/jsclass.h index c9b53c7679..def641715d 100644 --- a/external/spidermonkey/include/win32/jsclass.h +++ b/external/spidermonkey/include/win32/jsclass.h @@ -4,14 +4,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclass_h__ -#define jsclass_h__ +#ifndef jsclass_h +#define jsclass_h /* * A JSClass acts as a vtable for JS objects that allows JSAPI clients to * control various aspects of the behavior of an object like property lookup. * js::Class is an engine-private extension that allows more control over * object behavior and, e.g., allows custom slow layout. */ + #include "jsapi.h" #include "jsprvtd.h" @@ -21,6 +22,10 @@ class PropertyName; class SpecialId; class PropertyId; +// This is equal to JSFunction::class_. Use it in places where you don't want +// to #include jsfun.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionClassPtr; + static JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid); @@ -195,7 +200,7 @@ typedef void const char *name; \ uint32_t flags; \ \ - /* Mandatory non-null function pointer members. */ \ + /* Mandatory function pointer members. */ \ JSPropertyOp addProperty; \ JSDeletePropertyOp delProperty; \ JSPropertyOp getProperty; \ @@ -203,9 +208,9 @@ typedef void JSEnumerateOp enumerate; \ JSResolveOp resolve; \ JSConvertOp convert; \ - FinalizeOp finalize; \ \ - /* Optionally non-null members start here. */ \ + /* Optional members (may be null). */ \ + FinalizeOp finalize; \ JSCheckAccessOp checkAccess; \ JSNative call; \ JSHasInstanceOp hasInstance; \ @@ -214,7 +219,7 @@ typedef void /* * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much - * we have to padd js::Class to match the size of JSClass; + * we have to pad js::Class to match the size of JSClass. */ struct ClassSizeMeasurement { @@ -312,8 +317,9 @@ struct Class return flags & JSCLASS_EMULATES_UNDEFINED; } - /* Defined in jsfuninlines.h */ - inline bool isCallable() const; + bool isCallable() const { + return this == js::FunctionClassPtr || call; + } static size_t offsetOfFlags() { return offsetof(Class, flags); } }; @@ -387,7 +393,7 @@ IsPoisonedSpecialId(js::SpecialId iden) return false; } -template <> struct RootMethods +template <> struct GCMethods { static SpecialId initial() { return SpecialId(); } static ThingRootKind kind() { return THING_ROOT_ID; } @@ -396,4 +402,4 @@ template <> struct RootMethods } /* namespace js */ -#endif /* jsclass_h__ */ +#endif /* jsclass_h */ diff --git a/external/spidermonkey/include/win32/jsclist.h b/external/spidermonkey/include/win32/jsclist.h index 8782307fa4..23da9b8cd5 100644 --- a/external/spidermonkey/include/win32/jsclist.h +++ b/external/spidermonkey/include/win32/jsclist.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsclist_h___ -#define jsclist_h___ +#ifndef jsclist_h +#define jsclist_h #include "jstypes.h" @@ -104,4 +104,4 @@ typedef struct JSCListStr { #define JS_INIT_STATIC_CLIST(_l) \ {(_l), (_l)} -#endif /* jsclist_h___ */ +#endif /* jsclist_h */ diff --git a/external/spidermonkey/include/win32/jscpucfg.h b/external/spidermonkey/include/win32/jscpucfg.h index 6bb62b420f..c79bd7ad14 100644 --- a/external/spidermonkey/include/win32/jscpucfg.h +++ b/external/spidermonkey/include/win32/jscpucfg.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef js_cpucfg___ -#define js_cpucfg___ +#ifndef jscpucfg_h +#define jscpucfg_h #define JS_HAVE_LONG_LONG @@ -114,4 +114,4 @@ # endif #endif -#endif /* js_cpucfg___ */ +#endif /* jscpucfg_h */ diff --git a/external/spidermonkey/include/win32/jsdbgapi.h b/external/spidermonkey/include/win32/jsdbgapi.h index 4907d913a0..0ce7101337 100644 --- a/external/spidermonkey/include/win32/jsdbgapi.h +++ b/external/spidermonkey/include/win32/jsdbgapi.h @@ -4,12 +4,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsdbgapi_h___ -#define jsdbgapi_h___ +#ifndef jsdbgapi_h +#define jsdbgapi_h /* * JS debugger API. */ -#include "jsapi.h" + #include "jsprvtd.h" namespace JS { @@ -111,7 +111,7 @@ JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapHandler *handlerp, jsval *closurep); extern JS_PUBLIC_API(void) -JS_ClearScriptTraps(JSContext *cx, JSScript *script); +JS_ClearScriptTraps(JSRuntime *rt, JSScript *script); extern JS_PUBLIC_API(void) JS_ClearAllTrapsForCompartment(JSContext *cx); @@ -224,12 +224,6 @@ JS_GetScriptLineExtent(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(JSVersion) JS_GetScriptVersion(JSContext *cx, JSScript *script); -extern JS_PUBLIC_API(bool) -JS_GetScriptUserBit(JSScript *script); - -extern JS_PUBLIC_API(void) -JS_SetScriptUserBit(JSScript *script, bool b); - extern JS_PUBLIC_API(bool) JS_GetScriptIsSelfHosted(JSScript *script); @@ -433,9 +427,6 @@ JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); /************************************************************************/ -extern JS_FRIEND_API(void) -js_RevertVersion(JSContext *cx); - extern JS_PUBLIC_API(const JSDebugHooks *) JS_GetGlobalDebugHooks(JSRuntime *rt); @@ -465,4 +456,4 @@ JS_DumpCompartmentPCCounts(JSContext *cx); extern JS_FRIEND_API(JSBool) js_CallContextDebugHandler(JSContext *cx); -#endif /* jsdbgapi_h___ */ +#endif /* jsdbgapi_h */ diff --git a/external/spidermonkey/include/win32/jsdhash.h b/external/spidermonkey/include/win32/jsdhash.h deleted file mode 100644 index 1f7830fd2b..0000000000 --- a/external/spidermonkey/include/win32/jsdhash.h +++ /dev/null @@ -1,612 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef jsdhash_h___ -#define jsdhash_h___ - -/* - * Double hashing, a la Knuth 6. - * - * Try to keep this file in sync with xpcom/glue/pldhash.h. - */ -#include "jstypes.h" -#include "jsutil.h" - -#if defined(__GNUC__) && defined(__i386__) && !defined(XP_OS2) -#define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall)) -#elif defined(XP_WIN) -#define JS_DHASH_FASTCALL __fastcall -#else -#define JS_DHASH_FASTCALL -#endif - -#ifdef DEBUG_XXXbrendan -#define JS_DHASHMETER 1 -#endif - -/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ -#undef JS_DHASH_SIZE_LIMIT -#define JS_DHASH_SIZE_LIMIT JS_BIT(24) - -/* Minimum table size, or gross entry count (net is at most .75 loaded). */ -#ifndef JS_DHASH_MIN_SIZE -#define JS_DHASH_MIN_SIZE 16 -#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0 -#error "JS_DHASH_MIN_SIZE must be a power of two!" -#endif - -/* - * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - * expressed as a fixed-point 32-bit fraction. - */ -#define JS_DHASH_BITS 32 -#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U - -/* Primitive and forward-struct typedefs. */ -typedef uint32_t JSDHashNumber; -typedef struct JSDHashEntryHdr JSDHashEntryHdr; -typedef struct JSDHashEntryStub JSDHashEntryStub; -typedef struct JSDHashTable JSDHashTable; -typedef struct JSDHashTableOps JSDHashTableOps; - -/* - * Table entry header structure. - * - * In order to allow in-line allocation of key and value, we do not declare - * either here. Instead, the API uses const void *key as a formal parameter. - * The key need not be stored in the entry; it may be part of the value, but - * need not be stored at all. - * - * Callback types are defined below and grouped into the JSDHashTableOps - * structure, for single static initialization per hash table sub-type. - * - * Each hash table sub-type should nest the JSDHashEntryHdr structure at the - * front of its particular entry type. The keyHash member contains the result - * of multiplying the hash code returned from the hashKey callback (see below) - * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 - * and 1 values. The stored keyHash value is table size invariant, and it is - * maintained automatically by JS_DHashTableOperate -- users should never set - * it, and its only uses should be via the entry macros below. - * - * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor - * removed. An entry may be either busy or free; if busy, it may be live or - * removed. Consumers of this API should not access members of entries that - * are not live. - * - * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries - * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a - * non-live, busy (i.e., removed) entry pointer to its caller. See below for - * more details on JS_DHashTableOperate's calling rules. - */ -struct JSDHashEntryHdr { - JSDHashNumber keyHash; /* every entry must begin like this */ -}; - -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_FREE(JSDHashEntryHdr* entry) -{ - return entry->keyHash == 0; -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_BUSY(JSDHashEntryHdr* entry) -{ - return !JS_DHASH_ENTRY_IS_FREE(entry); -} -MOZ_ALWAYS_INLINE bool -JS_DHASH_ENTRY_IS_LIVE(JSDHashEntryHdr* entry) -{ - return entry->keyHash >= 2; -} - -/* - * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead) - * on most architectures, and may be allocated on the stack or within another - * structure or class (see below for the Init and Finish functions to use). - * - * To decide whether to use double hashing vs. chaining, we need to develop a - * trade-off relation, as follows: - * - * Let alpha be the load factor, esize the entry size in words, count the - * entry count, and pow2 the power-of-two table size in entries. - * - * (JSDHashTable overhead) > (JSHashTable overhead) - * (unused table entry space) > (malloc and .next overhead per entry) + - * (buckets overhead) - * (1 - alpha) * esize * pow2 > 2 * count + pow2 - * - * Notice that alpha is by definition (count / pow2): - * - * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2 - * (1 - alpha) * esize > 2 * alpha + 1 - * - * esize > (1 + 2 * alpha) / (1 - alpha) - * - * This assumes both tables must keep keyHash, key, and value for each entry, - * where key and value point to separately allocated strings or structures. - * If key and value can be combined into one pointer, then the trade-off is: - * - * esize > (1 + 3 * alpha) / (1 - alpha) - * - * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type - * that must be allocated separately and referenced by an entry.value pointer - * member, and provided key's allocation can be fused with its entry's, then - * k (the words wasted per entry with chaining) is 4. - * - * To see these curves, feed gnuplot input like so: - * - * gnuplot> f(x,k) = (1 + k * x) / (1 - x) - * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4) - * - * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4 - * words for chaining to be more space-efficient than double hashing. - * - * Solving for alpha helps us decide when to shrink an underloaded table: - * - * esize > (1 + k * alpha) / (1 - alpha) - * esize - alpha * esize > 1 + k * alpha - * esize - 1 > (k + esize) * alpha - * (esize - 1) / (k + esize) > alpha - * - * alpha < (esize - 1) / (esize + k) - * - * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k), - * assuming esize is not too large (in which case, chaining should probably be - * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3 - * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5 - * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below. - * - * The current implementation uses a configurable lower bound on alpha, which - * defaults to .25, when deciding to shrink the table (while still respecting - * JS_DHASH_MIN_SIZE). - * - * Note a qualitative difference between chaining and double hashing: under - * chaining, entry addresses are stable across table shrinks and grows. With - * double hashing, you can't safely hold an entry pointer and use it after an - * ADD or REMOVE operation, unless you sample table->generation before adding - * or removing, and compare the sample after, dereferencing the entry pointer - * only if table->generation has not changed. - * - * The moral of this story: there is no one-size-fits-all hash table scheme, - * but for small table entry size, and assuming entry address stability is not - * required, double hashing wins. - */ -struct JSDHashTable { - const JSDHashTableOps *ops; /* virtual operations, see below */ - void *data; /* ops- and instance-specific data */ - int16_t hashShift; /* multiplicative hash shift */ - uint8_t maxAlphaFrac; /* 8-bit fixed point max alpha */ - uint8_t minAlphaFrac; /* 8-bit fixed point min alpha */ - uint32_t entrySize; /* number of bytes in an entry */ - uint32_t entryCount; /* number of entries in table */ - uint32_t removedCount; /* removed entry sentinels in table */ - uint32_t generation; /* entry storage generation number */ - char *entryStore; /* entry storage */ -#ifdef JS_DHASHMETER - struct JSDHashStats { - uint32_t searches; /* total number of table searches */ - uint32_t steps; /* hash chain links traversed */ - uint32_t hits; /* searches that found key */ - uint32_t misses; /* searches that didn't find key */ - uint32_t lookups; /* number of JS_DHASH_LOOKUPs */ - uint32_t addMisses; /* adds that miss, and do work */ - uint32_t addOverRemoved; /* adds that recycled a removed entry */ - uint32_t addHits; /* adds that hit an existing entry */ - uint32_t addFailures; /* out-of-memory during add growth */ - uint32_t removeHits; /* removes that hit, and do work */ - uint32_t removeMisses; /* useless removes that miss */ - uint32_t removeFrees; /* removes that freed entry directly */ - uint32_t removeEnums; /* removes done by Enumerate */ - uint32_t grows; /* table expansions */ - uint32_t shrinks; /* table contractions */ - uint32_t compresses; /* table compressions */ - uint32_t enumShrinks; /* contractions after Enumerate */ - } stats; -#endif -}; - -/* - * Size in entries (gross, not net of free and removed sentinels) for table. - * We store hashShift rather than sizeLog2 to optimize the collision-free case - * in SearchTable. - */ -#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift) - -/* - * Table space at entryStore is allocated and freed using these callbacks. - * The allocator should return null on error only (not if called with nbytes - * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). - */ -typedef void * -(* JSDHashAllocTable)(JSDHashTable *table, uint32_t nbytes); - -typedef void -(* JSDHashFreeTable) (JSDHashTable *table, void *ptr); - -/* - * Compute the hash code for a given key to be looked up, added, or removed - * from table. A hash code may have any JSDHashNumber value. - */ -typedef JSDHashNumber -(* JSDHashHashKey) (JSDHashTable *table, const void *key); - -/* - * Compare the key identifying entry in table with the provided key parameter. - * Return JS_TRUE if keys match, JS_FALSE otherwise. - */ -typedef JSBool -(* JSDHashMatchEntry)(JSDHashTable *table, const JSDHashEntryHdr *entry, - const void *key); - -/* - * Copy the data starting at from to the new entry storage at to. Do not add - * reference counts for any strong references in the entry, however, as this - * is a "move" operation: the old entry storage at from will be freed without - * any reference-decrementing callback shortly. - */ -typedef void -(* JSDHashMoveEntry)(JSDHashTable *table, const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -/* - * Clear the entry and drop any strong references it holds. This callback is - * invoked during a JS_DHASH_REMOVE operation (see below for operation codes), - * but only if the given key is found in the table. - */ -typedef void -(* JSDHashClearEntry)(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Called when a table (whether allocated dynamically by itself, or nested in - * a larger structure, or allocated on the stack) is finished. This callback - * allows table->ops-specific code to finalize table->data. - */ -typedef void -(* JSDHashFinalize) (JSDHashTable *table); - -/* - * Initialize a new entry, apart from keyHash. This function is called when - * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the - * given key, and must add a new one. At that point, entry->keyHash is not - * set yet, to avoid claiming the last free entry in a severely overloaded - * table. - */ -typedef JSBool -(* JSDHashInitEntry)(JSDHashTable *table, JSDHashEntryHdr *entry, - const void *key); - -/* - * Finally, the "vtable" structure for JSDHashTable. The first eight hooks - * must be provided by implementations; they're called unconditionally by the - * generic jsdhash.c code. Hooks after these may be null. - * - * Summary of allocation-related hook usage with C++ placement new emphasis: - * allocTable Allocate raw bytes with malloc, no ctors run. - * freeTable Free raw bytes with free, no dtors run. - * initEntry Call placement new using default key-based ctor. - * Return JS_TRUE on success, JS_FALSE on error. - * moveEntry Call placement new using copy ctor, run dtor on old - * entry storage. - * clearEntry Run dtor on entry. - * finalize Stub unless table->data was initialized and needs to - * be finalized. - * - * Note the reason why initEntry is optional: the default hooks (stubs) clear - * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD), - * the returned entry pointer addresses an entry struct whose keyHash member - * has been set non-zero, but all other entry members are still clear (null). - * JS_DHASH_ADD callers can test such members to see whether the entry was - * newly created by the JS_DHASH_ADD call that just succeeded. If placement - * new or similar initialization is required, define an initEntry hook. Of - * course, the clearEntry hook must zero or null appropriately. - * - * XXX assumes 0 is null for pointer types. - */ -struct JSDHashTableOps { - /* Mandatory hooks. All implementations must provide these. */ - JSDHashAllocTable allocTable; - JSDHashFreeTable freeTable; - JSDHashHashKey hashKey; - JSDHashMatchEntry matchEntry; - JSDHashMoveEntry moveEntry; - JSDHashClearEntry clearEntry; - JSDHashFinalize finalize; - - /* Optional hooks start here. If null, these are not called. */ - JSDHashInitEntry initEntry; -}; - -/* - * Default implementations for the above ops. - */ -extern JS_PUBLIC_API(void *) -JS_DHashAllocTable(JSDHashTable *table, uint32_t nbytes); - -extern JS_PUBLIC_API(void) -JS_DHashFreeTable(JSDHashTable *table, void *ptr); - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashStringKey(JSDHashTable *table, const void *key); - -/* A minimal entry contains a keyHash header and a void key pointer. */ -struct JSDHashEntryStub { - JSDHashEntryHdr hdr; - const void *key; -}; - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchStringKey(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(void) -JS_DHashMoveEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -extern JS_PUBLIC_API(void) -JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFinalizeStub(JSDHashTable *table); - -/* - * If you use JSDHashEntryStub or a subclass of it as your entry struct, and - * if your entries move via memcpy and clear via memset(0), you can use these - * stub operations. - */ -extern JS_PUBLIC_API(const JSDHashTableOps *) -JS_DHashGetStubOps(void); - -/* - * Dynamically allocate a new JSDHashTable using malloc, initialize it using - * JS_DHashTableInit, and return its address. Return null on malloc failure. - * Note that the entry storage at table->entryStore will be allocated using - * the ops->allocTable callback. - */ -extern JS_PUBLIC_API(JSDHashTable *) -JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32_t entrySize, - uint32_t capacity); - -/* - * Finalize table's data, free its entry storage (via table->ops->freeTable), - * and return the memory starting at table to the malloc heap. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableDestroy(JSDHashTable *table); - -/* - * Initialize table with ops, data, entrySize, and capacity. Capacity is a - * guess for the smallest table size at which the table will usually be less - * than 75% loaded (the table will grow or shrink as needed; capacity serves - * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE). - */ -extern JS_PUBLIC_API(JSBool) -JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, - uint32_t entrySize, uint32_t capacity); - -/* - * Set maximum and minimum alpha for table. The defaults are 0.75 and .25. - * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if - * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or - * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that - * we don't shrink on the very next remove after growing a table upon adding - * an entry that brings entryCount past maxAlpha * tableSize. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableSetAlphaBounds(JSDHashTable *table, - float maxAlpha, - float minAlpha); - -/* - * Call this macro with k, the number of pointer-sized words wasted per entry - * under chaining, to compute the minimum alpha at which double hashing still - * beats chaining. - */ -#define JS_DHASH_MIN_ALPHA(table, k) \ - ((float)((table)->entrySize / sizeof(void *) - 1) \ - / ((table)->entrySize / sizeof(void *) + (k))) - -/* - * Default max/min alpha, and macros to compute the value for the |capacity| - * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any - * max alpha, such that adding entryCount entries right after initializing the - * table will not require a reallocation (so JS_DHASH_ADD can't fail for those - * JS_DHashTableOperate calls). - * - * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY. - * Don't use it directly! - */ -#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 -#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 - -#define JS_DHASH_CAP(entryCount, maxAlpha) \ - ((uint32_t)((double)(entryCount) / (maxAlpha))) - -#define JS_DHASH_CAPACITY(entryCount, maxAlpha) \ - (JS_DHASH_CAP(entryCount, maxAlpha) + \ - (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8_t)(0x100 * (maxAlpha))) \ - >> 8) < (entryCount))) - -#define JS_DHASH_DEFAULT_CAPACITY(entryCount) \ - JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) - -/* - * Finalize table's data, free its entry storage using table->ops->freeTable, - * and leave its members unchanged from their last live values (which leaves - * pointers dangling). If you want to burn cycles clearing table, it's up to - * your code to call memset. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableFinish(JSDHashTable *table); - -/* - * To consolidate keyHash computation and table grow/shrink code, we use a - * single entry point for lookup, add, and remove operations. The operation - * codes are declared here, along with codes returned by JSDHashEnumerator - * functions, which control JS_DHashTableEnumerate's behavior. - */ -typedef enum JSDHashOperator { - JS_DHASH_LOOKUP = 0, /* lookup entry */ - JS_DHASH_ADD = 1, /* add entry */ - JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */ - JS_DHASH_NEXT = 0, /* enumerator says continue */ - JS_DHASH_STOP = 1 /* enumerator says stop */ -} JSDHashOperator; - -/* - * To lookup a key in table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); - * - * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies - * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found. - * - * To add an entry identified by key to table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD); - * - * If entry is null upon return, then either the table is severely overloaded, - * and memory can't be allocated for entry storage via table->ops->allocTable; - * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may - * have returned false. - * - * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry) - * is true, and it is up to the caller to initialize the key and value parts - * of the entry sub-type, if they have not been set already (i.e. if entry was - * not already in the table, and if the optional initEntry hook was not used). - * - * To remove an entry identified by key from table, call: - * - * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); - * - * If key's entry is found, it is cleared (via table->ops->clearEntry) and - * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation - * returns null unconditionally; you should ignore its return value. - */ -extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL -JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); - -/* - * Remove an entry already accessed via LOOKUP or ADD. - * - * NB: this is a "raw" or low-level routine, intended to be used only where - * the inefficiency of a full JS_DHashTableOperate (which rehashes in order - * to find the entry given its key) is not tolerable. This function does not - * shrink the table if it is underloaded. It does not update stats #ifdef - * JS_DHASHMETER, either. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Enumerate entries in table using etor: - * - * count = JS_DHashTableEnumerate(table, etor, arg); - * - * JS_DHashTableEnumerate calls etor like so: - * - * op = etor(table, entry, number, arg); - * - * where number is a zero-based ordinal assigned to live entries according to - * their order in table->entryStore. - * - * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT, - * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via - * table->ops->clearEntry) and free entry. Then we check whether op contains - * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries - * that were enumerated so far. Return the total number of live entries when - * enumeration completes normally. - * - * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it - * must return JS_DHASH_STOP; otherwise undefined behavior results. - * - * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk - * or compressed after enumeration, but before JS_DHashTableEnumerate returns. - * Such an enumerator therefore can't safely set aside entry pointers, but an - * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries - * aside, e.g., to avoid copying live entries into an array of the entry type. - * Copying entry pointers is cheaper, and safe so long as the caller of such a - * "stable" Enumerate doesn't use the set-aside pointers after any call either - * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might - * grow or shrink entryStore. - * - * If your enumerator wants to remove certain entries, but set aside pointers - * to other entries that it retains, it can use JS_DHashTableRawRemove on the - * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if - * you want to remove entries, but for some reason you do not want entryStore - * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on - * the entry being enumerated, rather than returning JS_DHASH_REMOVE. - */ -typedef JSDHashOperator -(* JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number, void *arg); - -extern JS_PUBLIC_API(uint32_t) -JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); - -typedef size_t -(* JSDHashSizeOfEntryExcludingThisFun)(JSDHashEntryHdr *hdr, - JSMallocSizeOfFun mallocSizeOf, - void *arg); - -/** - * Measure the size of the table's entry storage, and if - * |sizeOfEntryExcludingThis| is non-NULL, measure the size of things pointed - * to by entries. Doesn't measure |ops| because it's often shared between - * tables, nor |data| because it's opaque. - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfExcludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -/** - * Like JS_DHashTableSizeOfExcludingThis, but includes sizeof(*this). - */ -extern JS_PUBLIC_API(size_t) -JS_DHashTableSizeOfIncludingThis(const JSDHashTable *table, - JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis, - JSMallocSizeOfFun mallocSizeOf, - void *arg = NULL); - -#ifdef DEBUG -/** - * Mark a table as immutable for the remainder of its lifetime. This - * changes the implementation from ASSERTing one set of invariants to - * ASSERTing a different set. - * - * When a table is NOT marked as immutable, the table implementation - * asserts that the table is not mutated from its own callbacks. It - * assumes the caller protects the table from being accessed on multiple - * threads simultaneously. - * - * When the table is marked as immutable, the re-entry assertions will - * no longer trigger erroneously due to multi-threaded access. Instead, - * mutations will cause assertions. - */ -extern JS_PUBLIC_API(void) -JS_DHashMarkTableImmutable(JSDHashTable *table); -#endif - -#ifdef JS_DHASHMETER -#include - -extern JS_PUBLIC_API(void) -JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp); -#endif - -#endif /* jsdhash_h___ */ diff --git a/external/spidermonkey/include/win32/jsfriendapi.h b/external/spidermonkey/include/win32/jsfriendapi.h index 848049ffe3..a1c3024fed 100644 --- a/external/spidermonkey/include/win32/jsfriendapi.h +++ b/external/spidermonkey/include/win32/jsfriendapi.h @@ -4,15 +4,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsfriendapi_h___ -#define jsfriendapi_h___ +#ifndef jsfriendapi_h +#define jsfriendapi_h -#include "mozilla/GuardObjects.h" +#include "mozilla/MemoryReporting.h" #include "jsclass.h" -#include "jscpucfg.h" -#include "jspubtd.h" #include "jsprvtd.h" +#include "jspubtd.h" + +#include "js/CallArgs.h" /* * This macro checks if the stack pointer has exceeded a given limit. If @@ -29,6 +30,11 @@ #define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0) +namespace JS { +template +class Heap; +} /* namespace JS */ + extern JS_FRIEND_API(void) JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data); @@ -48,7 +54,7 @@ extern JS_FRIEND_API(JSObject *) JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JSHandleObject obj); +JS_ObjectCountDynamicSlots(JS::HandleObject obj); extern JS_FRIEND_API(size_t) JS_SetProtoCalled(JSContext *cx); @@ -118,14 +124,27 @@ extern JS_FRIEND_API(JSObject *) JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(JSString *) -JS_BasicObjectToString(JSContext *cx, JSHandleObject obj); +JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); extern JS_FRIEND_API(JSBool) -js_GetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp); +js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JSBool strict, + JS::MutableHandleValue vp); JS_FRIEND_API(void) js_ReportOverRecursed(JSContext *maybecx); +JS_FRIEND_API(bool) +js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); + +JS_FRIEND_API(const char *) +js_ObjectClassName(JSContext *cx, JS::HandleObject obj); + +JS_FRIEND_API(bool) +js_AddObjectRoot(JSRuntime *rt, JSObject **objp); + +JS_FRIEND_API(void) +js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp); + #ifdef DEBUG /* @@ -157,7 +176,7 @@ extern JS_FRIEND_API(JSBool) JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props); extern JS_FRIEND_API(JSBool) -JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, +JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op, js::MutableHandleValue statep, js::MutableHandleId idp); struct JSFunctionSpecWithHelp { @@ -177,25 +196,24 @@ struct JSFunctionSpecWithHelp { extern JS_FRIEND_API(bool) JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs); -typedef bool (* JS_SourceHook)(JSContext *cx, JSScript *script, jschar **src, uint32_t *length); +typedef bool (* JS_SourceHook)(JSContext *cx, JS::Handle script, + jschar **src, uint32_t *length); extern JS_FRIEND_API(void) JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook); namespace js { -extern mozilla::ThreadLocal TlsPerThreadData; - inline JSRuntime * GetRuntime(const JSContext *cx) { - return ContextFriendFields::get(cx)->runtime; + return ContextFriendFields::get(cx)->runtime_; } inline JSCompartment * GetContextCompartment(const JSContext *cx) { - return ContextFriendFields::get(cx)->compartment; + return ContextFriendFields::get(cx)->compartment_; } inline JS::Zone * @@ -217,19 +235,6 @@ typedef bool extern JS_FRIEND_API(void) DumpHeapComplete(JSRuntime *rt, FILE *fp); -class JS_FRIEND_API(AutoSwitchCompartment) { - private: - JSContext *cx; - JSCompartment *oldCompartment; - public: - AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - AutoSwitchCompartment(JSContext *cx, JSHandleObject target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoSwitchCompartment(); - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - #ifdef OLD_GETTER_SETTER_METHODS JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, unsigned argc, js::Value *vp); JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, unsigned argc, js::Value *vp); @@ -254,6 +259,15 @@ IsAtomsCompartment(JSCompartment *comp); extern JS_FRIEND_API(bool) ReportIfUndeclaredVarAssignment(JSContext *cx, HandleString propname); +/* + * Returns whether we're in a non-strict property set (in that we're in a + * non-strict script and the bytecode we're on is a property set). The return + * value does NOT indicate any sort of exception was thrown: it's just a + * boolean. + */ +extern JS_FRIEND_API(bool) +IsInNonStrictPropertySet(JSContext *cx); + struct WeakMapTracer; /* @@ -301,7 +315,7 @@ IterateGrayObjects(JS::Zone *zone, GCThingCallback cellCallback, void *data); #ifdef JS_HAS_CTYPES extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(JSMallocSizeOfFun mallocSizeOf, JSObject *obj); +SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject *obj); #endif extern JS_FRIEND_API(JSCompartment *) @@ -321,8 +335,9 @@ struct TypeObject { }; struct BaseShape { - js::Class *clasp; - JSObject *parent; + js::Class *clasp; + JSObject *parent; + JSObject *_1; JSCompartment *compartment; }; @@ -365,19 +380,22 @@ struct Function { }; struct Atom { - size_t _; + static const size_t LENGTH_SHIFT = 4; + size_t lengthAndFlags; const jschar *chars; }; } /* namespace shadow */ -extern JS_FRIEND_DATA(js::Class) CallClass; -extern JS_FRIEND_DATA(js::Class) DeclEnvClass; -extern JS_FRIEND_DATA(js::Class) FunctionClass; -extern JS_FRIEND_DATA(js::Class) FunctionProxyClass; -extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectProxyClass; -extern JS_FRIEND_DATA(js::Class) ObjectClass; +// These are equal to |&{Function,Object,OuterWindow}ProxyObject::class_|. Use +// them in places where you don't want to #include vm/ProxyObject.h. +extern JS_FRIEND_DATA(js::Class* const) FunctionProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) ObjectProxyClassPtr; +extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr; + +// This is equal to |&JSObject::class_|. Use it in places where you don't want +// to #include jsobj.h. +extern JS_FRIEND_DATA(js::Class* const) ObjectClassPtr; inline js::Class * GetObjectClass(JSObject *obj) @@ -401,9 +419,15 @@ IsOuterObject(JSObject *obj) { return !!GetObjectClass(obj)->ext.innerObject; } +JS_FRIEND_API(bool) +IsFunctionObject(JSObject *obj); + JS_FRIEND_API(bool) IsScopeObject(JSObject *obj); +JS_FRIEND_API(bool) +IsCallObject(JSObject *obj); + inline JSObject * GetObjectParent(JSObject *obj) { @@ -423,6 +447,13 @@ GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +// For legacy consumers only. This whole concept is going away soon. +JS_FRIEND_API(JSObject *) +DefaultObjectForContextOrNull(JSContext *cx); + +JS_FRIEND_API(void) +SetDefaultObjectForContext(JSContext *cx, JSObject *obj); + JS_FRIEND_API(void) NotifyAnimationActivity(JSObject *obj); @@ -469,11 +500,11 @@ inline bool GetObjectProto(JSContext *cx, JS::Handle obj, JS::MutableHandle proto) { js::Class *clasp = GetObjectClass(obj); - if (clasp == &js::ObjectProxyClass || - clasp == &js::OuterWindowProxyClass || - clasp == &js::FunctionProxyClass) + if (clasp == js::ObjectProxyClassPtr || + clasp == js::OuterWindowProxyClassPtr || + clasp == js::FunctionProxyClassPtr) { - return JS_GetPrototype(cx, obj, proto.address()); + return JS_GetPrototype(cx, obj, proto); } proto.set(reinterpret_cast(obj.get())->type->proto); @@ -535,6 +566,13 @@ GetAtomChars(JSAtom *atom) return reinterpret_cast(atom)->chars; } +inline size_t +GetAtomLength(JSAtom *atom) +{ + using shadow::Atom; + return reinterpret_cast(atom)->lengthAndFlags >> Atom::LENGTH_SHIFT; +} + inline JSLinearString * AtomToLinearString(JSAtom *atom) { @@ -589,6 +627,12 @@ GetNativeStackLimit(const JSRuntime *rt) return PerThreadDataFriendFields::getMainThread(rt)->nativeStackLimit; } +inline uintptr_t +GetNativeStackLimit(JSContext *cx) +{ + return GetNativeStackLimit(GetRuntime(cx)); +} + /* * These macros report a stack overflow and run |onerror| if we are close to * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little @@ -598,18 +642,15 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \ js_ReportOverRecursed(cx); \ onerror; \ } \ JS_END_MACRO -#define JS_CHECK_RECURSION_WITH_EXTRA_DONT_REPORT(cx, extra, onerror) \ +#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ JS_BEGIN_MACRO \ - uint8_t stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ - &stackDummy_ - (extra))) \ - { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ onerror; \ } \ JS_END_MACRO @@ -617,7 +658,7 @@ GetNativeStackLimit(const JSRuntime *rt) #define JS_CHECK_CHROME_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(js::GetRuntime(cx)), \ + if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \ &stackDummy_, \ 1024 * sizeof(size_t))) \ { \ @@ -754,13 +795,13 @@ extern JS_FRIEND_API(bool) IsContextRunningJS(JSContext *cx); typedef void -(* AnalysisPurgeCallback)(JSRuntime *rt, JSFlatString *desc); +(* AnalysisPurgeCallback)(JSRuntime *rt, JS::Handle desc); extern JS_FRIEND_API(AnalysisPurgeCallback) SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback); typedef JSBool -(* DOMInstanceClassMatchesProto)(JSHandleObject protoObject, uint32_t protoID, +(* DOMInstanceClassMatchesProto)(JS::HandleObject protoObject, uint32_t protoID, uint32_t depth); struct JSDOMCallbacks { DOMInstanceClassMatchesProto instanceClassMatchesProto; @@ -851,10 +892,10 @@ NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& targetFilter, NukeReferencesToWindow nukeReferencesToWindow); -/* Specify information about ListBase proxies in the DOM, for use by ICs. */ +/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ /* - * The ListBaseShadowsCheck function will be called to check if the property for + * The DOMProxyShadowsCheck function will be called to check if the property for * id should be gotten from the prototype, or if there is an own property that * shadows it. * If DoesntShadow is returned then the slot at listBaseExpandoSlot should @@ -873,25 +914,31 @@ struct ExpandoAndGeneration { generation(0) {} - Value expando; + void Unlink() + { + ++generation; + expando.setUndefined(); + } + + JS::Heap expando; uint32_t generation; }; -typedef enum ListBaseShadowsResult { +typedef enum DOMProxyShadowsResult { ShadowCheckFailed, Shadows, DoesntShadow, DoesntShadowUnique -} ListBaseShadowsResult; -typedef ListBaseShadowsResult -(* ListBaseShadowsCheck)(JSContext* cx, JSHandleObject object, JSHandleId id); +} DOMProxyShadowsResult; +typedef DOMProxyShadowsResult +(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); JS_FRIEND_API(void) -SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot, - ListBaseShadowsCheck listBaseShadowsCheck); +SetDOMProxyInformation(void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, + DOMProxyShadowsCheck domProxyShadowsCheck); -void *GetListBaseHandlerFamily(); -uint32_t GetListBaseExpandoSlot(); -ListBaseShadowsCheck GetListBaseShadowsCheck(); +void *GetDOMProxyHandlerFamily(); +uint32_t GetDOMProxyExpandoSlot(); +DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); } /* namespace js */ @@ -960,6 +1007,137 @@ enum ViewType { }; } /* namespace ArrayBufferView */ + +/* + * A helper for building up an ArrayBuffer object's data + * before creating the ArrayBuffer itself. Will do doubling + * based reallocation, up to an optional maximum growth given. + * + * When all the data has been appended, call getArrayBuffer, + * passing in the JSContext* for which the ArrayBuffer object + * is to be created. This also implicitly resets the builder, + * or it can be reset explicitly at any point by calling reset(). + */ +class ArrayBufferBuilder +{ + void *rawcontents_; + uint8_t *dataptr_; + uint32_t capacity_; + uint32_t length_; + public: + ArrayBufferBuilder() + : rawcontents_(NULL), + dataptr_(NULL), + capacity_(0), + length_(0) + { + } + + ~ArrayBufferBuilder() { + reset(); + } + + void reset() { + if (rawcontents_) + JS_free(NULL, rawcontents_); + rawcontents_ = dataptr_ = NULL; + capacity_ = length_ = 0; + } + + // will truncate if newcap is < length() + bool setCapacity(uint32_t newcap) { + if (!JS_ReallocateArrayBufferContents(NULL, newcap, &rawcontents_, &dataptr_)) + return false; + + capacity_ = newcap; + if (length_ > newcap) + length_ = newcap; + + return true; + } + + // Append datalen bytes from data to the current buffer. If we + // need to grow the buffer, grow by doubling the size up to a + // maximum of maxgrowth (if given). If datalen is greater than + // what the new capacity would end up as, then grow by datalen. + // + // The data parameter must not overlap with anything beyond the + // builder's current valid contents [0..length) + bool append(const uint8_t *newdata, uint32_t datalen, uint32_t maxgrowth = 0) { + if (length_ + datalen > capacity_) { + uint32_t newcap; + // double while under maxgrowth or if not specified + if (!maxgrowth || capacity_ < maxgrowth) + newcap = capacity_ * 2; + else + newcap = capacity_ + maxgrowth; + + // but make sure there's always enough to satisfy our request + if (newcap < length_ + datalen) + newcap = length_ + datalen; + + // did we overflow? + if (newcap < capacity_) + return false; + + if (!setCapacity(newcap)) + return false; + } + + // assert that the region isn't overlapping so we can memcpy; + JS_ASSERT(!areOverlappingRegions(newdata, datalen, dataptr_ + length_, datalen)); + + memcpy(dataptr_ + length_, newdata, datalen); + length_ += datalen; + + return true; + } + + uint8_t *data() { + return dataptr_; + } + + uint32_t length() { + return length_; + } + + uint32_t capacity() { + return capacity_; + } + + JSObject* getArrayBuffer(JSContext *cx) { + // we need to check for length_ == 0, because nothing may have been + // added + if (capacity_ > length_ || length_ == 0) { + if (!setCapacity(length_)) + return NULL; + } + + JSObject* obj = JS_NewArrayBufferWithContents(cx, rawcontents_); + if (!obj) + return NULL; + + rawcontents_ = dataptr_ = NULL; + length_ = capacity_ = 0; + + return obj; + } + +protected: + + static bool areOverlappingRegions(const uint8_t *start1, uint32_t length1, + const uint8_t *start2, uint32_t length2) + { + const uint8_t *end1 = start1 + length1; + const uint8_t *end2 = start2 + length2; + + const uint8_t *max_start = start1 > start2 ? start1 : start2; + const uint8_t *min_end = end1 < end2 ? end1 : end2; + + return max_start < min_end; + } +}; + } /* namespace js */ typedef js::ArrayBufferView::ViewType JSArrayBufferViewType; @@ -1296,26 +1474,116 @@ JS_GetDataViewByteLength(JSObject *obj); JS_FRIEND_API(void *) JS_GetDataViewData(JSObject *obj); +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitGetterOp. + */ +class JSJitGetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitGetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args.rval()) + {} + + explicit JSJitGetterCallArgs(JS::Rooted* rooted) + : JS::MutableHandleValue(rooted) + {} + + JS::MutableHandleValue rval() { + return *this; + } +}; + +/* + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitSetterOp. + */ +class JSJitSetterCallArgs : protected JS::MutableHandleValue +{ + public: + explicit JSJitSetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandleValue(args[0]) + {} + + JS::MutableHandleValue operator[](unsigned i) { + MOZ_ASSERT(i == 0); + return *this; + } + + unsigned length() const { return 1; } + + // Add get() or maybe hasDefined() as needed +}; + +struct JSJitMethodCallArgsTraits; + +/* + * A class, expected to be passed by reference, which represents the CallArgs + * for a JSJitMethodOp. + */ +class JSJitMethodCallArgs : protected JS::detail::CallArgsBase +{ + private: + typedef JS::detail::CallArgsBase Base; + friend struct JSJitMethodCallArgsTraits; + + public: + explicit JSJitMethodCallArgs(const JS::CallArgs& args) { + argv_ = args.array(); + argc_ = args.length(); + } + + JS::MutableHandleValue rval() const { + return Base::rval(); + } + + unsigned length() const { return Base::length(); } + + JS::MutableHandleValue operator[](unsigned i) const { + return Base::operator[](i); + } + + bool hasDefined(unsigned i) const { + return Base::hasDefined(i); + } + + // Add get() as needed +}; + +struct JSJitMethodCallArgsTraits +{ + static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); + static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); +}; + /* * This struct contains metadata passed from the DOM to the JS Engine for JIT * optimizations on DOM property accessors. Eventually, this should be made * available to general JSAPI users, but we are not currently ready to do so. */ typedef bool -(* JSJitPropertyOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, JS::Value *vp); +(* JSJitGetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitGetterCallArgs args); typedef bool -(* JSJitMethodOp)(JSContext *cx, JSHandleObject thisObj, - void *specializedThis, unsigned argc, JS::Value *vp); +(* JSJitSetterOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, JSJitSetterCallArgs args); +typedef bool +(* JSJitMethodOp)(JSContext *cx, JS::HandleObject thisObj, + void *specializedThis, const JSJitMethodCallArgs& args); struct JSJitInfo { enum OpType { Getter, Setter, - Method + Method, + OpType_None }; - JSJitPropertyOp op; + union { + JSJitGetterOp getter; + JSJitSetterOp setter; + JSJitMethodOp method; + }; uint32_t protoID; uint32_t depth; OpType type; @@ -1325,12 +1593,18 @@ struct JSJitInfo { keep returning the same value for the given "this" object" */ JSValueType returnType; /* The return type tag. Might be JSVAL_TYPE_UNKNOWN */ + + /* An alternative native that's safe to call in parallel mode. */ + JSParallelNative parallelNative; }; +#define JS_JITINFO_NATIVE_PARALLEL(op) \ + {{NULL},0,0,JSJitInfo::OpType_None,false,false,false,JSVAL_TYPE_MISSING,op} + static JS_ALWAYS_INLINE const JSJitInfo * FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) { - JS_ASSERT(js::GetObjectClass(&v.toObject()) == &js::FunctionClass); + JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr); return reinterpret_cast(&v.toObject())->jitinfo; } @@ -1482,9 +1756,46 @@ assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id); inline void assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id) {}; #endif +typedef bool +(* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata); + +/* + * Specify a callback to invoke when creating each JS object in the current + * compartment, which may return a metadata object to associate with the + * object. Objects with different metadata have different shape hierarchies, + * so for efficiency, objects should generally try to share metadata objects. + */ +JS_FRIEND_API(void) +SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback); + +/* Manipulate the metadata associated with an object. */ + +JS_FRIEND_API(bool) +SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata); + +JS_FRIEND_API(JSObject *) +GetObjectMetadata(JSObject *obj); + /* ES5 8.12.8. */ extern JS_FRIEND_API(JSBool) -DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); +DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValue vp); + +/* + * Helper function. To approximate a call to the [[DefineOwnProperty]] internal + * method described in ES5, first call this, then call JS_DefinePropertyById. + * + * JS_DefinePropertyById by itself does not enforce the invariants on + * non-configurable properties when obj->isNative(). This function performs the + * relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11), + * but only if obj is native. + * + * The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as + * a sort of extension point, but there is no hook in js::Class, + * js::ProxyHandler, or the JSAPI with precisely the right semantics for it. + */ +extern JS_FRIEND_API(bool) +CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, + PropertyOp getter, StrictPropertyOp setter, unsigned attrs); } /* namespace js */ @@ -1495,4 +1806,26 @@ js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, extern JS_FRIEND_API(JSBool) js_ReportIsNotFunction(JSContext *cx, const JS::Value& v); -#endif /* jsfriendapi_h___ */ +#ifdef JSGC_GENERATIONAL +extern JS_FRIEND_API(void) +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data); + +extern JS_FRIEND_API(void) +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data); +#else +inline void +JS_StoreObjectPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSObject *key, void *data) {} + +inline void +JS_StoreStringPostBarrierCallback(JSContext* cx, + void (*callback)(JSTracer *trc, void *key, void *data), + JSString *key, void *data) {} +#endif /* JSGC_GENERATIONAL */ + +#endif /* jsfriendapi_h */ diff --git a/external/spidermonkey/include/win32/jslock.h b/external/spidermonkey/include/win32/jslock.h index b4a28a9fa9..522034ad68 100644 --- a/external/spidermonkey/include/win32/jslock.h +++ b/external/spidermonkey/include/win32/jslock.h @@ -4,18 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jslock_h__ -#define jslock_h__ - -#include "jsapi.h" +#ifndef jslock_h +#define jslock_h #ifdef JS_THREADSAFE +# include "jsapi.h" # include "pratom.h" -# include "prlock.h" # include "prcvar.h" -# include "prthread.h" # include "prinit.h" +# include "prlock.h" +# include "prthread.h" # define JS_ATOMIC_INCREMENT(p) PR_ATOMIC_INCREMENT((int32_t *)(p)) # define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p)) @@ -40,4 +39,4 @@ typedef struct PRLock PRLock; #endif /* JS_THREADSAFE */ -#endif /* jslock_h___ */ +#endif /* jslock_h */ diff --git a/external/spidermonkey/include/win32/json.h b/external/spidermonkey/include/win32/json.h deleted file mode 100644 index 7fa2c117c8..0000000000 --- a/external/spidermonkey/include/win32/json.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef json_h___ -#define json_h___ - -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsapi.h" - -#include "js/Vector.h" - -#define JSON_MAX_DEPTH 2048 -#define JSON_PARSER_BUFSIZE 1024 - -extern JSObject * -js_InitJSONClass(JSContext *cx, js::HandleObject obj); - -extern JSBool -js_Stringify(JSContext *cx, js::MutableHandleValue vp, - JSObject *replacer, js::Value space, - js::StringBuffer &sb); - -// Avoid build errors on certain platforms that define these names as constants -#undef STRICT -#undef LEGACY - -/* - * The type of JSON decoding to perform. Strict decoding is to-the-spec; - * legacy decoding accepts a few non-JSON syntaxes historically accepted by the - * implementation. (Full description of these deviations is deliberately - * omitted.) New users should use strict decoding rather than legacy decoding, - * as legacy decoding might be removed at a future time. - */ -enum DecodingMode { STRICT, LEGACY }; - -namespace js { - -extern JS_FRIEND_API(JSBool) -ParseJSONWithReviver(JSContext *cx, JS::StableCharPtr chars, size_t length, HandleValue filter, - MutableHandleValue vp, DecodingMode decodingMode = STRICT); - -} /* namespace js */ - -#endif /* json_h___ */ diff --git a/external/spidermonkey/include/win32/jsperf.h b/external/spidermonkey/include/win32/jsperf.h index a0287b4a57..468ce8609c 100644 --- a/external/spidermonkey/include/win32/jsperf.h +++ b/external/spidermonkey/include/win32/jsperf.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsperf_h___ -#define jsperf_h___ +#ifndef perf_jsperf_h +#define perf_jsperf_h #include "jsapi.h" @@ -127,4 +127,4 @@ extern JS_FRIEND_API(PerfMeasurement*) } // namespace JS -#endif // jsperf_h___ +#endif /* perf_jsperf_h */ diff --git a/external/spidermonkey/include/win32/jsprf.h b/external/spidermonkey/include/win32/jsprf.h index c0891f0e9e..ce159d8115 100644 --- a/external/spidermonkey/include/win32/jsprf.h +++ b/external/spidermonkey/include/win32/jsprf.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprf_h___ -#define jsprf_h___ +#ifndef jsprf_h +#define jsprf_h /* ** API for PR printf like routines. Supports the following formats @@ -24,9 +24,11 @@ ** %f - float ** %g - float */ -#include "jstypes.h" -#include + #include +#include + +#include "jstypes.h" /* ** sprintf into a fixed size buffer. Guarantees that a NUL is at the end @@ -75,4 +77,4 @@ extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); extern JS_PUBLIC_API(uint32_t) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); -#endif /* jsprf_h___ */ +#endif /* jsprf_h */ diff --git a/external/spidermonkey/include/win32/jsprototypes.h b/external/spidermonkey/include/win32/jsprototypes.h index 007d25d720..f9bacac409 100644 --- a/external/spidermonkey/include/win32/jsprototypes.h +++ b/external/spidermonkey/include/win32/jsprototypes.h @@ -6,8 +6,8 @@ /* A higher-order macro for enumerating all JSProtoKey values. */ -#ifndef jsprototypes_h___ -#define jsprototypes_h___ +#ifndef jsprototypes_h +#define jsprototypes_h #include "jsversion.h" @@ -56,5 +56,20 @@ macro(DataView, 35, js_InitTypedArrayClasses) \ macro(ParallelArray, 36, js_InitParallelArrayClass) \ macro(Intl, 37, js_InitIntlClass) \ + macro(Type, 38, js_InitBinaryDataClasses) \ + macro(Data, 39, js_InitBinaryDataClasses) \ + macro(uint8, 40, js_InitBinaryDataClasses) \ + macro(uint16, 41, js_InitBinaryDataClasses) \ + macro(uint32, 42, js_InitBinaryDataClasses) \ + macro(uint64, 43, js_InitBinaryDataClasses) \ + macro(int8, 44, js_InitBinaryDataClasses) \ + macro(int16, 45, js_InitBinaryDataClasses) \ + macro(int32, 46, js_InitBinaryDataClasses) \ + macro(int64, 47, js_InitBinaryDataClasses) \ + macro(float32, 48, js_InitBinaryDataClasses) \ + macro(float64, 49, js_InitBinaryDataClasses) \ + macro(ArrayType, 50, js_InitBinaryDataClasses) \ + macro(StructType, 51, js_InitBinaryDataClasses) \ + macro(ArrayTypeObject, 52, js_InitBinaryDataClasses) \ -#endif /* jsprototypes_h___ */ +#endif /* jsprototypes_h */ diff --git a/external/spidermonkey/include/win32/jsproxy.h b/external/spidermonkey/include/win32/jsproxy.h index 399490eddc..56868a05c3 100644 --- a/external/spidermonkey/include/win32/jsproxy.h +++ b/external/spidermonkey/include/win32/jsproxy.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsproxy_h___ -#define jsproxy_h___ +#ifndef jsproxy_h +#define jsproxy_h #include "jsapi.h" #include "jsfriendapi.h" @@ -129,7 +129,7 @@ class JS_FRIEND_API(BaseProxyHandler) MutableHandleValue vp); /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) = 0; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) = 0; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -190,7 +190,7 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -242,7 +242,7 @@ class Proxy static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); /* Spidermonkey extensions. */ - static bool isExtensible(JSObject *proxy); + static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -259,12 +259,17 @@ class Proxy inline bool IsObjectProxyClass(const Class *clasp) { - return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass; + return clasp == js::ObjectProxyClassPtr || clasp == js::OuterWindowProxyClassPtr; } inline bool IsFunctionProxyClass(const Class *clasp) { - return clasp == &js::FunctionProxyClass; + return clasp == js::FunctionProxyClassPtr; +} + +inline bool IsProxyClass(const Class *clasp) +{ + return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); } inline bool IsObjectProxy(JSObject *obj) @@ -279,36 +284,33 @@ inline bool IsFunctionProxy(JSObject *obj) inline bool IsProxy(JSObject *obj) { - Class *clasp = GetObjectClass(obj); - return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); + return IsProxyClass(GetObjectClass(obj)); } -/* Shared between object and function proxies. */ /* - * NOTE: JSSLOT_PROXY_PRIVATE is 0, because that way slot 0 is usable by API + * These are part of the API. + * + * NOTE: PROXY_PRIVATE_SLOT is 0 because that way slot 0 is usable by API * clients for both proxy and non-proxy objects. So an API client that only * needs to store one slot's worth of data doesn't need to branch on what sort * of object it has. */ -const uint32_t JSSLOT_PROXY_PRIVATE = 0; -const uint32_t JSSLOT_PROXY_HANDLER = 1; -const uint32_t JSSLOT_PROXY_EXTRA = 2; -/* Function proxies only. */ -const uint32_t JSSLOT_PROXY_CALL = 4; -const uint32_t JSSLOT_PROXY_CONSTRUCT = 5; +const uint32_t PROXY_PRIVATE_SLOT = 0; +const uint32_t PROXY_HANDLER_SLOT = 1; +const uint32_t PROXY_EXTRA_SLOT = 2; inline BaseProxyHandler * GetProxyHandler(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return (BaseProxyHandler *) GetReservedSlot(obj, JSSLOT_PROXY_HANDLER).toPrivate(); + return (BaseProxyHandler *) GetReservedSlot(obj, PROXY_HANDLER_SLOT).toPrivate(); } inline const Value & GetProxyPrivate(JSObject *obj) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE); + return GetReservedSlot(obj, PROXY_PRIVATE_SLOT); } inline JSObject * @@ -322,14 +324,14 @@ inline const Value & GetProxyExtra(JSObject *obj, size_t n) { JS_ASSERT(IsProxy(obj)); - return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n); + return GetReservedSlot(obj, PROXY_EXTRA_SLOT + n); } inline void SetProxyHandler(JSObject *obj, BaseProxyHandler *handler) { JS_ASSERT(IsProxy(obj)); - SetReservedSlot(obj, JSSLOT_PROXY_HANDLER, PrivateValue(handler)); + SetReservedSlot(obj, PROXY_HANDLER_SLOT, PrivateValue(handler)); } inline void @@ -337,7 +339,7 @@ SetProxyExtra(JSObject *obj, size_t n, const Value &extra) { JS_ASSERT(IsProxy(obj)); JS_ASSERT(n <= 1); - SetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n, extra); + SetReservedSlot(obj, PROXY_EXTRA_SLOT + n, extra); } enum ProxyCallable { @@ -346,7 +348,7 @@ enum ProxyCallable { }; JS_FRIEND_API(JSObject *) -NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv, +NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto, JSObject *parent, ProxyCallable callable = ProxyNotCallable); JSObject * @@ -426,6 +428,6 @@ class JS_FRIEND_API(AutoWaivePolicy) { } /* namespace js */ extern JS_FRIEND_API(JSObject *) -js_InitProxyClass(JSContext *cx, JSHandleObject obj); +js_InitProxyClass(JSContext *cx, JS::HandleObject obj); -#endif +#endif /* jsproxy_h */ diff --git a/external/spidermonkey/include/win32/jsprvtd.h b/external/spidermonkey/include/win32/jsprvtd.h index 4db5ed8c36..1fbc086a7c 100644 --- a/external/spidermonkey/include/win32/jsprvtd.h +++ b/external/spidermonkey/include/win32/jsprvtd.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsprvtd_h___ -#define jsprvtd_h___ +#ifndef jsprvtd_h +#define jsprvtd_h /* * JS private typename definitions. * @@ -56,13 +56,7 @@ typedef struct JSStackHeader JSStackHeader; typedef struct JSSubString JSSubString; typedef struct JSSpecializedNative JSSpecializedNative; -/* - * Template declarations. - * - * jsprvtd.h can be included in both C and C++ translation units. For C++, it - * may possibly be wrapped in an extern "C" block which does not agree with - * templates. - */ +/* String typedefs. */ class JSDependentString; class JSExtensibleString; class JSExternalString; @@ -76,6 +70,7 @@ namespace js { struct ArgumentsData; struct Class; +class AutoNameVector; class RegExpGuard; class RegExpObject; class RegExpObjectBuilder; @@ -83,6 +78,7 @@ class RegExpShared; class RegExpStatics; class MatchPairs; class PropertyName; +class LazyScript; enum RegExpFlag { @@ -95,19 +91,14 @@ enum RegExpFlag AllFlags = 0x0f }; -class ExecuteArgsGuard; -class InvokeFrameGuard; -class InvokeArgsGuard; class StringBuffer; class FrameRegs; class StackFrame; -class StackSegment; -class StackSpace; -class ContextStack; class ScriptFrameIter; class Proxy; +class JS_FRIEND_API(AutoEnterPolicy); class JS_FRIEND_API(BaseProxyHandler); class JS_FRIEND_API(Wrapper); class JS_FRIEND_API(CrossCompartmentWrapper); @@ -140,24 +131,29 @@ class WatchpointMap; typedef JSObject Env; typedef JSNative Native; +typedef JSParallelNative ParallelNative; +typedef JSThreadSafeNative ThreadSafeNative; typedef JSPropertyOp PropertyOp; typedef JSStrictPropertyOp StrictPropertyOp; typedef JSPropertyDescriptor PropertyDescriptor; +struct SourceCompressionToken; + namespace frontend { struct BytecodeEmitter; struct Definition; +class FullParseHandler; class FunctionBox; class ObjectBox; struct Token; struct TokenPos; class TokenStream; class ParseMapPool; -struct ParseNode; +class ParseNode; template -struct Parser; +class Parser; } /* namespace frontend */ @@ -284,18 +280,18 @@ typedef void * if an error or exception was thrown on cx. */ typedef JSObject * -(* JSObjectOp)(JSContext *cx, JSHandleObject obj); +(* JSObjectOp)(JSContext *cx, JS::Handle obj); /* Signature for class initialization ops. */ typedef JSObject * -(* JSClassInitializerOp)(JSContext *cx, JSHandleObject obj); +(* JSClassInitializerOp)(JSContext *cx, JS::HandleObject obj); /* * Hook that creates an iterator object for a given object. Returns the * iterator object or null if an error or exception was thrown on cx. */ typedef JSObject * -(* JSIteratorOp)(JSContext *cx, JSHandleObject obj, JSBool keysonly); +(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, JSBool keysonly); -#endif /* jsprvtd_h___ */ +#endif /* jsprvtd_h */ diff --git a/external/spidermonkey/include/win32/jspubtd.h b/external/spidermonkey/include/win32/jspubtd.h index 6b7e63e6ba..96f5dd8297 100644 --- a/external/spidermonkey/include/win32/jspubtd.h +++ b/external/spidermonkey/include/win32/jspubtd.h @@ -4,16 +4,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jspubtd_h___ -#define jspubtd_h___ +#ifndef jspubtd_h +#define jspubtd_h /* * JS public API typedefs. */ +#include "mozilla/PodOperations.h" + #include "jsprototypes.h" #include "jstypes.h" +#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) +# define JSGC_TRACK_EXACT_ROOTS +#endif + namespace JS { /* @@ -25,6 +31,8 @@ class Value; template class Rooted; +class JS_PUBLIC_API(AutoGCRooter); + struct Zone; } /* namespace JS */ @@ -44,10 +52,8 @@ struct Zone; * oblivious to the change. This feature can be explicitly disabled in debug * builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. */ - // Needed for cocos2d-js -#define JS_NO_JSVAL_JSID_STRUCT_TYPES - +#define JS_NO_JSVAL_JSID_STRUCT_TYPES # if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) # define JS_USE_JSID_STRUCT_TYPES # endif @@ -154,9 +160,10 @@ typedef enum { JSTRACE_SCRIPT, /* - * Trace kinds internal to the engine. The embedding can only them if it - * implements JSTraceCallback. + * Trace kinds internal to the engine. The embedding can only see them if + * it implements JSTraceCallback. */ + JSTRACE_LAZY_SCRIPT, JSTRACE_IONCODE, JSTRACE_SHAPE, JSTRACE_BASE_SHAPE, @@ -229,6 +236,18 @@ struct Runtime namespace js { +/* + * Parallel operations in general can have one of three states. They may + * succeed, fail, or "bail", where bail indicates that the code encountered an + * unexpected condition and should be re-run sequentially. Different + * subcategories of the "bail" state are encoded as variants of TP_RETRY_*. + */ +enum ParallelResult { TP_SUCCESS, TP_RETRY_SEQUENTIALLY, TP_RETRY_AFTER_GC, TP_FATAL }; + +struct ThreadSafeContext; +struct ForkJoinSlice; +class ExclusiveContext; + class Allocator; class SkipRoot; @@ -273,18 +292,28 @@ template <> struct RootKind : SpecificRootKind struct RootKind : SpecificRootKind {}; template <> struct RootKind : SpecificRootKind {}; -struct ContextFriendFields { - JSRuntime *const runtime; +struct ContextFriendFields +{ + protected: + JSRuntime *const runtime_; /* The current compartment. */ - JSCompartment *compartment; + JSCompartment *compartment_; /* The current zone. */ JS::Zone *zone_; + public: explicit ContextFriendFields(JSRuntime *rt) - : runtime(rt), compartment(NULL), zone_(NULL) - { } + : runtime_(rt), compartment_(NULL), zone_(NULL), autoGCRooters(NULL) + { +#ifdef JSGC_TRACK_EXACT_ROOTS + mozilla::PodArrayZero(thingGCRooters); +#endif +#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) + skipGCRooters = NULL; +#endif + } static const ContextFriendFields *get(const JSContext *cx) { return reinterpret_cast(cx); @@ -294,7 +323,7 @@ struct ContextFriendFields { return reinterpret_cast(cx); } -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -313,6 +342,13 @@ struct ContextFriendFields { */ SkipRoot *skipGCRooters; #endif + + /* Stack of thread-stack-allocated GC roots. */ + JS::AutoGCRooter *autoGCRooters; + + friend JSRuntime *GetRuntime(const JSContext *cx); + friend JSCompartment *GetContextCompartment(const JSContext *cx); + friend JS::Zone *GetContextZone(const JSContext *cx); }; class PerThreadData; @@ -338,7 +374,7 @@ struct PerThreadDataFriendFields PerThreadDataFriendFields(); -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#ifdef JSGC_TRACK_EXACT_ROOTS /* * Stack allocated GC roots for stack GC heap pointers, which may be * overwritten if moved during a GC. @@ -384,4 +420,4 @@ struct PerThreadDataFriendFields } /* namespace js */ -#endif /* jspubtd_h___ */ +#endif /* jspubtd_h */ diff --git a/external/spidermonkey/include/win32/jstypes.h b/external/spidermonkey/include/win32/jstypes.h index e4c02f8d8d..17f67f70e1 100644 --- a/external/spidermonkey/include/win32/jstypes.h +++ b/external/spidermonkey/include/win32/jstypes.h @@ -18,8 +18,8 @@ ** for all C files. **/ -#ifndef jstypes_h___ -#define jstypes_h___ +#ifndef jstypes_h +#define jstypes_h #include "mozilla/Attributes.h" #include "mozilla/Util.h" @@ -279,4 +279,4 @@ typedef int JSBool; # define JS_EXTENSION_(s) s #endif -#endif /* jstypes_h___ */ +#endif /* jstypes_h */ diff --git a/external/spidermonkey/include/win32/jsutil.h b/external/spidermonkey/include/win32/jsutil.h index 49e1641c61..4020822be1 100644 --- a/external/spidermonkey/include/win32/jsutil.h +++ b/external/spidermonkey/include/win32/jsutil.h @@ -8,19 +8,19 @@ * PR assertion checker. */ -#ifndef jsutil_h___ -#define jsutil_h___ +#ifndef jsutil_h +#define jsutil_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/GuardObjects.h" -#include "js/Utility.h" - #ifdef USE_ZLIB -#include "zlib.h" +#include #endif +#include "js/Utility.h" + /* Forward declarations. */ struct JSContext; @@ -204,15 +204,6 @@ UnsignedPtrDiff(const void *bigger, const void *smaller) return size_t(bigger) - size_t(smaller); } -/* - * Ordinarily, a function taking a JSContext* 'cx' parameter reports errors on - * the context. In some cases, functions optionally report and indicate this by - * taking a nullable 'maybecx' parameter. In some cases, though, a function - * always needs a 'cx', but optionally reports. This option is presented by the - * MaybeReportError. - */ -enum MaybeReportError { REPORT_ERROR = true, DONT_REPORT_ERROR = false }; - /*****************************************************************************/ /* A bit array is an array of bits represented by an array of words (size_t). */ @@ -391,4 +382,4 @@ typedef size_t jsbitmap; JS_END_MACRO #endif -#endif /* jsutil_h___ */ +#endif /* jsutil_h */ diff --git a/external/spidermonkey/include/win32/jsversion.h b/external/spidermonkey/include/win32/jsversion.h index f3169fb5d1..1780616a32 100644 --- a/external/spidermonkey/include/win32/jsversion.h +++ b/external/spidermonkey/include/win32/jsversion.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jsversion_h___ -#define jsversion_h___ +#ifndef jsversion_h +#define jsversion_h /* * Deprecated JS_VERSION handler. @@ -61,7 +61,7 @@ # define NEW_OBJECT_REPRESENTATION_ONLY() ((void)0) #else # define NEW_OBJECT_REPRESENTATION_ONLY() \ - MOZ_NOT_REACHED("don't call this! to be used in the new object representation") + MOZ_ASSUME_UNREACHABLE("don't call this! to be used in the new object representation") #endif -#endif /* jsversion_h___ */ +#endif /* jsversion_h */ diff --git a/external/spidermonkey/include/win32/jswrapper.h b/external/spidermonkey/include/win32/jswrapper.h index d0c0fc625c..f78df7db60 100644 --- a/external/spidermonkey/include/win32/jswrapper.h +++ b/external/spidermonkey/include/win32/jswrapper.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jswrapper_h___ -#define jswrapper_h___ +#ifndef jswrapper_h +#define jswrapper_h #include "mozilla/Attributes.h" @@ -66,8 +66,6 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler static Wrapper singleton; static Wrapper singletonWithPrototype; - - static void *getWrapperFamily(); }; /* Base class for all cross compartment wrapper handlers. */ @@ -105,7 +103,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper MutableHandleValue vp) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -139,7 +137,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base public: SecurityWrapper(unsigned flags); - virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) MOZ_OVERRIDE; @@ -185,7 +183,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -297,4 +295,4 @@ struct JS_FRIEND_API(AutoMaybeTouchDeadZones) } /* namespace js */ -#endif +#endif /* jswrapper_h */ diff --git a/external/spidermonkey/include/win32/mozilla/AllocPolicy.h b/external/spidermonkey/include/win32/mozilla/AllocPolicy.h new file mode 100644 index 0000000000..20087e93bb --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/AllocPolicy.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * An allocation policy concept, usable for structures and algorithms to + * control how memory is allocated and how failures are handled. + */ + +#ifndef mozilla_AllocPolicy_h +#define mozilla_AllocPolicy_h + +#include +#include + +namespace mozilla { + +/* + * Allocation policies are used to implement the standard allocation behaviors + * in a customizable way. Additionally, custom behaviors may be added to these + * behaviors, such as additionally reporting an error through an out-of-band + * mechanism when OOM occurs. The concept modeled here is as follows: + * + * - public copy constructor, assignment, destructor + * - void* malloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* calloc_(size_t) + * Responsible for OOM reporting when null is returned. + * - void* realloc_(void*, size_t, size_t) + * Responsible for OOM reporting when null is returned. The *used* bytes + * of the previous buffer is passed in (rather than the old allocation + * size), in addition to the *new* allocation size requested. + * - void free_(void*) + * - void reportAllocOverflow() const + * Called on allocation overflow (that is, an allocation implicitly tried + * to allocate more than the available memory space -- think allocating an + * array of large-size objects, where N * size overflows) before null is + * returned. + * + * mfbt provides (and typically uses by default) only MallocAllocPolicy, which + * does nothing more than delegate to the malloc/alloc/free functions. + */ + +/* + * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no + * extra behaviors. + */ +class MallocAllocPolicy +{ + public: + void* malloc_(size_t bytes) { return malloc(bytes); } + void* calloc_(size_t bytes) { return calloc(bytes, 1); } + void* realloc_(void* p, size_t oldBytes, size_t bytes) { return realloc(p, bytes); } + void free_(void* p) { free(p); } + void reportAllocOverflow() const {} +}; + + +} // namespace mozilla + +#endif /* mozilla_AllocPolicy_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Array.h b/external/spidermonkey/include/win32/mozilla/Array.h new file mode 100644 index 0000000000..5af9aaa133 --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/Array.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A compile-time constant-length array with bounds-checking assertions. */ + +#ifndef mozilla_Array_h +#define mozilla_Array_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" + +#include + +namespace mozilla { + +template +class Array +{ + T arr[Length]; + + public: + T& operator[](size_t i) { + MOZ_ASSERT(i < Length); + return arr[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(i < Length); + return arr[i]; + } +}; + +template +class Array +{ + public: + T& operator[](size_t i) { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } + + const T& operator[](size_t i) const { + MOZ_ASSUME_UNREACHABLE("indexing into zero-length array"); + } +}; + +} /* namespace mozilla */ + +#endif /* mozilla_Array_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Assertions.h b/external/spidermonkey/include/win32/mozilla/Assertions.h index 5ead7f493e..00b7037802 100644 --- a/external/spidermonkey/include/win32/mozilla/Assertions.h +++ b/external/spidermonkey/include/win32/mozilla/Assertions.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of runtime and static assertion macros for C and C++. */ -#ifndef mozilla_Assertions_h_ -#define mozilla_Assertions_h_ +#ifndef mozilla_Assertions_h +#define mozilla_Assertions_h #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" @@ -39,44 +40,24 @@ #endif /* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time*. This - * can be useful when you make certain assumptions about what must hold for + * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. + * In C++11, static_assert is provided by the compiler to the same effect. + * This can be useful when you make certain assumptions about what must hold for * optimal, or even correct, behavior. For example, you might assert that the * size of a struct is a multiple of the target architecture's word size: * * struct S { ... }; + * // C * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, * "S should be a multiple of word size for efficiency"); + * // C++11 + * static_assert(sizeof(S) % sizeof(size_t) == 0, + * "S should be a multiple of word size for efficiency"); * * This macro can be used in any location where both an extern declaration and a * typedef could be used. - * - * Be aware of the gcc 4.2 concerns noted further down when writing patches that - * use this macro, particularly if a patch only bounces on OS X. */ -#ifdef __cplusplus -# if defined(__clang__) -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_extension(cxx_static_assert) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__GNUC__) -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(_MSC_VER) -# if _MSC_VER >= 1600 /* MSVC 10 */ -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# elif defined(__HP_aCC) -# if __HP_aCC >= 62500 && defined(_HP_CXX0x_SOURCE) -# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) -# endif -# endif -#endif -#ifndef MOZ_STATIC_ASSERT +#ifndef __cplusplus /* * Some of the definitions below create an otherwise-unused typedef. This * triggers compiler warnings with some versions of gcc, so mark the typedefs @@ -124,78 +105,23 @@ # define MOZ_STATIC_ASSERT(cond, reason) \ extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE # endif -#endif #define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) +#else +#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) +#endif #ifdef __cplusplus extern "C" { #endif -/* - * MOZ_CRASH crashes the program, plain and simple, in a Breakpad-compatible - * way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. We use TerminateProcess - * with the exit code aborting would generate because we don't want to invoke - * atexit handlers, destructors, library unload handlers, and so on when our - * process might be in a compromised state. We don't use abort() because - * it'd cause Windows to annoyingly pop up the process error dialog multiple - * times. See bug 345118 and bug 426163. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = 123; \ - TerminateProcess(GetCurrentProcess(), 3); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - ::abort(); \ - } while (0) -# else -# define MOZ_CRASH() \ - do { \ - *((volatile int*) NULL) = 123; \ - abort(); \ - } while (0) -# endif -#endif - /* * Prints |s| as an assertion failure (using file and ln as the location of the * assertion) to the standard debug-output channel. * - * Usually you should use MOZ_ASSERT instead of this method. This method is - * primarily for internal use in this header, and only secondarily for use in - * implementing release-build assertions. + * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This + * method is primarily for internal use in this header, and only secondarily + * for use in implementing release-build assertions. */ static MOZ_ALWAYS_INLINE void MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) @@ -209,6 +135,112 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif } +static MOZ_ALWAYS_INLINE void +MOZ_ReportCrash(const char* s, const char* file, int ln) +{ +#ifdef ANDROID + __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", + "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); + fflush(stderr); +#endif +} + +/** + * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should + * call MOZ_CRASH instead. + */ +#if defined(_MSC_VER) + /* + * On MSVC use the __debugbreak compiler intrinsic, which produces an inline + * (not nested in a system function) breakpoint. This distinctively invokes + * Breakpad without requiring system library symbols on all stack-processing + * machines, as a nested breakpoint would require. + * + * We use TerminateProcess with the exit code aborting would generate + * because we don't want to invoke atexit handlers, destructors, library + * unload handlers, and so on when our process might be in a compromised + * state. + * + * We don't use abort() because it'd cause Windows to annoyingly pop up the + * process error dialog multiple times. See bug 345118 and bug 426163. + * + * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the + * compiler doesn't hassle us to provide a return statement after a + * MOZ_REALLY_CRASH() call. + * + * (Technically these are Windows requirements, not MSVC requirements. But + * practically you need MSVC for debugging, and we only ship builds created + * by MSVC, so doing it this way reduces complexity.) + */ + +__declspec(noreturn) __inline void MOZ_NoReturn() {} + +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + ::TerminateProcess(::GetCurrentProcess(), 3); \ + ::MOZ_NoReturn(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + __debugbreak(); \ + *((volatile int*) NULL) = 123; \ + TerminateProcess(GetCurrentProcess(), 3); \ + MOZ_NoReturn(); \ + } while (0) +# endif +#else +# ifdef __cplusplus +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + ::abort(); \ + } while (0) +# else +# define MOZ_REALLY_CRASH() \ + do { \ + *((volatile int*) NULL) = 123; \ + abort(); \ + } while (0) +# endif +#endif + +/* + * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a + * Breakpad-compatible way, in both debug and release builds. + * + * MOZ_CRASH is a good solution for "handling" failure cases when you're + * unwilling or unable to handle them more cleanly -- for OOM, for likely memory + * corruption, and so on. It's also a good solution if you need safe behavior + * in release builds as well as debug builds. But if the failure is one that + * should be debugged and fixed, MOZ_ASSERT is generally preferable. + * + * The optional explanation-string, if provided, must be a string literal + * explaining why we're crashing. This argument is intended for use with + * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's + * obvious why we're crashing. + * + * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an + * explanation-string, we print the string to stderr. Otherwise, we don't + * print anything; this is because we want MOZ_CRASH to be 100% safe in release + * builds, and it's hard to print to stderr safely when memory might have been + * corrupted. + */ +#ifndef DEBUG +# define MOZ_CRASH(...) MOZ_REALLY_CRASH() +#else +# define MOZ_CRASH(...) \ + do { \ + MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ + MOZ_REALLY_CRASH(); \ + } while(0) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif @@ -251,7 +283,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* Now the two-argument form. */ @@ -259,7 +291,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) do { \ if (MOZ_UNLIKELY(!(expr))) { \ MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH(); \ + MOZ_REALLY_CRASH(); \ } \ } while (0) /* And now, helper macrology up the wazoo. */ @@ -310,14 +342,14 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) #endif /* - * MOZ_NOT_REACHED_MARKER() expands to an expression which states that it is + * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that it is * undefined behavior for execution to reach this point. No guarantees are made * about what will happen if this is reached at runtime. Most code should - * probably use the higher level MOZ_NOT_REACHED, which uses this when + * probably use the higher level MOZ_ASSUME_UNREACHABLE, which uses this when * appropriate. */ #if defined(__clang__) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() #elif defined(__GNUC__) /* * __builtin_unreachable() was implemented in gcc 4.5. If we don't have @@ -325,49 +357,71 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) * in C++ in case there's another abort() visible in local scope. */ # if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0) -# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable() +# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() # else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif # endif #elif defined(_MSC_VER) -# define MOZ_NOT_REACHED_MARKER() __assume(0) +# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) #else # ifdef __cplusplus -# define MOZ_NOT_REACHED_MARKER() ::abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() # else -# define MOZ_NOT_REACHED_MARKER() abort() +# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() # endif #endif /* - * MOZ_NOT_REACHED(reason) indicates that the given point can't be reached - * during execution: simply reaching that point in execution is a bug. It takes - * as an argument an error message indicating the reason why that point should - * not have been reachable. + * MOZ_ASSUME_UNREACHABLE([reason]) tells the compiler that it can assume that + * the macro call cannot be reached during execution. This lets the compiler + * generate better-optimized code under some circumstances, at the expense of + * the program's behavior being undefined if control reaches the + * MOZ_ASSUME_UNREACHABLE. * - * // ...in a language parser... - * void handle(BooleanLiteralNode node) + * In Gecko, you probably should not use this macro outside of performance- or + * size-critical code, because it's unsafe. If you don't care about code size + * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. + * + * SpiderMonkey is a different beast, and there it's acceptable to use + * MOZ_ASSUME_UNREACHABLE more widely. + * + * Note that MOZ_ASSUME_UNREACHABLE is noreturn, so it's valid not to return a + * value following a MOZ_ASSUME_UNREACHABLE call. + * + * Example usage: + * + * enum ValueType { + * VALUE_STRING, + * VALUE_INT, + * VALUE_FLOAT + * }; + * + * int ptrToInt(ValueType type, void* value) { * { - * if (node.isTrue()) - * handleTrueLiteral(); - * else if (node.isFalse()) - * handleFalseLiteral(); - * else - * MOZ_NOT_REACHED("boolean literal that's not true or false?"); + * // We know for sure that type is either INT or FLOAT, and we want this + * // code to run as quickly as possible. + * switch (type) { + * case VALUE_INT: + * return *(int*) value; + * case VALUE_FLOAT: + * return (int) *(float*) value; + * default: + * MOZ_ASSUME_UNREACHABLE("can only handle VALUE_INT and VALUE_FLOAT"); + * } * } */ #if defined(DEBUG) -# define MOZ_NOT_REACHED(reason) \ +# define MOZ_ASSUME_UNREACHABLE(...) \ do { \ - MOZ_ASSERT(false, reason); \ - MOZ_NOT_REACHED_MARKER(); \ + MOZ_ASSERT(false, "MOZ_ASSUME_UNREACHABLE(" __VA_ARGS__ ")"); \ + MOZ_ASSUME_UNREACHABLE_MARKER(); \ } while (0) #else -# define MOZ_NOT_REACHED(reason) MOZ_NOT_REACHED_MARKER() +# define MOZ_ASSUME_UNREACHABLE(reason) MOZ_ASSUME_UNREACHABLE_MARKER() #endif /* @@ -384,4 +438,4 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) # define MOZ_ALWAYS_FALSE(expr) ((void)(expr)) #endif -#endif /* mozilla_Assertions_h_ */ +#endif /* mozilla_Assertions_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Atomics.h b/external/spidermonkey/include/win32/mozilla/Atomics.h new file mode 100644 index 0000000000..f876683c3e --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/Atomics.h @@ -0,0 +1,1014 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Implements (almost always) lock-free atomic operations. The operations here + * are a subset of that which can be found in C++11's header, with a + * different API to enforce consistent memory ordering constraints. + * + * Anyone caught using |volatile| for inter-thread memory safety needs to be + * sent a copy of this header and the C++11 standard. + */ + +#ifndef mozilla_Atomics_h +#define mozilla_Atomics_h + +#include "mozilla/Assertions.h" +#include "mozilla/TypeTraits.h" + +#include + +/* + * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK + * does not have . So be sure to check for support + * along with C++0x support. + */ +#if defined(__clang__) + /* + * clang doesn't like libstdc++'s version of before GCC 4.7, + * due to the loose typing of the __sync_* family of functions done by + * GCC. We do not have a particularly good way to detect this sort of + * case at this point, so just assume that if we're on a Linux system, + * we can't use the system's . + * + * OpenBSD uses an old libstdc++ 4.2.1 and thus doesnt have . + */ +# if !defined(__linux__) && !defined(__OpenBSD__) && \ + (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && \ + __has_include() +# define MOZ_HAVE_CXX11_ATOMICS +# endif +/* + * Android uses a different C++ standard library that does not provide + * support for . + * + * GCC 4.5.x and 4.6.x's unspecialized std::atomic template doesn't include + * inline definitions for the functions declared therein. This oversight + * leads to linking errors when using atomic enums. We therefore require + * GCC 4.7 or higher. + */ +#elif defined(__GNUC__) && !defined(__ANDROID__) +# include "mozilla/Compiler.h" +# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && \ + MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) +# define MOZ_HAVE_CXX11_ATOMICS +# endif +#elif defined(_MSC_VER) && _MSC_VER >= 1700 +# define MOZ_HAVE_CXX11_ATOMICS +#endif + +namespace mozilla { + +/** + * An enum of memory ordering possibilities for atomics. + * + * Memory ordering is the observable state of distinct values in memory. + * (It's a separate concept from atomicity, which concerns whether an + * operation can ever be observed in an intermediate state. Don't + * conflate the two!) Given a sequence of operations in source code on + * memory, it is *not* always the case that, at all times and on all + * cores, those operations will appear to have occurred in that exact + * sequence. First, the compiler might reorder that sequence, if it + * thinks another ordering will be more efficient. Second, the CPU may + * not expose so consistent a view of memory. CPUs will often perform + * their own instruction reordering, above and beyond that performed by + * the compiler. And each core has its own memory caches, and accesses + * (reads and writes both) to "memory" may only resolve to out-of-date + * cache entries -- not to the "most recently" performed operation in + * some global sense. Any access to a value that may be used by + * multiple threads, potentially across multiple cores, must therefore + * have a memory ordering imposed on it, for all code on all + * threads/cores to have a sufficiently coherent worldview. + * + * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and + * http://en.cppreference.com/w/cpp/atomic/memory_order go into more + * detail on all this, including examples of how each mode works. + * + * Note that for simplicity and practicality, not all of the modes in + * C++11 are supported. The missing C++11 modes are either subsumed by + * the modes we provide below, or not relevant for the CPUs we support + * in Gecko. These three modes are confusing enough as it is! + */ +enum MemoryOrdering { + /* + * Relaxed ordering is the simplest memory ordering: none at all. + * When the result of a write is observed, nothing may be inferred + * about other memory. Writes ostensibly performed "before" on the + * writing thread may not yet be visible. Writes performed "after" on + * the writing thread may already be visible, if the compiler or CPU + * reordered them. (The latter can happen if reads and/or writes get + * held up in per-processor caches.) Relaxed ordering means + * operations can always use cached values (as long as the actual + * updates to atomic values actually occur, correctly, eventually), so + * it's usually the fastest sort of atomic access. For this reason, + * *it's also the most dangerous kind of access*. + * + * Relaxed ordering is good for things like process-wide statistics + * counters that don't need to be consistent with anything else, so + * long as updates themselves are atomic. (And so long as any + * observations of that value can tolerate being out-of-date -- if you + * need some sort of up-to-date value, you need some sort of other + * synchronizing operation.) It's *not* good for locks, mutexes, + * reference counts, etc. that mediate access to other memory, or must + * be observably consistent with other memory. + * + * x86 architectures don't take advantage of the optimization + * opportunities that relaxed ordering permits. Thus it's possible + * that using relaxed ordering will "work" on x86 but fail elsewhere + * (ARM, say, which *does* implement non-sequentially-consistent + * relaxed ordering semantics). Be extra-careful using relaxed + * ordering if you can't easily test non-x86 architectures! + */ + Relaxed, + /* + * When an atomic value is updated with ReleaseAcquire ordering, and + * that new value is observed with ReleaseAcquire ordering, prior + * writes (atomic or not) are also observable. What ReleaseAcquire + * *doesn't* give you is any observable ordering guarantees for + * ReleaseAcquire-ordered operations on different objects. For + * example, if there are two cores that each perform ReleaseAcquire + * operations on separate objects, each core may or may not observe + * the operations made by the other core. The only way the cores can + * be synchronized with ReleaseAcquire is if they both + * ReleaseAcquire-access the same object. This implies that you can't + * necessarily describe some global total ordering of ReleaseAcquire + * operations. + * + * ReleaseAcquire ordering is good for (as the name implies) atomic + * operations on values controlling ownership of things: reference + * counts, mutexes, and the like. However, if you are thinking about + * using these to implement your own locks or mutexes, you should take + * a good, hard look at actual lock or mutex primitives first. + */ + ReleaseAcquire, + /* + * When an atomic value is updated with SequentiallyConsistent + * ordering, all writes observable when the update is observed, just + * as with ReleaseAcquire ordering. But, furthermore, a global total + * ordering of SequentiallyConsistent operations *can* be described. + * For example, if two cores perform SequentiallyConsistent operations + * on separate objects, one core will observably perform its update + * (and all previous operations will have completed), then the other + * core will observably perform its update (and all previous + * operations will have completed). (Although those previous + * operations aren't themselves ordered -- they could be intermixed, + * or ordered if they occur on atomic values with ordering + * requirements.) SequentiallyConsistent is the *simplest and safest* + * ordering of atomic operations -- it's always as if one operation + * happens, then another, then another, in some order -- and every + * core observes updates to happen in that single order. Because it + * has the most synchronization requirements, operations ordered this + * way also tend to be slowest. + * + * SequentiallyConsistent ordering can be desirable when multiple + * threads observe objects, and they all have to agree on the + * observable order of changes to them. People expect + * SequentiallyConsistent ordering, even if they shouldn't, when + * writing code, atomic or otherwise. SequentiallyConsistent is also + * the ordering of choice when designing lockless data structures. If + * you don't know what order to use, use this one. + */ + SequentiallyConsistent, +}; + +} // namespace mozilla + +// Build up the underlying intrinsics. +#ifdef MOZ_HAVE_CXX11_ATOMICS + +# include + +namespace mozilla { +namespace detail { + +/* + * We provide CompareExchangeFailureOrder to work around a bug in some + * versions of GCC's header. See bug 898491. + */ +template struct AtomicOrderConstraints; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; + static const std::memory_order LoadOrder = std::memory_order_relaxed; + static const std::memory_order StoreOrder = std::memory_order_relaxed; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_relaxed; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; + static const std::memory_order LoadOrder = std::memory_order_acquire; + static const std::memory_order StoreOrder = std::memory_order_release; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_acquire; +}; + +template<> +struct AtomicOrderConstraints +{ + static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; + static const std::memory_order LoadOrder = std::memory_order_seq_cst; + static const std::memory_order StoreOrder = std::memory_order_seq_cst; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_seq_cst; +}; + +template +struct IntrinsicBase +{ + typedef std::atomic ValueType; + typedef AtomicOrderConstraints OrderedOp; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T load(const typename Base::ValueType& ptr) { + return ptr.load(Base::OrderedOp::LoadOrder); + } + static void store(typename Base::ValueType& ptr, T val) { + ptr.store(val, Base::OrderedOp::StoreOrder); + } + static T exchange(typename Base::ValueType& ptr, T val) { + return ptr.exchange(val, Base::OrderedOp::AtomicRMWOrder); + } + static bool compareExchange(typename Base::ValueType& ptr, T oldVal, T newVal) { + return ptr.compare_exchange_strong(oldVal, newVal, + Base::OrderedOp::AtomicRMWOrder, + Base::OrderedOp::CompareExchangeFailureOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T add(typename Base::ValueType& ptr, T val) { + return ptr.fetch_add(val, Base::OrderedOp::AtomicRMWOrder); + } + static T sub(typename Base::ValueType& ptr, T val) { + return ptr.fetch_sub(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicBase +{ + typedef IntrinsicBase Base; + static T* add(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_add(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + static T* sub(typename Base::ValueType& ptr, ptrdiff_t val) { + return ptr.fetch_sub(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); + } + private: + /* + * GCC 4.6's header has a bug where adding X to an + * atomic is not the same as adding X to a T*. Hence the need + * for this function to provide the correct addend. + */ + static ptrdiff_t fixupAddend(ptrdiff_t val) { +#if defined(__clang__) || defined(_MSC_VER) + return val; +#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \ + !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) + return val * sizeof(T); +#else + return val; +#endif + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + typedef IntrinsicBase Base; + static T inc(typename Base::ValueType& ptr) { + return IntrinsicAddSub::add(ptr, 1); + } + static T dec(typename Base::ValueType& ptr) { + return IntrinsicAddSub::sub(ptr, 1); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + typedef IntrinsicBase Base; + static T or_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_or(val, Base::OrderedOp::AtomicRMWOrder); + } + static T xor_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_xor(val, Base::OrderedOp::AtomicRMWOrder); + } + static T and_(typename Base::ValueType& ptr, T val) { + return ptr.fetch_and(val, Base::OrderedOp::AtomicRMWOrder); + } +}; + +template +struct AtomicIntrinsics + : public IntrinsicMemoryOps, public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(__GNUC__) + +namespace mozilla { +namespace detail { + +/* + * The __sync_* family of intrinsics is documented here: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html + * + * While these intrinsics are deprecated in favor of the newer __atomic_* + * family of intrincs: + * + * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html + * + * any GCC version that supports the __atomic_* intrinsics will also support + * the header and so will be handled above. We provide a version of + * atomics using the __sync_* intrinsics to support older versions of GCC. + * + * All __sync_* intrinsics that we use below act as full memory barriers, for + * both compiler and hardware reordering, except for __sync_lock_test_and_set, + * which is a only an acquire barrier. When we call __sync_lock_test_and_set, + * we add a barrier above it as appropriate. + */ + +template struct Barrier; + +/* + * Some processors (in particular, x86) don't require quite so many calls to + * __sync_sychronize as our specializations of Barrier produce. If + * performance turns out to be an issue, defining these specializations + * on a per-processor basis would be a good first tuning step. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() { __sync_synchronize(); } + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() { __sync_synchronize(); } +}; + +template +struct IntrinsicMemoryOps +{ + static T load(const T& ptr) { + Barrier::beforeLoad(); + T val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(T& ptr, T val) { + Barrier::beforeStore(); + ptr = val; + Barrier::afterStore(); + } + static T exchange(T& ptr, T val) { + // __sync_lock_test_and_set is only an acquire barrier; loads and stores + // can't be moved up from after to before it, but they can be moved down + // from before to after it. We may want a stricter ordering, so we need + // an explicit barrier. + + Barrier::beforeStore(); + return __sync_lock_test_and_set(&ptr, val); + } + static bool compareExchange(T& ptr, T oldVal, T newVal) { + return __sync_bool_compare_and_swap(&ptr, oldVal, newVal); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T ValueType; + static T add(T& ptr, T val) { + return __sync_fetch_and_add(&ptr, val); + } + static T sub(T& ptr, T val) { + return __sync_fetch_and_sub(&ptr, val); + } +}; + +template +struct IntrinsicAddSub +{ + typedef T* ValueType; + /* + * The reinterpret_casts are needed so that + * __sync_fetch_and_{add,sub} will properly type-check. + * + * Also, these functions do not provide standard semantics for + * pointer types, so we need to adjust the addend. + */ + static ValueType add(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_add(&ptr, amount); + } + static ValueType sub(ValueType& ptr, ptrdiff_t val) { + ValueType amount = reinterpret_cast(val * sizeof(T)); + return __sync_fetch_and_sub(&ptr, amount); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static T inc(T& ptr) { return IntrinsicAddSub::add(ptr, 1); } + static T dec(T& ptr) { return IntrinsicAddSub::sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static T or_(T& ptr, T val) { + return __sync_fetch_and_or(&ptr, val); + } + static T xor_(T& ptr, T val) { + return __sync_fetch_and_xor(&ptr, val); + } + static T and_(T& ptr, T val) { + return __sync_fetch_and_and(&ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#elif defined(_MSC_VER) + +/* + * Windows comes with a full complement of atomic operations. + * Unfortunately, most of those aren't available for Windows XP (even if + * the compiler supports intrinsics for them), which is the oldest + * version of Windows we support. Therefore, we only provide operations + * on 32-bit datatypes for 32-bit Windows versions; for 64-bit Windows + * versions, we support 64-bit datatypes as well. + * + * To avoid namespace pollution issues, we declare whatever functions we + * need ourselves. + */ + +extern "C" { +long __cdecl _InterlockedExchangeAdd(long volatile* dst, long value); +long __cdecl _InterlockedOr(long volatile* dst, long value); +long __cdecl _InterlockedXor(long volatile* dst, long value); +long __cdecl _InterlockedAnd(long volatile* dst, long value); +long __cdecl _InterlockedExchange(long volatile *dst, long value); +long __cdecl _InterlockedCompareExchange(long volatile *dst, long newVal, long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd) +# pragma intrinsic(_InterlockedOr) +# pragma intrinsic(_InterlockedXor) +# pragma intrinsic(_InterlockedAnd) +# pragma intrinsic(_InterlockedExchange) +# pragma intrinsic(_InterlockedCompareExchange) + +namespace mozilla { +namespace detail { + +# if !defined(_M_IX86) && !defined(_M_X64) + /* + * The implementations below are optimized for x86ish systems. You + * will have to modify them if you are porting to Windows on a + * different architecture. + */ +# error "Unknown CPU type" +# endif + +/* + * The PrimitiveIntrinsics template should define |Type|, the datatype of size + * DataSize upon which we operate, and the following eight functions. + * + * static Type add(Type* ptr, Type val); + * static Type sub(Type* ptr, Type val); + * static Type or_(Type* ptr, Type val); + * static Type xor_(Type* ptr, Type val); + * static Type and_(Type* ptr, Type val); + * + * These functions perform the obvious operation on the value contained in + * |*ptr| combined with |val| and return the value previously stored in + * |*ptr|. + * + * static void store(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and must provide a full + * memory fence after the store to prevent compiler and hardware instruction + * reordering. It should also act as a compiler barrier to prevent reads and + * writes from moving to after the store. + * + * static Type exchange(Type* ptr, Type val); + * + * This function atomically stores |val| into |*ptr| and returns the previous + * contents of *ptr; + * + * static bool compareExchange(Type* ptr, Type oldVal, Type newVal); + * + * This function atomically performs the following operation: + * + * if (*ptr == oldVal) { + * *ptr = newVal; + * return true; + * } else { + * return false; + * } + * + */ +template struct PrimitiveIntrinsics; + +template<> +struct PrimitiveIntrinsics<4> +{ + typedef long Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * _InterlockedExchangeSubtract isn't available before Windows 7, + * and we must support Windows XP. + */ + return _InterlockedExchangeAdd(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange(ptr, newVal, oldVal) == oldVal; + } +}; + +# if defined(_M_X64) + +extern "C" { +long long __cdecl _InterlockedExchangeAdd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedOr64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedXor64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedAnd64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedExchange64(long long volatile* dst, + long long value); +long long __cdecl _InterlockedCompareExchange64(long long volatile* dst, + long long newVal, + long long oldVal); +} + +# pragma intrinsic(_InterlockedExchangeAdd64) +# pragma intrinsic(_InterlockedOr64) +# pragma intrinsic(_InterlockedXor64) +# pragma intrinsic(_InterlockedAnd64) +# pragma intrinsic(_InterlockedExchange64) +# pragma intrinsic(_InterlockedCompareExchange64) + +template <> +struct PrimitiveIntrinsics<8> +{ + typedef __int64 Type; + + static Type add(Type* ptr, Type val) { + return _InterlockedExchangeAdd64(ptr, val); + } + static Type sub(Type* ptr, Type val) { + /* + * There is no _InterlockedExchangeSubtract64. + */ + return _InterlockedExchangeAdd64(ptr, -val); + } + static Type or_(Type* ptr, Type val) { + return _InterlockedOr64(ptr, val); + } + static Type xor_(Type* ptr, Type val) { + return _InterlockedXor64(ptr, val); + } + static Type and_(Type* ptr, Type val) { + return _InterlockedAnd64(ptr, val); + } + static void store(Type* ptr, Type val) { + _InterlockedExchange64(ptr, val); + } + static Type exchange(Type* ptr, Type val) { + return _InterlockedExchange64(ptr, val); + } + static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { + return _InterlockedCompareExchange64(ptr, newVal, oldVal) == oldVal; + } +}; + +# endif + +extern "C" { void _ReadWriteBarrier(); } + +# pragma intrinsic(_ReadWriteBarrier) + +template struct Barrier; + +/* + * We do not provide an afterStore method in Barrier, as Relaxed and + * ReleaseAcquire orderings do not require one, and the required barrier + * for SequentiallyConsistent is handled by PrimitiveIntrinsics. + */ + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} +}; + +template<> +struct Barrier +{ + static void beforeLoad() {} + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template<> +struct Barrier +{ + static void beforeLoad() { _ReadWriteBarrier(); } + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T val) { return static_cast(val); } + static T fromPrimType(PrimType val) { return static_cast(val); } +}; + +template +struct CastHelper +{ + static PrimType toPrimType(T* val) { return reinterpret_cast(val); } + static T* fromPrimType(PrimType val) { return reinterpret_cast(val); } +}; + +template +struct IntrinsicBase +{ + typedef T ValueType; + typedef PrimitiveIntrinsics Primitives; + typedef typename Primitives::Type PrimType; + static_assert(sizeof(PrimType) == sizeof(T), + "Selection of PrimitiveIntrinsics was wrong"); + typedef CastHelper Cast; +}; + +template +struct IntrinsicMemoryOps : public IntrinsicBase +{ + static ValueType load(const ValueType& ptr) { + Barrier::beforeLoad(); + ValueType val = ptr; + Barrier::afterLoad(); + return val; + } + static void store(ValueType& ptr, ValueType val) { + // For SequentiallyConsistent, Primitives::store() will generate the + // proper memory fence. Everything else just needs a barrier before + // the store. + if (Order == SequentiallyConsistent) { + Primitives::store(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + } else { + Barrier::beforeStore(); + ptr = val; + } + } + static ValueType exchange(ValueType& ptr, ValueType val) { + PrimType oldval = + Primitives::exchange(reinterpret_cast(&ptr), + Cast::toPrimType(val)); + return Cast::fromPrimType(oldval); + } + static bool compareExchange(ValueType& ptr, ValueType oldVal, ValueType newVal) { + return Primitives::compareExchange(reinterpret_cast(&ptr), + Cast::toPrimType(oldVal), + Cast::toPrimType(newVal)); + } +}; + +template +struct IntrinsicApplyHelper : public IntrinsicBase +{ + typedef PrimType (*BinaryOp)(PrimType*, PrimType); + typedef PrimType (*UnaryOp)(PrimType*); + + static ValueType applyBinaryFunction(BinaryOp op, ValueType& ptr, + ValueType val) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + PrimType primTypeVal = Cast::toPrimType(val); + return Cast::fromPrimType(op(primTypePtr, primTypeVal)); + } + + static ValueType applyUnaryFunction(UnaryOp op, ValueType& ptr) { + PrimType* primTypePtr = reinterpret_cast(&ptr); + return Cast::fromPrimType(op(primTypePtr)); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::add, ptr, val); + } + static ValueType sub(ValueType& ptr, ValueType val) { + return applyBinaryFunction(&Primitives::sub, ptr, val); + } +}; + +template +struct IntrinsicAddSub : public IntrinsicApplyHelper +{ + static ValueType add(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::add, ptr, + (ValueType)(amount * sizeof(ValueType))); + } + static ValueType sub(ValueType& ptr, ptrdiff_t amount) { + return applyBinaryFunction(&Primitives::sub, ptr, + (ValueType)(amount * sizeof(ValueType))); + } +}; + +template +struct IntrinsicIncDec : public IntrinsicAddSub +{ + static ValueType inc(ValueType& ptr) { return add(ptr, 1); } + static ValueType dec(ValueType& ptr) { return sub(ptr, 1); } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ + static ValueType or_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::or_, ptr, val); + } + static ValueType xor_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::xor_, ptr, val); + } + static ValueType and_(ValueType& ptr, T val) { + return applyBinaryFunction(&Primitives::and_, ptr, val); + } +}; + +template +struct AtomicIntrinsics : public IntrinsicMemoryOps, + public IntrinsicIncDec +{ +}; + +} // namespace detail +} // namespace mozilla + +#else +# error "Atomic compiler intrinsics are not supported on your platform" +#endif + +namespace mozilla { + +namespace detail { + +template +class AtomicBase +{ + // We only support 32-bit types on 32-bit Windows, which constrains our + // implementation elsewhere. But we support pointer-sized types everywhere. + static_assert(sizeof(T) == 4 || (sizeof(uintptr_t) == 8 && sizeof(T) == 8), + "mozilla/Atomics.h only supports 32-bit and pointer-sized types"); + + protected: + typedef typename detail::AtomicIntrinsics Intrinsics; + typename Intrinsics::ValueType mValue; + + public: + AtomicBase() : mValue() {} + AtomicBase(T aInit) { Intrinsics::store(mValue, aInit); } + + operator T() const { return Intrinsics::load(mValue); } + + T operator=(T aValue) { + Intrinsics::store(mValue, aValue); + return aValue; + } + + /** + * Performs an atomic swap operation. aValue is stored and the previous + * value of this variable is returned. + */ + T exchange(T aValue) { + return Intrinsics::exchange(mValue, aValue); + } + + /** + * Performs an atomic compare-and-swap operation and returns true if it + * succeeded. This is equivalent to atomically doing + * + * if (mValue == aOldValue) { + * mValue = aNewValue; + * return true; + * } else { + * return false; + * } + */ + bool compareExchange(T aOldValue, T aNewValue) { + return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); + } + + private: + template + AtomicBase(const AtomicBase& aCopy) MOZ_DELETE; +}; + +template +class AtomicBaseIncDec : public AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + AtomicBaseIncDec() : Base() {} + AtomicBaseIncDec(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } + T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } + T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } + T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } + + private: + template + AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) MOZ_DELETE; +}; + +} // namespace detail + +/** + * A wrapper for a type that enforces that all memory accesses are atomic. + * + * In general, where a variable |T foo| exists, |Atomic foo| can be used in + * its place. Implementations for integral and pointer types are provided + * below. + * + * Atomic accesses are sequentially consistent by default. You should + * use the default unless you are tall enough to ride the + * memory-ordering roller coaster (if you're not sure, you aren't) and + * you have a compelling reason to do otherwise. + * + * There is one exception to the case of atomic memory accesses: providing an + * initial value of the atomic value is not guaranteed to be atomic. This is a + * deliberate design choice that enables static atomic variables to be declared + * without introducing extra static constructors. + */ +template +class Atomic; + +/** + * Atomic implementation for integral types. + * + * In addition to atomic store and load operations, compound assignment and + * increment/decrement operators are implemented which perform the + * corresponding read-modify-write operation atomically. Finally, an atomic + * swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + T operator+=(T delta) { return Base::Intrinsics::add(Base::mValue, delta) + delta; } + T operator-=(T delta) { return Base::Intrinsics::sub(Base::mValue, delta) - delta; } + T operator|=(T val) { return Base::Intrinsics::or_(Base::mValue, val) | val; } + T operator^=(T val) { return Base::Intrinsics::xor_(Base::mValue, val) ^ val; } + T operator&=(T val) { return Base::Intrinsics::and_(Base::mValue, val) & val; } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for pointer types. + * + * An atomic compare-and-swap primitive for pointer variables is provided, as + * are atomic increment and decement operators. Also provided are the compound + * assignment operators for addition and subtraction. Atomic swap (via + * exchange()) is included as well. + */ +template +class Atomic : public detail::AtomicBaseIncDec +{ + typedef typename detail::AtomicBaseIncDec Base; + + public: + Atomic() : Base() {} + Atomic(T* aInit) : Base(aInit) {} + + using Base::operator=; + + T* operator+=(ptrdiff_t delta) { + return Base::Intrinsics::add(Base::mValue, delta) + delta; + } + T* operator-=(ptrdiff_t delta) { + return Base::Intrinsics::sub(Base::mValue, delta) - delta; + } + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +/** + * Atomic implementation for enum types. + * + * The atomic store and load operations and the atomic swap method is provided. + */ +template +class Atomic::value>::Type> + : public detail::AtomicBase +{ + typedef typename detail::AtomicBase Base; + + public: + Atomic() : Base() {} + Atomic(T aInit) : Base(aInit) {} + + using Base::operator=; + + private: + Atomic(Atomic& aOther) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_Atomics_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Attributes.h b/external/spidermonkey/include/win32/mozilla/Attributes.h index 89f3641fc9..6ea9776fbf 100644 --- a/external/spidermonkey/include/win32/mozilla/Attributes.h +++ b/external/spidermonkey/include/win32/mozilla/Attributes.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of various class and method modifier attributes. */ -#ifndef mozilla_Attributes_h_ -#define mozilla_Attributes_h_ +#ifndef mozilla_Attributes_h +#define mozilla_Attributes_h #include "mozilla/Compiler.h" @@ -117,11 +118,18 @@ * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a * function at compile time. A constexpr function cannot examine any values * except its arguments and can have no side effects except its return value. + * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's + * value may be computed at compile time. It should be prefered to just + * marking variables as MOZ_CONSTEXPR because if the compiler does not support + * constexpr it will fall back to making the variable const, and some compilers + * do not accept variables being marked both const and constexpr. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR # define MOZ_CONSTEXPR constexpr +# define MOZ_CONSTEXPR_VAR constexpr #else # define MOZ_CONSTEXPR /* no support */ +# define MOZ_CONSTEXPR_VAR const #endif /* @@ -382,18 +390,42 @@ * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is * expected to live on the stack, so it is a compile-time error to use it, or * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). It may be a base or - * a member of another class only if both classes are marked with this - * annotation. + * a new expression (unless placement new is being used). If a member of + * another class uses this class, or if another class inherits from this + * class, then it is considered to be a stack class as well, although this + * attribute need not be provided in such cases. + * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is + * expected to live on the stack or in static storage, so it is a compile-time + * error to use it, or an array of such objects, as the type of a new + * expression (unless placement new is being used). If a member of another + * class uses this class, or if another class inherits from this class, then + * it is considered to be a non-heap class as well, although this attribute + * need not be provided in such cases. */ #ifdef MOZ_CLANG_PLUGIN # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) +# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) #else # define MOZ_MUST_OVERRIDE /* nothing */ # define MOZ_STACK_CLASS /* nothing */ +# define MOZ_NONHEAP_CLASS /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ +/* + * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that + * it's safe to use 'this' in an initializer list. + */ +#ifdef _MSC_VER +# define MOZ_THIS_IN_INITIALIZER_LIST() \ + __pragma(warning(push)) \ + __pragma(warning(disable:4355)) \ + this \ + __pragma(warning(pop)) +#else +# define MOZ_THIS_IN_INITIALIZER_LIST() this +#endif + #endif /* __cplusplus */ -#endif /* mozilla_Attributes_h_ */ +#endif /* mozilla_Attributes_h */ diff --git a/external/spidermonkey/include/win32/mozilla/BloomFilter.h b/external/spidermonkey/include/win32/mozilla/BloomFilter.h index 8680ef2907..afe4b72b80 100644 --- a/external/spidermonkey/include/win32/mozilla/BloomFilter.h +++ b/external/spidermonkey/include/win32/mozilla/BloomFilter.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * A counting Bloom filter implementation. This allows consumers to @@ -10,14 +11,14 @@ * incorrectly answer "yes" when the correct answer is "no"). */ -#ifndef mozilla_BloomFilter_h_ -#define mozilla_BloomFilter_h_ +#ifndef mozilla_BloomFilter_h +#define mozilla_BloomFilter_h #include "mozilla/Assertions.h" #include "mozilla/Likely.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Util.h" +#include #include namespace mozilla { @@ -105,7 +106,7 @@ class BloomFilter */ public: BloomFilter() { - MOZ_STATIC_ASSERT(KeySize <= keyShift, "KeySize too big"); + static_assert(KeySize <= keyShift, "KeySize too big"); // Should we have a custom operator new using calloc instead and // require that we're allocated via the operator? @@ -231,4 +232,4 @@ BloomFilter::mightContain(const T* t) const } // namespace mozilla -#endif /* mozilla_BloomFilter_h_ */ +#endif /* mozilla_BloomFilter_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Casting.h b/external/spidermonkey/include/win32/mozilla/Casting.h index b1e81c33fa..76df0ef27e 100644 --- a/external/spidermonkey/include/win32/mozilla/Casting.h +++ b/external/spidermonkey/include/win32/mozilla/Casting.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cast operations to supplement the built-in casting operations. */ -#ifndef mozilla_Casting_h_ -#define mozilla_Casting_h_ +#ifndef mozilla_Casting_h +#define mozilla_Casting_h #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" @@ -15,6 +16,27 @@ namespace mozilla { +/** + * Return a value of type |To|, containing the underlying bit pattern of |from|. + * + * |To| and |From| must be types of the same size; be careful of cross-platform + * size differences, or this might fail to compile on some but not all + * platforms. + */ +template +inline To +BitwiseCast(const From from) +{ + static_assert(sizeof(From) == sizeof(To), + "To and From must have the same size"); + union { + From from; + To to; + } u; + u.from = from; + return u.to; +} + namespace detail { enum ToSignedness { ToIsSigned, ToIsUnsigned }; @@ -43,7 +65,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return from <= From(To(-1)); } }; @@ -52,7 +74,7 @@ template struct UnsignedUnsignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -61,8 +83,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedUnsignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedUnsignedCheck::checkBounds(from); } }; @@ -72,7 +94,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (from < 0) return false; if (sizeof(To) >= sizeof(From)) @@ -93,7 +115,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { return true; } }; @@ -102,7 +124,7 @@ template struct UnsignedSignedCheck { public: - static bool check(const From from) { + static bool checkBounds(const From from) { const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); return from <= From(MaxValue); } @@ -112,8 +134,8 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { - return UnsignedSignedCheck::check(from); + static bool checkBounds(const From from) { + return UnsignedSignedCheck::checkBounds(from); } }; @@ -123,7 +145,7 @@ template struct BoundsCheckImpl { public: - static bool check(const From from) { + static bool checkBounds(const From from) { if (sizeof(From) <= sizeof(To)) return true; const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); @@ -141,15 +163,15 @@ template class BoundsChecker { public: - static bool check(const From from) { return true; } + static bool checkBounds(const From from) { return true; } }; template class BoundsChecker { public: - static bool check(const From from) { - return BoundsCheckImpl::check(from); + static bool checkBounds(const From from) { + return BoundsCheckImpl::checkBounds(from); } }; @@ -157,7 +179,7 @@ template inline bool IsInBounds(const From from) { - return BoundsChecker::check(from); + return BoundsChecker::checkBounds(from); } } // namespace detail @@ -177,4 +199,4 @@ SafeCast(const From from) } // namespace mozilla -#endif /* mozilla_Casting_h_ */ +#endif /* mozilla_Casting_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Char16.h b/external/spidermonkey/include/win32/mozilla/Char16.h index c6f9f87d44..e4b184f950 100644 --- a/external/spidermonkey/include/win32/mozilla/Char16.h +++ b/external/spidermonkey/include/win32/mozilla/Char16.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implements a UTF-16 character type. */ -#ifndef mozilla_Char16_h_ -#define mozilla_Char16_h_ +#ifndef mozilla_Char16_h +#define mozilla_Char16_h #include "mozilla/Assertions.h" @@ -49,8 +50,8 @@ */ #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s) -MOZ_STATIC_ASSERT(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); -MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); +static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); +static_assert(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); +static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); -#endif /* mozilla_Char16_h_ */ +#endif /* mozilla_Char16_h */ diff --git a/external/spidermonkey/include/win32/mozilla/CheckedInt.h b/external/spidermonkey/include/win32/mozilla/CheckedInt.h index 1dc80b032b..050cef8ed8 100644 --- a/external/spidermonkey/include/win32/mozilla/CheckedInt.h +++ b/external/spidermonkey/include/win32/mozilla/CheckedInt.h @@ -1,23 +1,23 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Provides checked integers, detecting integer overflow and divide-by-0. */ -#ifndef mozilla_CheckedInt_h_ -#define mozilla_CheckedInt_h_ +#ifndef mozilla_CheckedInt_h +#define mozilla_CheckedInt_h // Enable relying of Mozilla's MFBT for possibly-available C++11 features #define MOZ_CHECKEDINT_USE_MFBT +#include + #ifdef MOZ_CHECKEDINT_USE_MFBT # include "mozilla/Assertions.h" -# include "mozilla/StandardInteger.h" #else # include -# include -# define MOZ_STATIC_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_ASSERT(cond, reason) assert((cond) && reason) # define MOZ_DELETE #endif @@ -450,6 +450,44 @@ IsDivValid(T x, T y) !(IsSigned::value && x == MinValue::value && y == T(-1)); } +template::value> +struct IsModValidImpl; + +template +inline bool +IsModValid(T x, T y) +{ + return IsModValidImpl::run(x, y); +} + +/* + * Mod is pretty simple. + * For now, let's just use the ANSI C definition: + * If x or y are negative, the results are implementation defined. + * Consider these invalid. + * Undefined for y=0. + * The result will never exceed either x or y. + * + * Checking that x>=0 is a warning when T is unsigned. + */ + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + return y >= 1; + } +}; + +template +struct IsModValidImpl { + static inline bool run(T x, T y) { + if (x < 0) + return false; + + return y >= 1; + } +}; + template::value> struct NegateImpl; @@ -528,7 +566,7 @@ struct NegateImpl CheckedInt x(-1); // 1000 is of type int16_t, is found not to be in range for int8_t, // x is invalid - CheckedInt x(int16_t(1000)); + CheckedInt x(int16_t(1000)); // 3123456789 is of type uint32_t, is found not to be in range for int32_t, // x is invalid CheckedInt x(uint32_t(3123456789)); @@ -561,12 +599,12 @@ class CheckedInt template CheckedInt(U value, bool isValid) : mValue(value), mIsValid(isValid) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); } - friend class detail::NegateImpl; + friend struct detail::NegateImpl; public: /** @@ -585,16 +623,27 @@ class CheckedInt : mValue(T(value)), mIsValid(detail::IsInRange(value)) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } + + template + friend class CheckedInt; + + template + CheckedInt toChecked() const + { + CheckedInt ret(mValue); + ret.mIsValid = ret.mIsValid && mIsValid; + return ret; } /** Constructs a valid checked integer with initial value 0 */ CheckedInt() : mValue(0), mIsValid(true) { - MOZ_STATIC_ASSERT(detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value, + "This type is not supported by CheckedInt"); } /** @returns the actual value */ @@ -619,22 +668,31 @@ class CheckedInt const CheckedInt& rhs); template CheckedInt& operator +=(U rhs); + template friend CheckedInt operator -(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator -=(U rhs); + template friend CheckedInt operator *(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator *=(U rhs); + template friend CheckedInt operator /(const CheckedInt& lhs, - const CheckedInt &rhs); + const CheckedInt& rhs); template CheckedInt& operator /=(U rhs); + template + friend CheckedInt operator %(const CheckedInt& lhs, + const CheckedInt& rhs); + template + CheckedInt& operator %=(U rhs); + CheckedInt operator -() const { return detail::NegateImpl::negate(*this); @@ -726,6 +784,7 @@ MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) +MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) #undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR @@ -757,9 +816,9 @@ template inline typename detail::CastToCheckedIntImpl::ReturnType castToCheckedInt(U u) { - MOZ_STATIC_ASSERT(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); return detail::CastToCheckedIntImpl::run(u); } @@ -786,6 +845,7 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) +MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) #undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS @@ -815,4 +875,4 @@ typedef CheckedInt CheckedUint64; } // namespace mozilla -#endif /* mozilla_CheckedInt_h_ */ +#endif /* mozilla_CheckedInt_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Compiler.h b/external/spidermonkey/include/win32/mozilla/Compiler.h index 58239b0e30..d1ef1e79aa 100644 --- a/external/spidermonkey/include/win32/mozilla/Compiler.h +++ b/external/spidermonkey/include/win32/mozilla/Compiler.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various compiler checks. */ -#ifndef mozilla_Compiler_h_ -#define mozilla_Compiler_h_ +#ifndef mozilla_Compiler_h +#define mozilla_Compiler_h #if !defined(__clang__) && defined(__GNUC__) @@ -28,4 +29,4 @@ #endif -#endif /* mozilla_Compiler_h_ */ +#endif /* mozilla_Compiler_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Constants.h b/external/spidermonkey/include/win32/mozilla/Constants.h index 904b30145a..86bbb6b354 100644 --- a/external/spidermonkey/include/win32/mozilla/Constants.h +++ b/external/spidermonkey/include/win32/mozilla/Constants.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt math constants. */ -#ifndef mozilla_Constants_h_ -#define mozilla_Constants_h_ +#ifndef mozilla_Constants_h +#define mozilla_Constants_h #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -#endif /* mozilla_Constants_h_ */ +#endif /* mozilla_Constants_h */ diff --git a/external/spidermonkey/include/win32/mozilla/DebugOnly.h b/external/spidermonkey/include/win32/mozilla/DebugOnly.h index 1f78ed7989..e5f0d729b5 100644 --- a/external/spidermonkey/include/win32/mozilla/DebugOnly.h +++ b/external/spidermonkey/include/win32/mozilla/DebugOnly.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * assertions). */ -#ifndef mozilla_DebugOnly_h_ -#define mozilla_DebugOnly_h_ +#ifndef mozilla_DebugOnly_h +#define mozilla_DebugOnly_h namespace mozilla { @@ -74,4 +75,4 @@ class DebugOnly } -#endif /* mozilla_DebugOnly_h_ */ +#endif /* mozilla_DebugOnly_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Decimal.h b/external/spidermonkey/include/win32/mozilla/Decimal.h index 8032fd6e23..3c67d784c9 100644 --- a/external/spidermonkey/include/win32/mozilla/Decimal.h +++ b/external/spidermonkey/include/win32/mozilla/Decimal.h @@ -38,7 +38,7 @@ #define Decimal_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" +#include #include "mozilla/Types.h" #include diff --git a/external/spidermonkey/include/win32/mozilla/Endian.h b/external/spidermonkey/include/win32/mozilla/Endian.h index 5d2f905b41..dc6d11d3ba 100644 --- a/external/spidermonkey/include/win32/mozilla/Endian.h +++ b/external/spidermonkey/include/win32/mozilla/Endian.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -59,16 +60,16 @@ * }; */ -#ifndef mozilla_Endian_h_ -#define mozilla_Endian_h_ +#ifndef mozilla_Endian_h +#define mozilla_Endian_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/DebugOnly.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" +#include #include #if defined(_MSC_VER) && _MSC_VER >= 1300 @@ -636,4 +637,4 @@ class NativeEndian MOZ_FINAL : public detail::Endian } /* namespace mozilla */ -#endif /* mozilla_Endian_h_ */ +#endif /* mozilla_Endian_h */ diff --git a/external/spidermonkey/include/win32/mozilla/EnumSet.h b/external/spidermonkey/include/win32/mozilla/EnumSet.h index b18b005669..95c5608cf4 100644 --- a/external/spidermonkey/include/win32/mozilla/EnumSet.h +++ b/external/spidermonkey/include/win32/mozilla/EnumSet.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,7 +10,8 @@ #define mozilla_EnumSet_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" + +#include namespace mozilla { @@ -172,4 +174,4 @@ class EnumSet } // namespace mozilla -#endif // mozilla_EnumSet_h_ +#endif /* mozilla_EnumSet_h_*/ diff --git a/external/spidermonkey/include/win32/mozilla/FloatingPoint.h b/external/spidermonkey/include/win32/mozilla/FloatingPoint.h index 30af2217b1..d80f6a7234 100644 --- a/external/spidermonkey/include/win32/mozilla/FloatingPoint.h +++ b/external/spidermonkey/include/win32/mozilla/FloatingPoint.h @@ -1,16 +1,19 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Various predicates and operations on IEEE-754 floating point types. */ -#ifndef mozilla_FloatingPoint_h_ -#define mozilla_FloatingPoint_h_ +#ifndef mozilla_FloatingPoint_h +#define mozilla_FloatingPoint_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" +#include "mozilla/Casting.h" + +#include namespace mozilla { @@ -35,80 +38,58 @@ namespace mozilla { * the case. But we required this in implementations of these algorithms that * preceded this header, so we shouldn't break anything if we continue doing so. */ -MOZ_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); +static_assert(sizeof(double) == sizeof(uint64_t), "double must be 64 bits"); const unsigned DoubleExponentBias = 1023; const unsigned DoubleExponentShift = 52; -namespace detail { - const uint64_t DoubleSignBit = 0x8000000000000000ULL; const uint64_t DoubleExponentBits = 0x7ff0000000000000ULL; const uint64_t DoubleSignificandBits = 0x000fffffffffffffULL; -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleExponentBits) == 0, - "sign bit doesn't overlap exponent bits"); -MOZ_STATIC_ASSERT((DoubleSignBit & DoubleSignificandBits) == 0, - "sign bit doesn't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleExponentBits & DoubleSignificandBits) == 0, - "exponent bits don't overlap significand bits"); +static_assert((DoubleSignBit & DoubleExponentBits) == 0, + "sign bit doesn't overlap exponent bits"); +static_assert((DoubleSignBit & DoubleSignificandBits) == 0, + "sign bit doesn't overlap significand bits"); +static_assert((DoubleExponentBits & DoubleSignificandBits) == 0, + "exponent bits don't overlap significand bits"); -MOZ_STATIC_ASSERT((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == - ~uint64_t(0), - "all bits accounted for"); - -union DoublePun -{ - /* - * Every way to pun the bits of a double introduces an additional layer of - * complexity, across a multitude of platforms, architectures, and ABIs. - * Use *only* uint64_t to reduce complexity. Don't add new punning here - * without discussion! - */ - uint64_t u; - double d; -}; - -} /* namespace detail */ +static_assert((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == + ~uint64_t(0), + "all bits accounted for"); /** Determines whether a double is NaN. */ static MOZ_ALWAYS_INLINE bool IsNaN(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * A double is NaN if all exponent bits are 1 and the significand contains at * least one non-zero bit. */ - return (pun.u & detail::DoubleExponentBits) == detail::DoubleExponentBits && - (pun.u & detail::DoubleSignificandBits) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) == DoubleExponentBits && + (bits & DoubleSignificandBits) != 0; } /** Determines whether a double is +Infinity or -Infinity. */ static MOZ_ALWAYS_INLINE bool IsInfinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - return (pun.u & ~detail::DoubleSignBit) == detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & ~DoubleSignBit) == DoubleExponentBits; } /** Determines whether a double is not NaN or infinite. */ static MOZ_ALWAYS_INLINE bool IsFinite(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * NaN and Infinities are the only non-finite doubles, and both have all * exponent bits set to 1. */ - return (pun.u & detail::DoubleExponentBits) != detail::DoubleExponentBits; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleExponentBits) != DoubleExponentBits; } /** @@ -120,36 +101,30 @@ IsNegative(double d) { MOZ_ASSERT(!IsNaN(d), "NaN does not have a sign"); - union detail::DoublePun pun; - pun.d = d; - /* The sign bit is set if the double is negative. */ - return (pun.u & detail::DoubleSignBit) != 0; + uint64_t bits = BitwiseCast(d); + return (bits & DoubleSignBit) != 0; } /** Determines whether a double represents -0. */ static MOZ_ALWAYS_INLINE bool IsNegativeZero(double d) { - union detail::DoublePun pun; - pun.d = d; - /* Only the sign bit is set if the double is -0. */ - return pun.u == detail::DoubleSignBit; + uint64_t bits = BitwiseCast(d); + return bits == DoubleSignBit; } /** Returns the exponent portion of the double. */ static MOZ_ALWAYS_INLINE int_fast16_t ExponentComponent(double d) { - union detail::DoublePun pun; - pun.d = d; - /* * The exponent component of a double is an unsigned number, biased from its * actual value. Subtract the bias to retrieve the actual exponent. */ - return int_fast16_t((pun.u & detail::DoubleExponentBits) >> DoubleExponentShift) - + uint64_t bits = BitwiseCast(d); + return int_fast16_t((bits & DoubleExponentBits) >> DoubleExponentShift) - int_fast16_t(DoubleExponentBias); } @@ -157,28 +132,22 @@ ExponentComponent(double d) static MOZ_ALWAYS_INLINE double PositiveInfinity() { - union detail::DoublePun pun; - /* * Positive infinity has all exponent bits set, sign bit set to 0, and no * significand. */ - pun.u = detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleExponentBits); } /** Returns -Infinity. */ static MOZ_ALWAYS_INLINE double NegativeInfinity() { - union detail::DoublePun pun; - /* * Negative infinity has all exponent bits set, sign bit set to 1, and no * significand. */ - pun.u = detail::DoubleSignBit | detail::DoubleExponentBits; - return pun.d; + return BitwiseCast(DoubleSignBit | DoubleExponentBits); } /** Constructs a NaN value with the specified sign bit and significand bits. */ @@ -186,24 +155,21 @@ static MOZ_ALWAYS_INLINE double SpecificNaN(int signbit, uint64_t significand) { MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~detail::DoubleSignificandBits) == 0); - MOZ_ASSERT(significand & detail::DoubleSignificandBits); + MOZ_ASSERT((significand & ~DoubleSignificandBits) == 0); + MOZ_ASSERT(significand & DoubleSignificandBits); - union detail::DoublePun pun; - pun.u = (signbit ? detail::DoubleSignBit : 0) | - detail::DoubleExponentBits | - significand; - MOZ_ASSERT(IsNaN(pun.d)); - return pun.d; + double d = BitwiseCast((signbit ? DoubleSignBit : 0) | + DoubleExponentBits | + significand); + MOZ_ASSERT(IsNaN(d)); + return d; } /** Computes the smallest non-zero positive double value. */ static MOZ_ALWAYS_INLINE double MinDoubleValue() { - union detail::DoublePun pun; - pun.u = 1; - return pun.d; + return BitwiseCast(uint64_t(1)); } static MOZ_ALWAYS_INLINE bool @@ -224,9 +190,22 @@ DoubleIsInt32(double d, int32_t* i) static MOZ_ALWAYS_INLINE double UnspecifiedNaN() { - return mozilla::SpecificNaN(0, 0xfffffffffffffULL); + return SpecificNaN(0, 0xfffffffffffffULL); +} + +/** + * Compare two doubles for equality, *without* equating -0 to +0, and equating + * any NaN value to any other NaN value. (The normal equality operators equate + * -0 with +0, and they equate NaN to no other value.) + */ +static inline bool +DoublesAreIdentical(double d1, double d2) +{ + if (IsNaN(d1)) + return IsNaN(d2); + return BitwiseCast(d1) == BitwiseCast(d2); } } /* namespace mozilla */ -#endif /* mozilla_FloatingPoint_h_ */ +#endif /* mozilla_FloatingPoint_h */ diff --git a/external/spidermonkey/include/win32/mozilla/GuardObjects.h b/external/spidermonkey/include/win32/mozilla/GuardObjects.h index 6c2058938c..aeae7dcbc0 100644 --- a/external/spidermonkey/include/win32/mozilla/GuardObjects.h +++ b/external/spidermonkey/include/win32/mozilla/GuardObjects.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -9,6 +10,7 @@ #define mozilla_GuardObjects_h #include "mozilla/Assertions.h" +#include "mozilla/NullPtr.h" #include "mozilla/Types.h" #ifdef __cplusplus @@ -72,7 +74,7 @@ class MOZ_EXPORT GuardObjectNotifier bool* statementDone; public: - GuardObjectNotifier() : statementDone(NULL) { } + GuardObjectNotifier() : statementDone(nullptr) { } ~GuardObjectNotifier() { *statementDone = true; diff --git a/external/spidermonkey/include/win32/mozilla/HashFunctions.h b/external/spidermonkey/include/win32/mozilla/HashFunctions.h index 96242b629a..6d0d24e7b1 100644 --- a/external/spidermonkey/include/win32/mozilla/HashFunctions.h +++ b/external/spidermonkey/include/win32/mozilla/HashFunctions.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Utilities for hashing. */ @@ -39,17 +40,18 @@ * }; * * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKey.h. + * in nsHashKeys.h. */ -#ifndef mozilla_HashFunctions_h_ -#define mozilla_HashFunctions_h_ +#ifndef mozilla_HashFunctions_h +#define mozilla_HashFunctions_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + #ifdef __cplusplus namespace mozilla { @@ -173,8 +175,8 @@ AddToHash(uint32_t hash, A* a) * catch data pointers and couldn't handle function pointers. */ - MOZ_STATIC_ASSERT(sizeof(a) == sizeof(uintptr_t), - "Strange pointer!"); + static_assert(sizeof(a) == sizeof(uintptr_t), + "Strange pointer!"); return detail::AddUintptrToHash(hash, uintptr_t(a)); } @@ -356,4 +358,5 @@ HashBytes(const void* bytes, size_t length); } /* namespace mozilla */ #endif /* __cplusplus */ -#endif /* mozilla_HashFunctions_h_ */ + +#endif /* mozilla_HashFunctions_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Likely.h b/external/spidermonkey/include/win32/mozilla/Likely.h index 6412b4943b..4f21609295 100644 --- a/external/spidermonkey/include/win32/mozilla/Likely.h +++ b/external/spidermonkey/include/win32/mozilla/Likely.h @@ -1,15 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a * boolean predicate should be branch-predicted. */ -#ifndef mozilla_Likely_h_ -#define mozilla_Likely_h_ +#ifndef mozilla_Likely_h +#define mozilla_Likely_h #if defined(__clang__) || defined(__GNUC__) # define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) @@ -19,4 +20,4 @@ # define MOZ_UNLIKELY(x) (!!(x)) #endif -#endif /* mozilla_Likely_h_ */ +#endif /* mozilla_Likely_h */ diff --git a/external/spidermonkey/include/win32/mozilla/LinkedList.h b/external/spidermonkey/include/win32/mozilla/LinkedList.h index 5cfd60e4ac..c29760b3e7 100644 --- a/external/spidermonkey/include/win32/mozilla/LinkedList.h +++ b/external/spidermonkey/include/win32/mozilla/LinkedList.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -45,18 +46,19 @@ * } * * void notifyObservers(char* topic) { - * for (Observer* o = list.getFirst(); o != NULL; o = o->getNext()) - * o->Observe(topic); + * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) + * o->observe(topic); * } * }; * */ -#ifndef mozilla_LinkedList_h_ -#define mozilla_LinkedList_h_ +#ifndef mozilla_LinkedList_h +#define mozilla_LinkedList_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #ifdef __cplusplus @@ -69,10 +71,10 @@ template class LinkedListElement { /* - * It's convenient that we return NULL when getNext() or getPrevious() hits - * the end of the list, but doing so costs an extra word of storage in each - * linked list node (to keep track of whether |this| is the sentinel node) - * and a branch on this value in getNext/getPrevious. + * It's convenient that we return nullptr when getNext() or getPrevious() + * hits the end of the list, but doing so costs an extra word of storage in + * each linked list node (to keep track of whether |this| is the sentinel + * node) and a branch on this value in getNext/getPrevious. * * We could get rid of the extra word of storage by shoving the "is * sentinel" bit into one of the pointers, although this would, of course, @@ -107,12 +109,10 @@ class LinkedListElement LinkedListElement* prev; const bool isSentinel; - LinkedListElement* thisDuringConstruction() { return this; } - public: LinkedListElement() - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(false) { } @@ -122,8 +122,8 @@ class LinkedListElement } /* - * Get the next element in the list, or NULL if this is the last element in - * the list. + * Get the next element in the list, or nullptr if this is the last element + * in the list. */ T* getNext() { return next->asT(); @@ -133,8 +133,8 @@ class LinkedListElement } /* - * Get the previous element in the list, or NULL if this is the first element - * in the list. + * Get the previous element in the list, or nullptr if this is the first + * element in the list. */ T* getPrevious() { return prev->asT(); @@ -201,24 +201,24 @@ class LinkedListElement }; LinkedListElement(NodeKind nodeKind) - : next(thisDuringConstruction()), - prev(thisDuringConstruction()), + : next(MOZ_THIS_IN_INITIALIZER_LIST()), + prev(MOZ_THIS_IN_INITIALIZER_LIST()), isSentinel(nodeKind == NODE_KIND_SENTINEL) { } /* - * Return |this| cast to T* if we're a normal node, or return NULL if we're - * a sentinel node. + * Return |this| cast to T* if we're a normal node, or return nullptr if + * we're a sentinel node. */ T* asT() { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } const T* asT() const { if (isSentinel) - return NULL; + return nullptr; return static_cast(this); } @@ -285,7 +285,7 @@ class LinkedList } /* - * Get the first element of the list, or NULL if the list is empty. + * Get the first element of the list, or nullptr if the list is empty. */ T* getFirst() { return sentinel.getNext(); @@ -295,7 +295,7 @@ class LinkedList } /* - * Get the last element of the list, or NULL if the list is empty. + * Get the last element of the list, or nullptr if the list is empty. */ T* getLast() { return sentinel.getPrevious(); @@ -306,7 +306,7 @@ class LinkedList /* * Get and remove the first element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popFirst() { T* ret = sentinel.getNext(); @@ -317,7 +317,7 @@ class LinkedList /* * Get and remove the last element of the list. If the list is empty, - * return NULL. + * return nullptr. */ T* popLast() { T* ret = sentinel.getPrevious(); @@ -415,7 +415,7 @@ class LinkedList if (elem == t) return; } - MOZ_NOT_REACHED("element wasn't found in this list!"); + MOZ_CRASH("element wasn't found in this list!"); #endif } @@ -425,5 +425,6 @@ class LinkedList } /* namespace mozilla */ -#endif /* ifdef __cplusplus */ -#endif /* ifdef mozilla_LinkedList_h_ */ +#endif /* __cplusplus */ + +#endif /* mozilla_LinkedList_h */ diff --git a/external/spidermonkey/include/win32/mozilla/MSStdInt.h b/external/spidermonkey/include/win32/mozilla/MSStdInt.h deleted file mode 100644 index 0447f2f11b..0000000000 --- a/external/spidermonkey/include/win32/mozilla/MSStdInt.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// 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. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/external/spidermonkey/include/win32/mozilla/MathAlgorithms.h b/external/spidermonkey/include/win32/mozilla/MathAlgorithms.h index 0a47810553..6d58691e06 100644 --- a/external/spidermonkey/include/win32/mozilla/MathAlgorithms.h +++ b/external/spidermonkey/include/win32/mozilla/MathAlgorithms.h @@ -1,19 +1,20 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt maths algorithms. */ -#ifndef mozilla_MathAlgorithms_h_ -#define mozilla_MathAlgorithms_h_ +#ifndef mozilla_MathAlgorithms_h +#define mozilla_MathAlgorithms_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/TypeTraits.h" #include #include +#include namespace mozilla { @@ -142,6 +143,288 @@ Abs(const long double d) return std::fabs(d); } +} // namespace mozilla + +#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define MOZ_BITSCAN_WINDOWS + + extern "C" { + unsigned char _BitScanForward(unsigned long* Index, unsigned long mask); + unsigned char _BitScanReverse(unsigned long* Index, unsigned long mask); +# pragma intrinsic(_BitScanForward, _BitScanReverse) + +# if defined(_M_AMD64) || defined(_M_X64) +# define MOZ_BITSCAN_WINDOWS64 + unsigned char _BitScanForward64(unsigned long* index, unsigned __int64 mask); + unsigned char _BitScanReverse64(unsigned long* index, unsigned __int64 mask); +# pragma intrinsic(_BitScanForward64, _BitScanReverse64) +# endif + } // extern "C" + +#endif + +namespace mozilla { + +namespace detail { + +#if defined(MOZ_BITSCAN_WINDOWS) + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanReverse(&index, static_cast(u)); + return uint_fast8_t(31 - index); + } + + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + unsigned long index; + _BitScanForward(&index, static_cast(u)); + return uint_fast8_t(index); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanReverse64(&index, static_cast(u)); + return uint_fast8_t(63 - index); +# else + uint32_t hi = uint32_t(u >> 32); + if (hi != 0) + return CountLeadingZeroes32(hi); + return 32 + CountLeadingZeroes32(uint32_t(u)); +# endif + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { +# if defined(MOZ_BITSCAN_WINDOWS64) + unsigned long index; + _BitScanForward64(&index, static_cast(u)); + return uint_fast8_t(index); +# else + uint32_t lo = uint32_t(u); + if (lo != 0) + return CountTrailingZeroes32(lo); + return 32 + CountTrailingZeroes32(uint32_t(u >> 32)); +# endif + } + +# ifdef MOZ_HAVE_BITSCAN64 +# undef MOZ_HAVE_BITSCAN64 +# endif + +#elif defined(__clang__) || defined(__GNUC__) + +# if defined(__clang__) +# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) +# error "A clang providing __builtin_c[lt]z is required to build" +# endif +# else + // gcc has had __builtin_clz and friends since 3.4: no need to check. +# endif + + inline uint_fast8_t + CountLeadingZeroes32(uint32_t u) + { + return __builtin_clz(u); + } + + inline uint_fast8_t + CountTrailingZeroes32(uint32_t u) + { + return __builtin_ctz(u); + } + + inline uint_fast8_t + CountLeadingZeroes64(uint64_t u) + { + return __builtin_clzll(u); + } + + inline uint_fast8_t + CountTrailingZeroes64(uint64_t u) + { + return __builtin_ctzll(u); + } + +#else +# error "Implement these!" + inline uint_fast8_t CountLeadingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountLeadingZeroes64(uint64_t u) MOZ_DELETE; + inline uint_fast8_t CountTrailingZeroes64(uint64_t u) MOZ_DELETE; +#endif + +} // namespace detail + +/** + * Compute the number of high-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the highest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountLeadingZeroes32(0xF0FF1000) is 0; + * CountLeadingZeroes32(0x7F8F0001) is 1; + * CountLeadingZeroes32(0x3FFF0100) is 2; + * CountLeadingZeroes32(0x1FF50010) is 3; and so on. + */ +inline uint_fast8_t +CountLeadingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes32(u); +} + +/** + * Compute the number of low-order zero bits in the NON-ZERO number |u|. That + * is, looking at the bitwise representation of the number, with the lowest- + * valued bits at the start, return the number of zeroes before the first one + * is observed. + * + * CountTrailingZeroes32(0x0100FFFF) is 0; + * CountTrailingZeroes32(0x7000FFFE) is 1; + * CountTrailingZeroes32(0x0080FFFC) is 2; + * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. + */ +inline uint_fast8_t +CountTrailingZeroes32(uint32_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes32(u); +} + +/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountLeadingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountLeadingZeroes64(u); +} + +/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ +inline uint_fast8_t +CountTrailingZeroes64(uint64_t u) +{ + MOZ_ASSERT(u != 0); + return detail::CountTrailingZeroes64(u); +} + +namespace detail { + +template +class CeilingLog2; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 32 - CountLeadingZeroes32(t - 1); + } +}; + +template +class CeilingLog2 +{ + public: + static uint_fast8_t compute(const T t) { + // Check for <= 1 to avoid the == 0 undefined case. + return t <= 1 ? 0 : 64 - CountLeadingZeroes64(t - 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the least power of 2 greater than or equal to |t|. + * + * CeilingLog2(0..1) is 0; + * CeilingLog2(2) is 1; + * CeilingLog2(3..4) is 2; + * CeilingLog2(5..8) is 3; + * CeilingLog2(9..16) is 4; and so on. + */ +template +inline uint_fast8_t +CeilingLog2(const T t) +{ + return detail::CeilingLog2::compute(t); +} + +/** A CeilingLog2 variant that accepts only size_t. */ +inline uint_fast8_t +CeilingLog2Size(size_t n) +{ + return CeilingLog2(n); +} + +namespace detail { + +template +class FloorLog2; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 31 - CountLeadingZeroes32(t | 1); + } +}; + +template +class FloorLog2 +{ + public: + static uint_fast8_t compute(const T t) { + return 63 - CountLeadingZeroes64(t | 1); + } +}; + +} // namespace detail + +/** + * Compute the log of the greatest power of 2 less than or equal to |t|. + * + * FloorLog2(0..1) is 0; + * FloorLog2(2..3) is 1; + * FloorLog2(4..7) is 2; + * FloorLog2(8..15) is 3; and so on. + */ +template +inline uint_fast8_t +FloorLog2(const T t) +{ + return detail::FloorLog2::compute(t); +} + +/** A FloorLog2 variant that accepts only size_t. */ +inline uint_fast8_t +FloorLog2Size(size_t n) +{ + return FloorLog2(n); +} + +/* + * Compute the smallest power of 2 greater than or equal to |x|. |x| must not + * be so great that the computed value would overflow |size_t|. + */ +inline size_t +RoundUpPow2(size_t x) +{ + MOZ_ASSERT(x <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), + "can't round up -- will overflow!"); + return size_t(1) << CeilingLog2(x); +} + } /* namespace mozilla */ -#endif /* mozilla_MathAlgorithms_h_ */ +#endif /* mozilla_MathAlgorithms_h */ diff --git a/external/spidermonkey/include/win32/mozilla/MemoryChecking.h b/external/spidermonkey/include/win32/mozilla/MemoryChecking.h index 3287e57ba1..2130990c6b 100644 --- a/external/spidermonkey/include/win32/mozilla/MemoryChecking.h +++ b/external/spidermonkey/include/win32/mozilla/MemoryChecking.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -19,8 +20,8 @@ * With no memory checker available, all macros expand to the empty statement. */ -#ifndef mozilla_MemoryChecking_h_ -#define mozilla_MemoryChecking_h_ +#ifndef mozilla_MemoryChecking_h +#define mozilla_MemoryChecking_h #if defined(MOZ_VALGRIND) #include "valgrind/memcheck.h" @@ -68,4 +69,4 @@ extern "C" { #endif -#endif /* mozilla_MemoryChecking_h_ */ +#endif /* mozilla_MemoryChecking_h */ diff --git a/external/spidermonkey/include/win32/mozilla/MemoryReporting.h b/external/spidermonkey/include/win32/mozilla/MemoryReporting.h new file mode 100644 index 0000000000..d2340ecf09 --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/MemoryReporting.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Memory reporting infrastructure. */ + +#ifndef mozilla_MemoryReporting_h +#define mozilla_MemoryReporting_h + +#include + +#ifdef __cplusplus + +namespace mozilla { + +/* + * This is for functions that are like malloc_usable_size. Such functions are + * used for measuring the size of data structures. + */ +typedef size_t (*MallocSizeOf)(const void* p); + +} /* namespace mozilla */ + +#endif /* __cplusplus */ + +typedef size_t (*MozMallocSizeOf)(const void* p); + +#endif /* mozilla_MemoryReporting_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Move.h b/external/spidermonkey/include/win32/mozilla/Move.h new file mode 100644 index 0000000000..97178daaa6 --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/Move.h @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* C++11-style, but C++98-usable, "move references" implementation. */ + +#ifndef mozilla_Move_h +#define mozilla_Move_h + +namespace mozilla { + +/* + * "Move" References + * + * Some types can be copied much more efficiently if we know the original's + * value need not be preserved --- that is, if we are doing a "move", not a + * "copy". For example, if we have: + * + * Vector u; + * Vector v(u); + * + * the constructor for v must apply a copy constructor to each element of u --- + * taking time linear in the length of u. However, if we know we will not need u + * any more once v has been initialized, then we could initialize v very + * efficiently simply by stealing u's dynamically allocated buffer and giving it + * to v --- a constant-time operation, regardless of the size of u. + * + * Moves often appear in container implementations. For example, when we append + * to a vector, we may need to resize its buffer. This entails moving each of + * its extant elements from the old, smaller buffer to the new, larger buffer. + * But once the elements have been migrated, we're just going to throw away the + * old buffer; we don't care if they still have their values. So if the vector's + * element type can implement "move" more efficiently than "copy", the vector + * resizing should by all means use a "move" operation. Hash tables also need to + * be resized. + * + * The details of the optimization, and whether it's worth applying, vary from + * one type to the next. And while some constructor calls are moves, many really + * are copies, and can't be optimized this way. So we need: + * + * 1) a way for a particular invocation of a copy constructor to say that it's + * really a move, and that the value of the original isn't important + * afterwards (although it must still be safe to destroy); and + * + * 2) a way for a type (like Vector) to announce that it can be moved more + * efficiently than it can be copied, and provide an implementation of that + * move operation. + * + * The Move(T&) function takes a reference to a T, and returns a MoveRef + * referring to the same value; that's 1). A MoveRef is simply a reference + * to a T, annotated to say that a copy constructor applied to it may move that + * T, instead of copying it. Finally, a constructor that accepts an MoveRef + * should perform a more efficient move, instead of a copy, providing 2). + * + * So, where we might define a copy constructor for a class C like this: + * + * C(const C& rhs) { ... copy rhs to this ... } + * + * we would declare a move constructor like this: + * + * C(MoveRef rhs) { ... move rhs to this ... } + * + * And where we might perform a copy like this: + * + * C c2(c1); + * + * we would perform a move like this: + * + * C c2(Move(c1)) + * + * Note that MoveRef implicitly converts to T&, so you can pass a MoveRef + * to an ordinary copy constructor for a type that doesn't support a special + * move constructor, and you'll just get a copy. This means that templates can + * use Move whenever they know they won't use the original value any more, even + * if they're not sure whether the type at hand has a specialized move + * constructor. If it doesn't, the MoveRef will just convert to a T&, and + * the ordinary copy constructor will apply. + * + * A class with a move constructor can also provide a move assignment operator, + * which runs this's destructor, and then applies the move constructor to + * *this's memory. A typical definition: + * + * C& operator=(MoveRef rhs) { + * this->~C(); + * new(this) C(rhs); + * return *this; + * } + * + * With that in place, one can write move assignments like this: + * + * c2 = Move(c1); + * + * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but + * destructible state. + * + * This header file defines MoveRef and Move in the mozilla namespace. It's up + * to individual containers to annotate moves as such, by calling Move; and it's + * up to individual types to define move constructors. + * + * One hint: if you're writing a move constructor where the type has members + * that should be moved themselves, it's much nicer to write this: + * + * C(MoveRef c) : x(Move(c->x)), y(Move(c->y)) { } + * + * than the equivalent: + * + * C(MoveRef c) { new(&x) X(Move(c->x)); new(&y) Y(Move(c->y)); } + * + * especially since GNU C++ fails to notice that this does indeed initialize x + * and y, which may matter if they're const. + */ +template +class MoveRef +{ + T* pointer; + + public: + explicit MoveRef(T& t) : pointer(&t) { } + T& operator*() const { return *pointer; } + T* operator->() const { return pointer; } + operator T& () const { return *pointer; } +}; + +template +inline MoveRef +Move(T& t) +{ + return MoveRef(t); +} + +template +inline MoveRef +Move(const T& t) +{ + // With some versions of gcc, for a class C, there's an (incorrect) ambiguity + // between the C(const C&) constructor and the default C(C&&) C++11 move + // constructor, when the constructor is called with a const C& argument. + // + // This ambiguity manifests with the Move implementation above when Move is + // passed const U& for some class U. Calling Move(const U&) returns a + // MoveRef, which is then commonly passed to the U constructor, + // triggering an implicit conversion to const U&. gcc doesn't know whether to + // call U(const U&) or U(U&&), so it wrongly reports a compile error. + // + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50442 has since been fixed, so + // this is no longer an issue for up-to-date compilers. But there's no harm + // in keeping it around for older compilers, so we might as well. See also + // bug 686280. + return MoveRef(const_cast(t)); +} + +/** Swap |t| and |u| using move-construction if possible. */ +template +inline void +Swap(T& t, T& u) +{ + T tmp(Move(t)); + t = Move(u); + u = Move(tmp); +} + +} // namespace mozilla + +#endif /* mozilla_Move_h */ diff --git a/external/spidermonkey/include/win32/mozilla/NullPtr.h b/external/spidermonkey/include/win32/mozilla/NullPtr.h index 7dcb03d734..14c0f07df2 100644 --- a/external/spidermonkey/include/win32/mozilla/NullPtr.h +++ b/external/spidermonkey/include/win32/mozilla/NullPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * constant. */ -#ifndef mozilla_NullPtr_h_ -#define mozilla_NullPtr_h_ +#ifndef mozilla_NullPtr_h +#define mozilla_NullPtr_h #include "mozilla/Compiler.h" @@ -45,4 +46,4 @@ # endif #endif -#endif /* mozilla_NullPtr_h_ */ +#endif /* mozilla_NullPtr_h */ diff --git a/external/spidermonkey/include/win32/mozilla/PodOperations.h b/external/spidermonkey/include/win32/mozilla/PodOperations.h index 6c6af27fc9..bec89fa928 100644 --- a/external/spidermonkey/include/win32/mozilla/PodOperations.h +++ b/external/spidermonkey/include/win32/mozilla/PodOperations.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -156,4 +157,4 @@ PodEqual(const T* one, const T* two, size_t len) } // namespace mozilla -#endif // mozilla_PodOperations_h_ +#endif /* mozilla_PodOperations_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Poison.h b/external/spidermonkey/include/win32/mozilla/Poison.h index c4adc23e71..75e0f081cd 100644 --- a/external/spidermonkey/include/win32/mozilla/Poison.h +++ b/external/spidermonkey/include/win32/mozilla/Poison.h @@ -9,13 +9,14 @@ * an address that leads to a safe crash when dereferenced. */ -#ifndef mozilla_Poison_h_ -#define mozilla_Poison_h_ +#ifndef mozilla_Poison_h +#define mozilla_Poison_h #include "mozilla/Assertions.h" -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" +#include + MOZ_BEGIN_EXTERN_C extern MFBT_DATA uintptr_t gMozillaPoisonValue; @@ -36,11 +37,11 @@ inline uintptr_t mozPoisonValue() */ inline void mozWritePoison(void* aPtr, size_t aSize) { - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); const uintptr_t POISON = mozPoisonValue(); char* p = (char*)aPtr; char* limit = p + aSize; + MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); + MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); for (; p < limit; p += sizeof(uintptr_t)) { *((uintptr_t*)p) = POISON; } @@ -58,4 +59,4 @@ extern MFBT_DATA uintptr_t gMozillaPoisonSize; MOZ_END_EXTERN_C -#endif /* mozilla_Poison_h_ */ +#endif /* mozilla_Poison_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Range.h b/external/spidermonkey/include/win32/mozilla/Range.h index e14594d09d..4e02d962b5 100644 --- a/external/spidermonkey/include/win32/mozilla/Range.h +++ b/external/spidermonkey/include/win32/mozilla/Range.h @@ -1,12 +1,11 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef mozilla_Range_h_ -#define mozilla_Range_h_ +#ifndef mozilla_Range_h +#define mozilla_Range_h #include "mozilla/NullPtr.h" #include "mozilla/RangedPtr.h" @@ -40,10 +39,13 @@ class Range return mStart[offset]; } + const T& operator[](size_t offset) const { + return mStart[offset]; + } + operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; } }; } // namespace mozilla -#endif // mozilla_Range_h_ - +#endif /* mozilla_Range_h */ diff --git a/external/spidermonkey/include/win32/mozilla/RangedPtr.h b/external/spidermonkey/include/win32/mozilla/RangedPtr.h index 7ce19d071f..493fcdbaee 100644 --- a/external/spidermonkey/include/win32/mozilla/RangedPtr.h +++ b/external/spidermonkey/include/win32/mozilla/RangedPtr.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,11 +9,12 @@ * construction. */ -#ifndef mozilla_RangedPtr_h_ -#define mozilla_RangedPtr_h_ +#ifndef mozilla_RangedPtr_h +#define mozilla_RangedPtr_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" #include "mozilla/Util.h" namespace mozilla { @@ -59,7 +61,7 @@ class RangedPtr #ifdef DEBUG return RangedPtr(p, rangeStart, rangeEnd); #else - return RangedPtr(p, NULL, size_t(0)); + return RangedPtr(p, nullptr, size_t(0)); #endif } @@ -251,4 +253,4 @@ class RangedPtr } /* namespace mozilla */ -#endif /* mozilla_RangedPtr_h_ */ +#endif /* mozilla_RangedPtr_h */ diff --git a/external/spidermonkey/include/win32/mozilla/ReentrancyGuard.h b/external/spidermonkey/include/win32/mozilla/ReentrancyGuard.h new file mode 100644 index 0000000000..d589f368a2 --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/ReentrancyGuard.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Small helper class for asserting uses of a class are non-reentrant. */ + +#ifndef mozilla_ReentrancyGuard_h +#define mozilla_ReentrancyGuard_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/GuardObjects.h" + +namespace mozilla { + +/* Useful for implementing containers that assert non-reentrancy */ +class ReentrancyGuard +{ + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER +#ifdef DEBUG + bool& entered; +#endif + + public: + template +#ifdef DEBUG + ReentrancyGuard(T& obj + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : entered(obj.entered) +#else + ReentrancyGuard(T& + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) +#endif + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; +#ifdef DEBUG + MOZ_ASSERT(!entered); + entered = true; +#endif + } + ~ReentrancyGuard() + { +#ifdef DEBUG + entered = false; +#endif + } + + private: + ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE; + void operator=(const ReentrancyGuard&) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_ReentrancyGuard_h */ diff --git a/external/spidermonkey/include/win32/mozilla/RefPtr.h b/external/spidermonkey/include/win32/mozilla/RefPtr.h index 9f4163a21a..3c275afdc7 100644 --- a/external/spidermonkey/include/win32/mozilla/RefPtr.h +++ b/external/spidermonkey/include/win32/mozilla/RefPtr.h @@ -1,14 +1,16 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Helpers for defining and using refcounted objects. */ -#ifndef mozilla_RefPtr_h_ -#define mozilla_RefPtr_h_ +#ifndef mozilla_RefPtr_h +#define mozilla_RefPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/TypeTraits.h" @@ -41,13 +43,19 @@ template OutParamRef byRef(RefPtr&); * state distinguishes use-before-ref (refcount==0) from * use-after-destroy (refcount==0xffffdead). */ -#ifdef DEBUG namespace detail { +#ifdef DEBUG static const int DEAD = 0xffffdead; -} #endif -template +// This is used WeakPtr.h as well as this file. +enum RefCountAtomicity +{ + AtomicRefCount, + NonAtomicRefCount +}; + +template class RefCounted { friend class RefPtr; @@ -56,8 +64,6 @@ class RefCounted RefCounted() : refCnt(0) { } ~RefCounted() { MOZ_ASSERT(refCnt == detail::DEAD); - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from RefCounted"); } public: @@ -87,7 +93,33 @@ class RefCounted } private: - int refCnt; + typename Conditional, int>::Type refCnt; +}; + +} + +template +class RefCounted : public detail::RefCounted +{ + public: + ~RefCounted() { + static_assert(IsBaseOf::value, + "T must derive from RefCounted"); + } +}; + +/** + * AtomicRefCounted is like RefCounted, with an atomically updated + * reference counter. + */ +template +class AtomicRefCounted : public detail::RefCounted +{ + public: + ~AtomicRefCounted() { + static_assert(IsBaseOf::value, + "T must derive from AtomicRefCounted"); + } }; /** @@ -259,9 +291,6 @@ byRef(RefPtr& ptr) } // namespace mozilla -#endif // mozilla_RefPtr_h_ - - #if 0 // Command line that builds these tests @@ -416,3 +445,5 @@ main(int argc, char** argv) } #endif + +#endif /* mozilla_RefPtr_h */ diff --git a/external/spidermonkey/include/win32/mozilla/SHA1.h b/external/spidermonkey/include/win32/mozilla/SHA1.h index a6604e699f..b167648540 100644 --- a/external/spidermonkey/include/win32/mozilla/SHA1.h +++ b/external/spidermonkey/include/win32/mozilla/SHA1.h @@ -1,17 +1,18 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Simple class for computing SHA1. */ -#ifndef mozilla_SHA1_h_ -#define mozilla_SHA1_h_ +#ifndef mozilla_SHA1_h +#define mozilla_SHA1_h -#include "mozilla/StandardInteger.h" #include "mozilla/Types.h" #include +#include namespace mozilla { @@ -58,4 +59,4 @@ class SHA1Sum } /* namespace mozilla */ -#endif /* mozilla_SHA1_h_ */ +#endif /* mozilla_SHA1_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Scoped.h b/external/spidermonkey/include/win32/mozilla/Scoped.h index 677a1a3797..fc48584b3e 100644 --- a/external/spidermonkey/include/win32/mozilla/Scoped.h +++ b/external/spidermonkey/include/win32/mozilla/Scoped.h @@ -1,11 +1,13 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* A number of structures to simplify scope-based RAII management. */ -#ifndef mozilla_Scoped_h_ -#define mozilla_Scoped_h_ +#ifndef mozilla_Scoped_h +#define mozilla_Scoped_h /* * Resource Acquisition Is Initialization is a programming idiom used @@ -52,6 +54,7 @@ #include "mozilla/Attributes.h" #include "mozilla/GuardObjects.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -193,7 +196,7 @@ template struct ScopedFreePtrTraits { typedef T* type; - static T* empty() { return NULL; } + static T* empty() { return nullptr; } static void release(T* ptr) { free(ptr); } }; SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits) @@ -256,7 +259,7 @@ template struct TypeSpecificScopedPointerTraits { typedef T* type; - const static type empty() { return NULL; } + const static type empty() { return nullptr; } const static void release(type value) { if (value) @@ -268,4 +271,4 @@ SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) } /* namespace mozilla */ -#endif // mozilla_Scoped_h_ +#endif /* mozilla_Scoped_h */ diff --git a/external/spidermonkey/include/win32/mozilla/SplayTree.h b/external/spidermonkey/include/win32/mozilla/SplayTree.h index f9a10d36dd..de0235aec9 100644 --- a/external/spidermonkey/include/win32/mozilla/SplayTree.h +++ b/external/spidermonkey/include/win32/mozilla/SplayTree.h @@ -1,7 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -10,8 +9,8 @@ * are faster to access again. */ -#ifndef mozilla_SplayTree_h_ -#define mozilla_SplayTree_h_ +#ifndef mozilla_SplayTree_h +#define mozilla_SplayTree_h #include "mozilla/Assertions.h" #include "mozilla/NullPtr.h" @@ -282,4 +281,4 @@ class SplayTree } /* namespace mozilla */ -#endif /* mozilla_SplayTree_h_ */ +#endif /* mozilla_SplayTree_h */ diff --git a/external/spidermonkey/include/win32/mozilla/StandardInteger.h b/external/spidermonkey/include/win32/mozilla/StandardInteger.h deleted file mode 100644 index 8e4c8578f1..0000000000 --- a/external/spidermonkey/include/win32/mozilla/StandardInteger.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implements the C99 interface for C and C++ code. */ - -#ifndef mozilla_StandardInteger_h_ -#define mozilla_StandardInteger_h_ - -/* - * The C99 standard header exposes typedefs for common fixed-width - * integer types. It would be feasible to simply #include , but - * MSVC++ versions prior to 2010 don't provide . We could solve this - * by reimplementing for MSVC++ 2008 and earlier. But then we reach - * a second problem: our custom might conflict with a - * defined by an embedder already looking to work around the MSVC++ - * absence. - * - * We address these issues in this manner: - * - * 1. If the preprocessor macro MOZ_CUSTOM_STDINT_H is defined to a path to a - * custom implementation, we will #include it. Embedders using - * a custom must define this macro to an implementation that - * will work with their embedding. - * 2. Otherwise, if we are compiling with a an MSVC++ version without - * , #include our custom reimplementation. - * 3. Otherwise, #include the standard provided by the compiler. - * - * Note that we can't call this file "stdint.h" or something case-insensitively - * equal to "stdint.h" because then MSVC (and other compilers on - * case-insensitive file systems) will include this file, rather than the system - * stdint.h, when we ask for below. - */ -#if defined(MOZ_CUSTOM_STDINT_H) -# include MOZ_CUSTOM_STDINT_H -#elif defined(_MSC_VER) && _MSC_VER < 1600 -# include "mozilla/MSStdInt.h" -#else -# include -#endif - -#endif /* mozilla_StandardInteger_h_ */ diff --git a/external/spidermonkey/include/win32/mozilla/TemplateLib.h b/external/spidermonkey/include/win32/mozilla/TemplateLib.h new file mode 100644 index 0000000000..50275fdadb --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/TemplateLib.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Reusable template meta-functions on types and compile-time values. Meta- + * functions are placed inside the 'tl' namespace to avoid conflict with non- + * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. + * mozilla::FloorLog2). + * + * When constexpr support becomes universal, we should probably use that instead + * of some of these templates, for simplicity. + */ + +#ifndef mozilla_TemplateLib_h +#define mozilla_TemplateLib_h + +#include +#include + +namespace mozilla { + +namespace tl { + +/** Compute min/max. */ +template +struct Min +{ + static const size_t value = I < J ? I : J; +}; +template +struct Max +{ + static const size_t value = I > J ? I : J; +}; + +/** Compute floor(log2(i)). */ +template +struct FloorLog2 +{ + static const size_t value = 1 + FloorLog2::value; +}; +template<> struct FloorLog2<0> { /* Error */ }; +template<> struct FloorLog2<1> { static const size_t value = 0; }; + +/** Compute ceiling(log2(i)). */ +template +struct CeilingLog2 +{ + static const size_t value = FloorLog2<2 * I - 1>::value; +}; + +/** Round up to the nearest power of 2. */ +template +struct RoundUpPow2 +{ + static const size_t value = size_t(1) << CeilingLog2::value; +}; +template<> +struct RoundUpPow2<0> +{ + static const size_t value = 1; +}; + +/** Compute the number of bits in the given unsigned type. */ +template +struct BitSize +{ + static const size_t value = sizeof(T) * CHAR_BIT; +}; + +/** + * Produce an N-bit mask, where N <= BitSize::value. Handle the + * language-undefined edge case when N = BitSize::value. + */ +template +struct NBitMask +{ + // Assert the precondition. On success this evaluates to 0. Otherwise it + // triggers divide-by-zero at compile time: a guaranteed compile error in + // C++11, and usually one in C++98. Add this value to |value| to assure + // its computation. + static const size_t checkPrecondition = 0 / size_t(N < BitSize::value); + static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; +}; +template<> +struct NBitMask::value> +{ + static const size_t value = size_t(-1); +}; + +/** + * For the unsigned integral type size_t, compute a mask M for N such that + * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) + */ +template +struct MulOverflowMask +{ + static const size_t value = + ~NBitMask::value - CeilingLog2::value>::value; +}; +template<> struct MulOverflowMask<0> { /* Error */ }; +template<> struct MulOverflowMask<1> { static const size_t value = 0; }; + +} // namespace tl + +} // namespace mozilla + +#endif /* mozilla_TemplateLib_h */ diff --git a/external/spidermonkey/include/win32/mozilla/ThreadLocal.h b/external/spidermonkey/include/win32/mozilla/ThreadLocal.h index 2b4eb30207..6df109821f 100644 --- a/external/spidermonkey/include/win32/mozilla/ThreadLocal.h +++ b/external/spidermonkey/include/win32/mozilla/ThreadLocal.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Cross-platform lightweight thread local data wrappers. */ -#ifndef mozilla_ThreadLocal_h_ -#define mozilla_ThreadLocal_h_ +#ifndef mozilla_ThreadLocal_h +#define mozilla_ThreadLocal_h #if defined(XP_WIN) // This file will get included in any file that wants to add a profiler mark. @@ -28,6 +29,7 @@ __declspec(dllimport) unsigned long __stdcall TlsAlloc(); #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/NullPtr.h" namespace mozilla { @@ -98,15 +100,15 @@ template inline bool ThreadLocal::init() { - MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); + static_assert(sizeof(T) <= sizeof(void*), + "mozilla::ThreadLocal can't be used for types larger than " + "a pointer"); MOZ_ASSERT(!initialized()); #ifdef XP_WIN key = TlsAlloc(); inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES #else - inited = !pthread_key_create(&key, NULL); + inited = !pthread_key_create(&key, nullptr); #endif return inited; } @@ -144,4 +146,4 @@ ThreadLocal::set(const T value) } // namespace mozilla -#endif // mozilla_ThreadLocal_h_ +#endif /* mozilla_ThreadLocal_h */ diff --git a/external/spidermonkey/include/win32/mozilla/TypeTraits.h b/external/spidermonkey/include/win32/mozilla/TypeTraits.h index 656bc775f8..53c0b5c2f6 100644 --- a/external/spidermonkey/include/win32/mozilla/TypeTraits.h +++ b/external/spidermonkey/include/win32/mozilla/TypeTraits.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Template-based metaprogramming and type-testing facilities. */ -#ifndef mozilla_TypeTraits_h_ -#define mozilla_TypeTraits_h_ +#ifndef mozilla_TypeTraits_h +#define mozilla_TypeTraits_h /* * These traits are approximate copies of the traits and semantics from C++11's @@ -126,6 +127,28 @@ struct IsPointer : FalseType {}; template struct IsPointer : TrueType {}; +namespace detail { + +// __is_enum is a supported extension across all of our supported compilers. +template +struct IsEnumHelper + : IntegralConstant +{}; + +} // namespace detail + +/** + * IsEnum determines whether a type is an enum type. + * + * mozilla::IsEnum::value is true; + * mozilla::IsEnum::value is false; + * mozilla::IsEnum::value is false; + */ +template +struct IsEnum + : detail::IsEnumHelper::Type> +{}; + /* 20.9.4.2 Composite type traits [meta.unary.comp] */ /** @@ -197,8 +220,24 @@ template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; template struct IsPod : TrueType {}; +namespace detail { + +template::value> +struct IsSignedHelper; + +template +struct IsSignedHelper : TrueType {}; + +template +struct IsSignedHelper + : IntegralConstant::value && T(-1) < T(1)> +{}; + +} // namespace detail + /** - * IsSigned determines whether a type is a signed arithmetic type. + * IsSigned determines whether a type is a signed arithmetic type. |char| is + * considered a signed type if it has the same representation as |signed char|. * * Don't use this if the type might be user-defined! You might or might not get * a compile error, depending. @@ -209,10 +248,26 @@ template struct IsPod : TrueType {}; * mozilla::IsSigned::value is true. */ template -struct IsSigned - : IntegralConstant::value && T(-1) < T(0)> +struct IsSigned : detail::IsSignedHelper {}; + +namespace detail { + +template::value> +struct IsUnsignedHelper; + +template +struct IsUnsignedHelper : FalseType {}; + +template +struct IsUnsignedHelper + : IntegralConstant::value && + (IsSame::Type, bool>::value || + T(1) < T(-1))> {}; +} // namespace detail + /** * IsUnsigned determines whether a type is an unsigned arithmetic type. * @@ -225,9 +280,7 @@ struct IsSigned * mozilla::IsUnsigned::value is false. */ template -struct IsUnsigned - : IntegralConstant::value && T(0) < T(-1)> -{}; +struct IsUnsigned : detail::IsUnsignedHelper {}; /* 20.9.5 Type property queries [meta.unary.prop.query] */ @@ -427,6 +480,160 @@ struct RemoveCV /* 20.9.7.3 Sign modifications [meta.trans.sign] */ +template +struct EnableIf; + +template +struct Conditional; + +namespace detail { + +template +struct WithC : Conditional +{}; + +template +struct WithV : Conditional +{}; + + +template +struct WithCV : WithC::Type> +{}; + +template +struct CorrespondingSigned; + +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef signed char Type; }; +template<> +struct CorrespondingSigned { typedef short Type; }; +template<> +struct CorrespondingSigned { typedef int Type; }; +template<> +struct CorrespondingSigned { typedef long Type; }; +template<> +struct CorrespondingSigned { typedef long long Type; }; + +template::Type, + bool IsSignedIntegerType = IsSigned::value && + !IsSame::value> +struct MakeSigned; + +template +struct MakeSigned +{ + typedef T Type; +}; + +template +struct MakeSigned + : WithCV::value, IsVolatile::value, + typename CorrespondingSigned::Type> +{}; + +} // namespace detail + +/** + * MakeSigned produces the corresponding signed integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already a signed integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an unsigned integer type, the signed variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the integral type of the same size as T, with the lowest rank, + * with T's const/volatile qualifiers, is produced. (This basically only acts + * to produce signed char when T = char.) + * + * mozilla::MakeSigned::Type is signed long; + * mozilla::MakeSigned::Type is volatile int; + * mozilla::MakeSigned::Type is const signed short; + * mozilla::MakeSigned::Type is const signed char; + * mozilla::MakeSigned is an error; + * mozilla::MakeSigned is an error. + */ +template +struct MakeSigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeSigned + >::Type +{}; + +namespace detail { + +template +struct CorrespondingUnsigned; + +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned char Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned short Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned int Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long Type; }; +template<> +struct CorrespondingUnsigned { typedef unsigned long long Type; }; + + +template::Type, + bool IsUnsignedIntegerType = IsUnsigned::value && + !IsSame::value> +struct MakeUnsigned; + +template +struct MakeUnsigned +{ + typedef T Type; +}; + +template +struct MakeUnsigned + : WithCV::value, IsVolatile::value, + typename CorrespondingUnsigned::Type> +{}; + +} // namespace detail + +/** + * MakeUnsigned produces the corresponding unsigned integer type for a given + * integral type T, with the const/volatile qualifiers of T. T must be a + * possibly-const/volatile-qualified integral type that isn't bool. + * + * If T is already an unsigned integer type (not including char!), then T is + * produced. + * + * Otherwise, if T is an signed integer type, the unsigned variety of T, with + * T's const/volatile qualifiers, is produced. + * + * Otherwise, the unsigned integral type of the same size as T, with the lowest + * rank, with T's const/volatile qualifiers, is produced. (This basically only + * acts to produce unsigned char when T = char.) + * + * mozilla::MakeUnsigned::Type is unsigned long; + * mozilla::MakeUnsigned::Type is volatile unsigned int; + * mozilla::MakeUnsigned::Type is const unsigned short; + * mozilla::MakeUnsigned::Type is const unsigned char; + * mozilla::MakeUnsigned is an error; + * mozilla::MakeUnsigned is an error. + */ +template +struct MakeUnsigned + : EnableIf::value && !IsSame::Type>::value, + typename detail::MakeUnsigned + >::Type +{}; + /* 20.9.7.4 Array modifications [meta.trans.arr] */ /* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ @@ -451,7 +658,7 @@ struct RemoveCV * ... * }; */ -template +template struct EnableIf {}; @@ -481,4 +688,4 @@ struct Conditional } /* namespace mozilla */ -#endif /* mozilla_TypeTraits_h_ */ +#endif /* mozilla_TypeTraits_h */ diff --git a/external/spidermonkey/include/win32/mozilla/TypedEnum.h b/external/spidermonkey/include/win32/mozilla/TypedEnum.h index 889960a32d..6f595cb4c5 100644 --- a/external/spidermonkey/include/win32/mozilla/TypedEnum.h +++ b/external/spidermonkey/include/win32/mozilla/TypedEnum.h @@ -1,12 +1,13 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Macros to emulate C++11 typed enums and enum classes. */ -#ifndef mozilla_TypedEnum_h_ -#define mozilla_TypedEnum_h_ +#ifndef mozilla_TypedEnum_h +#define mozilla_TypedEnum_h #include "mozilla/Attributes.h" @@ -91,16 +92,33 @@ * mandatory. As with MOZ_ENUM_TYPE(), it will do nothing on compilers that do * not support it. * - * Note that the workaround implemented here is not compatible with enums - * nested inside a class. + * MOZ_{BEGIN,END}_ENUM_CLASS doesn't work for defining enum classes nested + * inside classes. To define an enum class nested inside another class, use + * MOZ_{BEGIN,END}_NESTED_ENUM_CLASS, and place a MOZ_FINISH_NESTED_ENUM_CLASS + * in namespace scope to handle bits that can only be implemented with + * namespace-scoped code. For example: + * + * class FooBar { + * + * MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t) + * A, + * B = 6 + * MOZ_END_NESTED_ENUM_CLASS(Enum) + * + * }; + * + * MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum) */ #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) /* * All compilers that support strong enums also support an explicit * underlying type, so no extra check is needed. */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) enum class Name : type { -# define MOZ_END_ENUM_CLASS(Name) }; +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ + enum class Name : type { +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) /* nothing */ #else /** * We need Name to both name a type, and scope the provided enumerator @@ -136,14 +154,14 @@ * { * return Enum::A; * } - */ -# define MOZ_BEGIN_ENUM_CLASS(Name, type) \ + */\ +# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ class Name \ { \ public: \ enum Enum MOZ_ENUM_TYPE(type) \ { -# define MOZ_END_ENUM_CLASS(Name) \ +# define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; \ Name() {} \ Name(Enum aEnum) : mEnum(aEnum) {} \ @@ -151,7 +169,8 @@ operator Enum() const { return mEnum; } \ private: \ Enum mEnum; \ - }; \ + }; +# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) \ inline int operator+(const int&, const Name::Enum&) MOZ_DELETE; \ inline int operator+(const Name::Enum&, const int&) MOZ_DELETE; \ inline int operator-(const int&, const Name::Enum&) MOZ_DELETE; \ @@ -207,7 +226,11 @@ inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \ inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE; #endif +# define MOZ_BEGIN_ENUM_CLASS(Name, type) MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) +# define MOZ_END_ENUM_CLASS(Name) \ + MOZ_END_NESTED_ENUM_CLASS(Name) \ + MOZ_FINISH_NESTED_ENUM_CLASS(Name) #endif /* __cplusplus */ -#endif /* mozilla_TypedEnum_h_ */ +#endif /* mozilla_TypedEnum_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Types.h b/external/spidermonkey/include/win32/mozilla/Types.h index 56e5cb82fb..5340b2b600 100644 --- a/external/spidermonkey/include/win32/mozilla/Types.h +++ b/external/spidermonkey/include/win32/mozilla/Types.h @@ -1,28 +1,22 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt foundational types and macros. */ -#ifndef mozilla_Types_h_ -#define mozilla_Types_h_ +#ifndef mozilla_Types_h +#define mozilla_Types_h /* * This header must be valid C and C++, includable by code embedding either * SpiderMonkey or Gecko. */ -/* - * Expose all the integer types defined in C99's (and the integer - * limit and constant macros, if compiling C code or if compiling C++ code and - * the right __STDC_*_MACRO has been defined for each). These are all usable - * throughout mfbt code, and throughout Mozilla code more generally. - */ -#include "mozilla/StandardInteger.h" - -/* Also expose size_t. */ +/* Expose all types and size_t. */ #include +#include /* Implement compiler and linker macros needed for APIs. */ @@ -133,4 +127,12 @@ # define MOZ_END_EXTERN_C #endif -#endif /* mozilla_Types_h_ */ +/* + * GCC's typeof is available when decltype is not. + */ +#if defined(__GNUC__) && defined(__cplusplus) && \ + !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +# define decltype __typeof__ +#endif + +#endif /* mozilla_Types_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Util.h b/external/spidermonkey/include/win32/mozilla/Util.h index 097c5478eb..4f1c634a59 100644 --- a/external/spidermonkey/include/win32/mozilla/Util.h +++ b/external/spidermonkey/include/win32/mozilla/Util.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,8 +9,8 @@ * new headers, or to other appropriate existing headers, not here. */ -#ifndef mozilla_Util_h_ -#define mozilla_Util_h_ +#ifndef mozilla_Util_h +#define mozilla_Util_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" @@ -196,6 +197,58 @@ class Maybe constructed = true; } + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); + constructed = true; + } + T* addr() { MOZ_ASSERT(constructed); return &asT(); @@ -271,7 +324,7 @@ ArrayEnd(T (&arr)[N]) /* * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for MOZ_STATIC_ASSERT() calls that + * that can't use C++ template functions and for static_assert() calls that * can't call ArrayLength() when it is not a C++11 constexpr function. */ #ifdef MOZ_HAVE_CXX11_CONSTEXPR @@ -280,4 +333,4 @@ ArrayEnd(T (&arr)[N]) # define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) #endif -#endif /* mozilla_Util_h_ */ +#endif /* mozilla_Util_h */ diff --git a/external/spidermonkey/include/win32/mozilla/Vector.h b/external/spidermonkey/include/win32/mozilla/Vector.h new file mode 100644 index 0000000000..8759df8c06 --- /dev/null +++ b/external/spidermonkey/include/win32/mozilla/Vector.h @@ -0,0 +1,1190 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A type/length-parametrized vector class. */ + +#ifndef mozilla_Vector_h +#define mozilla_Vector_h + +#include "mozilla/AllocPolicy.h" +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Move.h" +#include "mozilla/NullPtr.h" +#include "mozilla/ReentrancyGuard.h" +#include "mozilla/TemplateLib.h" +#include "mozilla/TypeTraits.h" +#include "mozilla/Util.h" + +#include // for placement new + +/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4345) +#endif + +namespace mozilla { + +template +class VectorBase; + +namespace detail { + +/* + * Check that the given capacity wastes the minimal amount of space if + * allocated on the heap. This means that cap*sizeof(T) is as close to a + * power-of-two as possible. growStorageBy() is responsible for ensuring + * this. + */ +template +static bool CapacityHasExcessSpace(size_t cap) +{ + size_t size = cap * sizeof(T); + return RoundUpPow2(size) - size >= sizeof(T); +} + +/* + * This template class provides a default implementation for vector operations + * when the element type is not known to be a POD, as judged by IsPod. + */ +template +struct VectorImpl +{ + /* Destroys constructed objects in the range [begin, end). */ + static inline void destroy(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + p->~T(); + } + + /* Constructs objects in the uninitialized range [begin, end). */ + static inline void initialize(T* begin, T* end) { + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + /* + * Copy-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(*p); + } + + /* + * Move-constructs objects in the uninitialized range + * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). + */ + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + new(dst) T(Move(*p)); + } + + /* + * Copy-constructs objects in the uninitialized range [dst, dst+n) from the + * same object u. + */ + template + static inline void copyConstructN(T* dst, size_t n, const U& u) { + for (T* end = dst + n; dst < end; ++dst) + new(dst) T(u); + } + + /* + * Grows the given buffer to have capacity newCap, preserving the objects + * constructed in the range [begin, end) and updating v. Assumes that (1) + * newCap has not overflowed, and (2) multiplying newCap by sizeof(T) will + * not overflow. + */ + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + T* newbuf = reinterpret_cast(v.malloc_(newCap * sizeof(T))); + if (!newbuf) + return false; + T* dst = newbuf; + T* src = v.beginNoCheck(); + for (; src < v.endNoCheck(); ++dst, ++src) + new(dst) T(Move(*src)); + VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); + v.free_(v.mBegin); + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +/* + * This partial template specialization provides a default implementation for + * vector operations when the element type is known to be a POD, as judged by + * IsPod. + */ +template +struct VectorImpl +{ + static inline void destroy(T*, T*) {} + + static inline void initialize(T* begin, T* end) { + /* + * You would think that memset would be a big win (or even break even) + * when we know T is a POD. But currently it's not. This is probably + * because |append| tends to be given small ranges and memset requires + * a function call that doesn't get inlined. + * + * memset(begin, 0, sizeof(T) * (end-begin)); + */ + for (T* p = begin; p < end; ++p) + new(p) T(); + } + + template + static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) { + /* + * See above memset comment. Also, notice that copyConstruct is + * currently templated (T != U), so memcpy won't work without + * requiring T == U. + * + * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); + */ + for (const U* p = srcbeg; p < srcend; ++p, ++dst) + *dst = *p; + } + + template + static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { + copyConstruct(dst, srcbeg, srcend); + } + + static inline void copyConstructN(T* dst, size_t n, const T& t) { + for (T* end = dst + n; dst < end; ++dst) + *dst = t; + } + + static inline bool + growTo(VectorBase& v, size_t newCap) { + MOZ_ASSERT(!v.usingInlineStorage()); + MOZ_ASSERT(!CapacityHasExcessSpace(newCap)); + size_t oldSize = sizeof(T) * v.mCapacity; + size_t newSize = sizeof(T) * newCap; + T* newbuf = reinterpret_cast(v.realloc_(v.mBegin, oldSize, newSize)); + if (!newbuf) + return false; + v.mBegin = newbuf; + /* v.mLength is unchanged. */ + v.mCapacity = newCap; + return true; + } +}; + +} // namespace detail + +/* + * A CRTP base class for vector-like classes. Unless you really really want + * your own vector class -- and you almost certainly don't -- you should use + * mozilla::Vector instead! + * + * See mozilla::Vector for interface requirements. + */ +template +class VectorBase : private AllocPolicy +{ + /* utilities */ + + static const bool sElemIsPod = IsPod::value; + typedef detail::VectorImpl Impl; + friend struct detail::VectorImpl; + + bool growStorageBy(size_t incr); + bool convertToHeapStorage(size_t newCap); + + /* magic constants */ + + static const int sMaxInlineBytes = 1024; + + /* compute constants */ + + /* + * Consider element size to be 1 for buffer sizing if there are 0 inline + * elements. This allows us to compile when the definition of the element + * type is not visible here. + * + * Explicit specialization is only allowed at namespace scope, so in order + * to keep everything here, we use a dummy template parameter with partial + * specialization. + */ + template + struct ElemSize + { + static const size_t value = sizeof(T); + }; + template + struct ElemSize<0, Dummy> + { + static const size_t value = 1; + }; + + static const size_t sInlineCapacity = + tl::Min::value>::value; + + /* Calculate inline buffer size; avoid 0-sized array. */ + static const size_t sInlineBytes = + tl::Max<1, sInlineCapacity * ElemSize::value>::value; + + /* member data */ + + /* + * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, + * mBegin + mLength) hold valid constructed T objects. The range [mBegin + + * mLength, mBegin + mCapacity) holds uninitialized memory. The range + * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory + * previously allocated by a call to reserve(). + */ + T* mBegin; + + /* Number of elements in the vector. */ + size_t mLength; + + /* Max number of elements storable in the vector without resizing. */ + size_t mCapacity; + +#ifdef DEBUG + /* Max elements of reserved or used space in this vector. */ + size_t mReserved; +#endif + + /* Memory used for inline storage. */ + AlignedStorage storage; + +#ifdef DEBUG + friend class ReentrancyGuard; + bool entered; +#endif + + /* private accessors */ + + bool usingInlineStorage() const { + return mBegin == const_cast(this)->inlineStorage(); + } + + T* inlineStorage() { + return static_cast(storage.addr()); + } + + T* beginNoCheck() const { + return mBegin; + } + + T* endNoCheck() { + return mBegin + mLength; + } + + const T* endNoCheck() const { + return mBegin + mLength; + } + +#ifdef DEBUG + size_t reserved() const { + MOZ_ASSERT(mReserved <= mCapacity); + MOZ_ASSERT(mLength <= mReserved); + return mReserved; + } +#endif + + /* Append operations guaranteed to succeed due to pre-reserved space. */ + template void internalAppend(const U& u); + template + void internalAppendAll(const VectorBase& u); + void internalAppendN(const T& t, size_t n); + template void internalAppend(const U* begin, size_t length); + + public: + static const size_t sMaxInlineStorage = N; + + typedef T ElementType; + + VectorBase(AllocPolicy = AllocPolicy()); + VectorBase(MoveRef); /* Move constructor. */ + ThisVector& operator=(MoveRef); /* Move assignment. */ + ~VectorBase(); + + /* accessors */ + + const AllocPolicy& allocPolicy() const { + return *this; + } + + AllocPolicy& allocPolicy() { + return *this; + } + + enum { InlineLength = N }; + + size_t length() const { + return mLength; + } + + bool empty() const { + return mLength == 0; + } + + size_t capacity() const { + return mCapacity; + } + + T* begin() { + MOZ_ASSERT(!entered); + return mBegin; + } + + const T* begin() const { + MOZ_ASSERT(!entered); + return mBegin; + } + + T* end() { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + const T* end() const { + MOZ_ASSERT(!entered); + return mBegin + mLength; + } + + T& operator[](size_t i) { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + const T& operator[](size_t i) const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(i < mLength); + return begin()[i]; + } + + T& back() { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + const T& back() const { + MOZ_ASSERT(!entered); + MOZ_ASSERT(!empty()); + return *(end() - 1); + } + + class Range + { + friend class VectorBase; + T* cur_; + T* end_; + Range(T* cur, T* end) : cur_(cur), end_(end) {} + + public: + Range() {} + bool empty() const { return cur_ == end_; } + size_t remain() const { return end_ - cur_; } + T& front() const { return *cur_; } + void popFront() { MOZ_ASSERT(!empty()); ++cur_; } + T popCopyFront() { MOZ_ASSERT(!empty()); return *cur_++; } + }; + + Range all() { + return Range(begin(), end()); + } + + /* mutators */ + + /** + * Given that the vector is empty and has no inline storage, grow to + * |capacity|. + */ + bool initCapacity(size_t request); + + /** + * If reserve(length() + N) succeeds, the N next appends are guaranteed to + * succeed. + */ + bool reserve(size_t request); + + /** + * Destroy elements in the range [end() - incr, end()). Does not deallocate + * or unreserve storage for those elements. + */ + void shrinkBy(size_t incr); + + /** Grow the vector by incr elements. */ + bool growBy(size_t incr); + + /** Call shrinkBy or growBy based on whether newSize > length(). */ + bool resize(size_t newLength); + + /** + * Increase the length of the vector, but don't initialize the new elements + * -- leave them as uninitialized memory. + */ + bool growByUninitialized(size_t incr); + bool resizeUninitialized(size_t newLength); + + /** Shorthand for shrinkBy(length()). */ + void clear(); + + /** Clears and releases any heap-allocated storage. */ + void clearAndFree(); + + /** + * If true, appending |needed| elements won't reallocate elements storage. + * This *doesn't* mean that infallibleAppend may be used! You still must + * reserve the extra space, even if this method indicates that appends won't + * need to reallocate elements storage. + */ + bool canAppendWithoutRealloc(size_t needed) const; + + /** + * Potentially fallible append operations. + * + * The function templates that take an unspecified type U require a const T& + * or a MoveRef. The MoveRef variants move their operands into the + * vector, instead of copying them. If they fail, the operand is left + * unmoved. + */ + template bool append(const U& u); + template + bool appendAll(const VectorBase& u); + bool appendN(const T& t, size_t n); + template bool append(const U* begin, const U* end); + template bool append(const U* begin, size_t length); + + /* + * Guaranteed-infallible append operations for use upon vectors whose + * memory has been pre-reserved. Don't use this if you haven't reserved the + * memory! + */ + template void infallibleAppend(const U& u) { + internalAppend(u); + } + void infallibleAppendN(const T& t, size_t n) { + internalAppendN(t, n); + } + template void infallibleAppend(const U* aBegin, const U* aEnd) { + internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); + } + template void infallibleAppend(const U* aBegin, size_t aLength) { + internalAppend(aBegin, aLength); + } + + void popBack(); + + T popCopy(); + + /** + * Transfers ownership of the internal buffer used by this vector to the + * caller. (It's the caller's responsibility to properly deallocate this + * buffer, in accordance with this vector's AllocPolicy.) After this call, + * the vector is empty. Since the returned buffer may need to be allocated + * (if the elements are currently stored in-place), the call can fail, + * returning nullptr. + * + * N.B. Although a T*, only the range [0, length()) is constructed. + */ + T* extractRawBuffer(); + + /** + * Transfer ownership of an array of objects into the vector. The caller + * must have allocated the array in accordance with this vector's + * AllocPolicy. + * + * N.B. This call assumes that there are no uninitialized elements in the + * passed array. + */ + void replaceRawBuffer(T* p, size_t length); + + /** + * Places |val| at position |p|, shifting existing elements from |p| onward + * one position higher. On success, |p| should not be reused because it'll + * be a dangling pointer if reallocation of the vector storage occurred; the + * return value should be used instead. On failure, nullptr is returned. + * + * Example usage: + * + * if (!(p = vec.insert(p, val))) + * + * + * + * This is inherently a linear-time operation. Be careful! + */ + T* insert(T* p, const T& val); + + /** + * Removes the element |t|, which must fall in the bounds [begin, end), + * shifting existing elements from |t + 1| onward one position lower. + */ + void erase(T* t); + + /** + * Measure the size of the vector's heap-allocated storage. + */ + size_t sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const; + + /** + * Like sizeOfExcludingThis, but also measures the size of the vector + * object (which must be heap-allocated) itself. + */ + size_t sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const; + + void swap(ThisVector& other); + + private: + VectorBase(const ThisVector&) MOZ_DELETE; + void operator=(const ThisVector&) MOZ_DELETE; +}; + +/* This does the re-entrancy check plus several other sanity checks. */ +#define MOZ_REENTRANCY_GUARD_ET_AL \ + ReentrancyGuard g(*this); \ + MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ + MOZ_ASSERT(reserved() <= mCapacity); \ + MOZ_ASSERT(mLength <= reserved()); \ + MOZ_ASSERT(mLength <= mCapacity) + +/* Vector Implementation */ + +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(AP ap) + : AP(ap), + mBegin(static_cast(storage.addr())), + mLength(0), + mCapacity(sInlineCapacity) +#ifdef DEBUG + , mReserved(sInlineCapacity), + entered(false) +#endif +{} + +/* Move constructor. */ +template +MOZ_ALWAYS_INLINE +VectorBase::VectorBase(MoveRef rhs) + : AllocPolicy(rhs) +#ifdef DEBUG + , entered(false) +#endif +{ + mLength = rhs->mLength; + mCapacity = rhs->mCapacity; +#ifdef DEBUG + mReserved = rhs->mReserved; +#endif + + if (rhs->usingInlineStorage()) { + /* We can't move the buffer over in this case, so copy elements. */ + mBegin = static_cast(storage.addr()); + Impl::moveConstruct(mBegin, rhs->beginNoCheck(), rhs->endNoCheck()); + /* + * Leave rhs's mLength, mBegin, mCapacity, and mReserved as they are. + * The elements in its in-line storage still need to be destroyed. + */ + } else { + /* + * Take src's buffer, and turn src into an empty vector using + * in-line storage. + */ + mBegin = rhs->mBegin; + rhs->mBegin = static_cast(rhs->storage.addr()); + rhs->mCapacity = sInlineCapacity; + rhs->mLength = 0; +#ifdef DEBUG + rhs->mReserved = sInlineCapacity; +#endif + } +} + +/* Move assignment. */ +template +MOZ_ALWAYS_INLINE +TV& +VectorBase::operator=(MoveRef rhs) +{ + TV* tv = static_cast(this); + tv->~TV(); + new(tv) TV(rhs); + return *tv; +} + +template +MOZ_ALWAYS_INLINE +VectorBase::~VectorBase() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); +} + +/* + * This function will create a new heap buffer with capacity newCap, + * move all elements in the inline buffer to this new buffer, + * and fail on OOM. + */ +template +inline bool +VectorBase::convertToHeapStorage(size_t newCap) +{ + MOZ_ASSERT(usingInlineStorage()); + + /* Allocate buffer. */ + MOZ_ASSERT(!detail::CapacityHasExcessSpace(newCap)); + T* newBuf = reinterpret_cast(this->malloc_(newCap * sizeof(T))); + if (!newBuf) + return false; + + /* Copy inline elements into heap buffer. */ + Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + + /* Switch in heap buffer. */ + mBegin = newBuf; + /* mLength is unchanged. */ + mCapacity = newCap; + return true; +} + +template +MOZ_NEVER_INLINE bool +VectorBase::growStorageBy(size_t incr) +{ + MOZ_ASSERT(mLength + incr > mCapacity); + MOZ_ASSERT_IF(!usingInlineStorage(), + !detail::CapacityHasExcessSpace(mCapacity)); + + /* + * When choosing a new capacity, its size should is as close to 2**N bytes + * as possible. 2**N-sized requests are best because they are unlikely to + * be rounded up by the allocator. Asking for a 2**N number of elements + * isn't as good, because if sizeof(T) is not a power-of-two that would + * result in a non-2**N request size. + */ + + size_t newCap; + + if (incr == 1) { + if (usingInlineStorage()) { + /* This case occurs in ~70--80% of the calls to this function. */ + size_t newSize = + tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::value; + newCap = newSize / sizeof(T); + goto convert; + } + + if (mLength == 0) { + /* This case occurs in ~0--10% of the calls to this function. */ + newCap = 1; + goto grow; + } + + /* This case occurs in ~15--20% of the calls to this function. */ + + /* + * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector + * to 1GB of memory on a 32-bit system, which is a reasonable limit. It + * also ensures that + * + * static_cast(end()) - static_cast(begin()) + * + * doesn't overflow ptrdiff_t (see bug 510319). + */ + if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::value) { + this->reportAllocOverflow(); + return false; + } + + /* + * If we reach here, the existing capacity will have a size that is already + * as close to 2^N as sizeof(T) will allow. Just double the capacity, and + * then there might be space for one more element. + */ + newCap = mLength * 2; + if (detail::CapacityHasExcessSpace(newCap)) + newCap += 1; + } else { + /* This case occurs in ~2% of the calls to this function. */ + size_t newMinCap = mLength + incr; + + /* Did mLength + incr overflow? Will newCap * sizeof(T) overflow? */ + if (newMinCap < mLength || + newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value) + { + this->reportAllocOverflow(); + return false; + } + + size_t newMinSize = newMinCap * sizeof(T); + size_t newSize = RoundUpPow2(newMinSize); + newCap = newSize / sizeof(T); + } + + if (usingInlineStorage()) { + convert: + return convertToHeapStorage(newCap); + } + +grow: + return Impl::growTo(*this, newCap); +} + +template +inline bool +VectorBase::initCapacity(size_t request) +{ + MOZ_ASSERT(empty()); + MOZ_ASSERT(usingInlineStorage()); + if (request == 0) + return true; + T* newbuf = reinterpret_cast(this->malloc_(request * sizeof(T))); + if (!newbuf) + return false; + mBegin = newbuf; + mCapacity = request; +#ifdef DEBUG + mReserved = request; +#endif + return true; +} + +template +inline bool +VectorBase::reserve(size_t request) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (request > mCapacity && !growStorageBy(request - mLength)) + return false; + +#ifdef DEBUG + if (request > mReserved) + mReserved = request; + MOZ_ASSERT(mLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); +#endif + return true; +} + +template +inline void +VectorBase::shrinkBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(incr <= mLength); + Impl::destroy(endNoCheck() - incr, endNoCheck()); + mLength -= incr; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growBy(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + T* newend = endNoCheck() + incr; + Impl::initialize(endNoCheck(), newend); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::growByUninitialized(size_t incr) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (incr > mCapacity - mLength && !growStorageBy(incr)) + return false; + + MOZ_ASSERT(mLength + incr <= mCapacity); + mLength += incr; +#ifdef DEBUG + if (mLength > mReserved) + mReserved = mLength; +#endif + return true; +} + +template +inline bool +VectorBase::resize(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growBy(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::resizeUninitialized(size_t newLength) +{ + size_t curLength = mLength; + if (newLength > curLength) + return growByUninitialized(newLength - curLength); + shrinkBy(curLength - newLength); + return true; +} + +template +inline void +VectorBase::clear() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + Impl::destroy(beginNoCheck(), endNoCheck()); + mLength = 0; +} + +template +inline void +VectorBase::clearAndFree() +{ + clear(); + + if (usingInlineStorage()) + return; + + this->free_(beginNoCheck()); + mBegin = static_cast(storage.addr()); + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif +} + +template +inline bool +VectorBase::canAppendWithoutRealloc(size_t needed) const +{ + return mLength + needed <= mCapacity; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendAll(const VectorBase& other) +{ + internalAppend(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U& u) +{ + MOZ_ASSERT(mLength + 1 <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + new(endNoCheck()) T(u); + ++mLength; +} + +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendN(const T& t, size_t needed) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppendN(t, needed); + return true; +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppendN(const T& t, size_t needed) +{ + MOZ_ASSERT(mLength + needed <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstructN(endNoCheck(), needed, t); + mLength += needed; +} + +template +inline T* +VectorBase::insert(T* p, const T& val) +{ + MOZ_ASSERT(begin() <= p); + MOZ_ASSERT(p <= end()); + size_t pos = p - begin(); + MOZ_ASSERT(pos <= mLength); + size_t oldLength = mLength; + if (pos == oldLength) { + if (!append(val)) + return nullptr; + } else { + T oldBack = back(); + if (!append(oldBack)) /* Dup the last element. */ + return nullptr; + for (size_t i = oldLength; i > pos; --i) + (*this)[i] = (*this)[i - 1]; + (*this)[pos] = val; + } + return begin() + pos; +} + +template +inline void +VectorBase::erase(T* it) +{ + MOZ_ASSERT(begin() <= it); + MOZ_ASSERT(it < end()); + while (it + 1 < end()) { + *it = *(it + 1); + ++it; + } + popBack(); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U* insBegin, const U* insEnd) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + size_t needed = PointerRangeSize(insBegin, insEnd); + if (mLength + needed > mCapacity && !growStorageBy(needed)) + return false; + +#ifdef DEBUG + if (mLength + needed > mReserved) + mReserved = mLength + needed; +#endif + internalAppend(insBegin, needed); + return true; +} + +template +template +MOZ_ALWAYS_INLINE void +VectorBase::internalAppend(const U* insBegin, size_t insLength) +{ + MOZ_ASSERT(mLength + insLength <= mReserved); + MOZ_ASSERT(mReserved <= mCapacity); + Impl::copyConstruct(endNoCheck(), insBegin, insBegin + insLength); + mLength += insLength; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U& u) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + if (mLength == mCapacity && !growStorageBy(1)) + return false; + +#ifdef DEBUG + if (mLength + 1 > mReserved) + mReserved = mLength + 1; +#endif + internalAppend(u); + return true; +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::appendAll(const VectorBase& other) +{ + return append(other.begin(), other.length()); +} + +template +template +MOZ_ALWAYS_INLINE bool +VectorBase::append(const U *insBegin, size_t insLength) +{ + return append(insBegin, insBegin + insLength); +} + +template +MOZ_ALWAYS_INLINE void +VectorBase::popBack() +{ + MOZ_REENTRANCY_GUARD_ET_AL; + MOZ_ASSERT(!empty()); + --mLength; + endNoCheck()->~T(); +} + +template +MOZ_ALWAYS_INLINE T +VectorBase::popCopy() +{ + T ret = back(); + popBack(); + return ret; +} + +template +inline T* +VectorBase::extractRawBuffer() +{ + T* ret; + if (usingInlineStorage()) { + ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); + if (!ret) + return nullptr; + Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); + Impl::destroy(beginNoCheck(), endNoCheck()); + /* mBegin, mCapacity are unchanged. */ + mLength = 0; + } else { + ret = mBegin; + mBegin = static_cast(storage.addr()); + mLength = 0; + mCapacity = sInlineCapacity; +#ifdef DEBUG + mReserved = sInlineCapacity; +#endif + } + return ret; +} + +template +inline void +VectorBase::replaceRawBuffer(T* p, size_t aLength) +{ + MOZ_REENTRANCY_GUARD_ET_AL; + + /* Destroy what we have. */ + Impl::destroy(beginNoCheck(), endNoCheck()); + if (!usingInlineStorage()) + this->free_(beginNoCheck()); + + /* Take in the new buffer. */ + if (aLength <= sInlineCapacity) { + /* + * We convert to inline storage if possible, even though p might + * otherwise be acceptable. Maybe this behaviour should be + * specifiable with an argument to this function. + */ + mBegin = static_cast(storage.addr()); + mLength = aLength; + mCapacity = sInlineCapacity; + Impl::moveConstruct(mBegin, p, p + aLength); + Impl::destroy(p, p + aLength); + this->free_(p); + } else { + mBegin = p; + mLength = aLength; + mCapacity = aLength; + } +#ifdef DEBUG + mReserved = aLength; +#endif +} + +template +inline size_t +VectorBase::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const +{ + return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck()); +} + +template +inline size_t +VectorBase::sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const +{ + return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); +} + +template +inline void +VectorBase::swap(TV& other) +{ + static_assert(N == 0, + "still need to implement this for N != 0"); + + // This only works when inline storage is always empty. + if (!usingInlineStorage() && other.usingInlineStorage()) { + other.mBegin = mBegin; + mBegin = inlineStorage(); + } else if (usingInlineStorage() && !other.usingInlineStorage()) { + mBegin = other.mBegin; + other.mBegin = other.inlineStorage(); + } else if (!usingInlineStorage() && !other.usingInlineStorage()) { + Swap(mBegin, other.mBegin); + } else { + // This case is a no-op, since we'd set both to use their inline storage. + } + + Swap(mLength, other.mLength); + Swap(mCapacity, other.mCapacity); +#ifdef DEBUG + Swap(mReserved, other.mReserved); +#endif +} + +/* + * STL-like container providing a short-lived, dynamic buffer. Vector calls the + * constructors/destructors of all elements stored in its internal buffer, so + * non-PODs may be safely used. Additionally, Vector will store the first N + * elements in-place before resorting to dynamic allocation. + * + * T requirements: + * - default and copy constructible, assignable, destructible + * - operations do not throw + * N requirements: + * - any value, however, N is clamped to min/max values + * AllocPolicy: + * - see "Allocation policies" in AllocPolicy.h (defaults to + * mozilla::MallocAllocPolicy) + * + * Vector is not reentrant: T member functions called during Vector member + * functions must not call back into the same object! + */ +template +class Vector + : public VectorBase > +{ + typedef VectorBase Base; + + public: + Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + Vector(mozilla::MoveRef vec) : Base(vec) {} + Vector& operator=(mozilla::MoveRef vec) { + return Base::operator=(vec); + } +}; + +} // namespace mozilla + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif /* mozilla_Vector_h */ diff --git a/external/spidermonkey/include/win32/mozilla/WeakPtr.h b/external/spidermonkey/include/win32/mozilla/WeakPtr.h index d61b0b37d3..c714ebf565 100644 --- a/external/spidermonkey/include/win32/mozilla/WeakPtr.h +++ b/external/spidermonkey/include/win32/mozilla/WeakPtr.h @@ -1,7 +1,8 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Weak pointer functionality, implemented as a mixin for use with any class. */ @@ -13,6 +14,9 @@ * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime * of 'Foo'. * + * AtomicSupportsWeakPtr can be used for a variant with an atomically updated + * reference counter. + * * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional * dereference, and an additional heap allocated pointer sized object shared * between all of the WeakPtrs. @@ -55,10 +59,11 @@ * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h */ -#ifndef mozilla_WeakPtr_h_ -#define mozilla_WeakPtr_h_ +#ifndef mozilla_WeakPtr_h +#define mozilla_WeakPtr_h #include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" #include "mozilla/NullPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/TypeTraits.h" @@ -71,8 +76,8 @@ template class SupportsWeakPtrBase; namespace detail { // This can live beyond the lifetime of the class derived from SupportsWeakPtrBase. -template -class WeakReference : public RefCounted > +template +class WeakReference : public RefCounted, Atomicity> { public: explicit WeakReference(T* p) : ptr(p) {} @@ -81,8 +86,8 @@ class WeakReference : public RefCounted > } private: - friend class WeakPtrBase >; - friend class SupportsWeakPtrBase >; + friend class WeakPtrBase; + friend class SupportsWeakPtrBase; void detach() { ptr = nullptr; } @@ -103,8 +108,8 @@ class SupportsWeakPtrBase protected: ~SupportsWeakPtrBase() { - MOZ_STATIC_ASSERT((IsBaseOf, T>::value), - "T must derive from SupportsWeakPtrBase"); + static_assert(IsBaseOf, T>::value, + "T must derive from SupportsWeakPtrBase"); if (weakRef) weakRef->detach(); } @@ -116,10 +121,30 @@ class SupportsWeakPtrBase }; template -class SupportsWeakPtr : public SupportsWeakPtrBase > +class SupportsWeakPtr + : public SupportsWeakPtrBase > { }; +template +class AtomicSupportsWeakPtr + : public SupportsWeakPtrBase > +{ +}; + +namespace detail { + +template +struct WeakReferenceCount +{ + static const RefCountAtomicity atomicity = + IsBaseOf, T>::value + ? AtomicRefCount + : NonAtomicRefCount; +}; + +} + template class WeakPtrBase { @@ -152,9 +177,9 @@ class WeakPtrBase }; template -class WeakPtr : public WeakPtrBase > +class WeakPtr : public WeakPtrBase::atomicity> > { - typedef WeakPtrBase > Base; + typedef WeakPtrBase::atomicity> > Base; public: WeakPtr(const WeakPtr& o) : Base(o) {} WeakPtr(const Base& o) : Base(o) {} @@ -163,4 +188,4 @@ class WeakPtr : public WeakPtrBase > } // namespace mozilla -#endif /* ifdef mozilla_WeakPtr_h_ */ +#endif /* mozilla_WeakPtr_h */ diff --git a/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id index 34db1e4f01..8362daf11f 100644 --- a/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -ab3b6f2938d78c25531e3afcac0dbc1e2ae234ac \ No newline at end of file +faf19f806c33a8c42138cd4ada1c76d04f9510f4 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id index d808087a7d..8da98b5613 100644 --- a/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -be12c5e66dcb793cb02c542083565cc569d9cf43 \ No newline at end of file +9c5b123f113fb3b0b6846b4f1123ec5a40004944 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id index fd7cdf9335..74e8973064 100644 --- a/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -916f323784cc5896ba7fe056ee2a6be4cc75507f \ No newline at end of file +3e18fa7933f481d605147b1d46dd7afee105fa2c \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id index 62d0642dea..a263aa1a15 100644 --- a/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -de60414ce2fd3a5d2d446568baf6a5b1f268dace \ No newline at end of file +62ff11f15f6f4dae163513e336bc3e4671b91a90 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id index 904a424da5..609f8680c6 100644 --- a/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -97a549a55dd578b65863f083b4aa76a4c0a521b7 \ No newline at end of file +591cdbb9304d6f7b5682542b7a50e0b5ae4d6a4d \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/win32/mozjs-23.0.dll.REMOVED.git-id b/external/spidermonkey/prebuilt/win32/mozjs-23.0.dll.REMOVED.git-id deleted file mode 100644 index a57db13141..0000000000 --- a/external/spidermonkey/prebuilt/win32/mozjs-23.0.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -83c05fbd090f7df8dda9789f7201534375ebb993 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/win32/mozjs-23.0.lib.REMOVED.git-id b/external/spidermonkey/prebuilt/win32/mozjs-23.0.lib.REMOVED.git-id deleted file mode 100644 index c727112da9..0000000000 --- a/external/spidermonkey/prebuilt/win32/mozjs-23.0.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c4ea49d145a5b6898bd7c5c00c8e78413a6894b1 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id b/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id new file mode 100644 index 0000000000..7e9dc81732 --- /dev/null +++ b/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id @@ -0,0 +1 @@ +c1212ee7de1da38ee10b27e327120205ab2cac7c \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id b/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id new file mode 100644 index 0000000000..ae3f274acc --- /dev/null +++ b/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id @@ -0,0 +1 @@ +5991d26d951ae7b8398cd037bb22422ec33ab949 \ No newline at end of file From 3b86d6398f7af675b883319ef422dab955ebb1c9 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 30 Oct 2013 21:56:07 +0800 Subject: [PATCH 082/144] [sp v25] Fixing complication errors after updating Spidermonkey to v25. --- .../javascript/bindings/ScriptingCore.cpp | 101 +++- ...dings_chipmunk_auto_classes_registration.h | 36 +- ...bindings_chipmunk_functions_registration.h | 546 +++++++++--------- .../chipmunk/js_bindings_chipmunk_manual.cpp | 13 +- .../js_bindings_chipmunk_registration.cpp | 36 +- .../cocos2d_specifics.cpp.REMOVED.git-id | 2 +- .../cocosbuilder/js_bindings_ccbreader.cpp | 4 +- .../bindings/cocosjs_manual_conversions.cpp | 6 +- .../jsb_cocos2dx_extension_manual.cpp | 14 +- .../bindings/js_bindings_opengl.cpp | 11 +- .../javascript/bindings/jsb_helper.h | 12 +- .../bindings/jsb_opengl_registration.cpp | 10 +- .../js_bindings_system_registration.cpp | 10 +- .../bindings/network/XMLHTTPRequest.cpp | 7 +- .../bindings/network/jsb_websocket.cpp | 32 +- 15 files changed, 452 insertions(+), 388 deletions(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index c4603fc8c0..6a8ac7dd98 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -300,13 +300,13 @@ JSBool JSB_core_restartVM(JSContext *cx, uint32_t argc, jsval *vp) void registerDefaultClasses(JSContext* cx, JSObject* global) { // first, try to get the ns - jsval nsval; + JS::RootedValue nsval(cx); JSObject *ns; JS_GetProperty(cx, global, "cc", &nsval); if (nsval == JSVAL_VOID) { ns = JS_NewObject(cx, NULL, NULL, NULL); nsval = OBJECT_TO_JSVAL(ns); - JS_SetProperty(cx, global, "cc", &nsval); + JS_SetProperty(cx, global, "cc", nsval); } else { JS_ValueToObject(cx, nsval, &ns); } @@ -315,8 +315,9 @@ void registerDefaultClasses(JSContext* cx, JSObject* global) { // Javascript controller (__jsc__) // JSObject *jsc = JS_NewObject(cx, NULL, NULL, NULL); - jsval jscVal = OBJECT_TO_JSVAL(jsc); - JS_SetProperty(cx, global, "__jsc__", &jscVal); + JS::RootedValue jscVal(cx); + jscVal = OBJECT_TO_JSVAL(jsc); + JS_SetProperty(cx, global, "__jsc__", jscVal); JS_DefineFunction(cx, jsc, "garbageCollect", ScriptingCore::forceGC, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); JS_DefineFunction(cx, jsc, "dumpRoot", ScriptingCore::dumpRoot, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); @@ -451,6 +452,11 @@ void ScriptingCore::createGlobalContext() { this->_cx = NULL; this->_rt = NULL; } + + // Start the engine. Added in SpiderMonkey v25 + if (!JS_Init()) + return; + // Removed from Spidermonkey 19. //JS_SetCStringsAreUTF8(); this->_rt = JS_NewRuntime(8L * 1024L * 1024L, JS_USE_HELPER_THREADS); @@ -461,13 +467,15 @@ void ScriptingCore::createGlobalContext() { JS_SetNativeStackQuota(_rt, JSB_MAX_STACK_QUOTA); this->_cx = JS_NewContext(_rt, 8192); + JS_SetOptions(this->_cx, JSOPTION_TYPE_INFERENCE); - JS_SetVersion(this->_cx, JSVERSION_LATEST); + +// JS_SetVersion(this->_cx, JSVERSION_LATEST); // Only disable METHODJIT on iOS. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) - JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT); - JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT_ALWAYS); +// JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT); +// JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT_ALWAYS); #endif JS_SetErrorReporter(this->_cx, ScriptingCore::reportError); @@ -475,7 +483,10 @@ void ScriptingCore::createGlobalContext() { //JS_SetGCZeal(this->_cx, 2, JS_DEFAULT_ZEAL_FREQ); #endif this->_global = NewGlobalObject(_cx); - + JS_AddObjectRoot(_cx, &_global); + JSAutoCompartment ac(_cx, _global); + js::SetDefaultObjectForContext(_cx, _global); + for (std::vector::iterator it = registrationList.begin(); it != registrationList.end(); it++) { sc_register_sth callback = *it; callback(this->_cx, this->_global); @@ -507,8 +518,12 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c if (cx == NULL) { cx = _cx; } - JSScript *script = NULL; + + JSAutoCompartment ac(cx, global); + + js::RootedScript script(cx); js::RootedObject obj(cx, global); + JS::CompileOptions options(cx); options.setUTF8(true).setFileAndLine(fullPath.c_str(), 1); @@ -659,7 +674,7 @@ JSBool ScriptingCore::executeScript(JSContext *cx, uint32_t argc, jsval *vp) return JS_FALSE; } } else { - JSObject* glob = JS_GetGlobalForScopeChain(cx); + JSObject* glob = JS::CurrentGlobalOrNull(cx); res = ScriptingCore::getInstance()->runScript(path, glob); } return res; @@ -925,8 +940,8 @@ JSBool ScriptingCore::executeFunctionWithOwner(jsval owner, const char *name, ui { JSBool bRet = JS_FALSE; JSBool hasAction; - jsval temp_retval; JSContext* cx = this->_cx; + JS::RootedValue temp_retval(cx); JSObject* obj = JSVAL_TO_OBJECT(owner); do @@ -1213,7 +1228,8 @@ JSBool jsval_to_std_string(JSContext *cx, jsval v, std::string* ret) { JSBool jsval_to_ccpoint(JSContext *cx, jsval v, Point* ret) { JSObject *tmp; - jsval jsx, jsy; + JS::RootedValue jsx(cx); + JS::RootedValue jsy(cx); double x, y; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1231,7 +1247,11 @@ JSBool jsval_to_ccpoint(JSContext *cx, jsval v, Point* ret) { JSBool jsval_to_ccacceleration(JSContext* cx,jsval v, Acceleration* ret) { JSObject *tmp; - jsval jsx, jsy, jsz, jstimestamp; + JS::RootedValue jsx(cx); + JS::RootedValue jsy(cx); + JS::RootedValue jsz(cx); + JS::RootedValue jstimestamp(cx); + double x, y, timestamp, z; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1292,7 +1312,11 @@ JSBool jsvals_variadic_to_ccarray( JSContext *cx, jsval *vp, int argc, Array** r JSBool jsval_to_ccrect(JSContext *cx, jsval v, Rect* ret) { JSObject *tmp; - jsval jsx, jsy, jswidth, jsheight; + JS::RootedValue jsx(cx); + JS::RootedValue jsy(cx); + JS::RootedValue jswidth(cx); + JS::RootedValue jsheight(cx); + double x, y, width, height; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1316,7 +1340,8 @@ JSBool jsval_to_ccrect(JSContext *cx, jsval v, Rect* ret) { JSBool jsval_to_ccsize(JSContext *cx, jsval v, Size* ret) { JSObject *tmp; - jsval jsw, jsh; + JS::RootedValue jsw(cx); + JS::RootedValue jsh(cx); double w, h; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1333,7 +1358,11 @@ JSBool jsval_to_ccsize(JSContext *cx, jsval v, Size* ret) { JSBool jsval_to_cccolor4b(JSContext *cx, jsval v, Color4B* ret) { JSObject *tmp; - jsval jsr, jsg, jsb, jsa; + JS::RootedValue jsr(cx); + JS::RootedValue jsg(cx); + JS::RootedValue jsb(cx); + JS::RootedValue jsa(cx); + double r, g, b, a; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1357,7 +1386,10 @@ JSBool jsval_to_cccolor4b(JSContext *cx, jsval v, Color4B* ret) { JSBool jsval_to_cccolor4f(JSContext *cx, jsval v, Color4F* ret) { JSObject *tmp; - jsval jsr, jsg, jsb, jsa; + JS::RootedValue jsr(cx); + JS::RootedValue jsg(cx); + JS::RootedValue jsb(cx); + JS::RootedValue jsa(cx); double r, g, b, a; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1380,7 +1412,9 @@ JSBool jsval_to_cccolor4f(JSContext *cx, jsval v, Color4F* ret) { JSBool jsval_to_cccolor3b(JSContext *cx, jsval v, Color3B* ret) { JSObject *tmp; - jsval jsr, jsg, jsb; + JS::RootedValue jsr(cx); + JS::RootedValue jsg(cx); + JS::RootedValue jsb(cx); double r, g, b; JSBool ok = v.isObject() && JS_ValueToObject(cx, v, &tmp) && @@ -1554,7 +1588,7 @@ jsval ccdictionary_to_jsval(JSContext* cx, Dictionary* dict) DictElement* pElement = NULL; CCDICT_FOREACH(dict, pElement) { - jsval dictElement; + JS::RootedValue dictElement(cx); Object* obj = pElement->getObject(); //First, check whether object is associated with js object. js_proxy_t* jsproxy = js_get_or_create_proxy(cx, obj); @@ -1591,7 +1625,7 @@ jsval ccdictionary_to_jsval(JSContext* cx, Dictionary* dict) const char* key = pElement->getStrKey(); if (key && strlen(key) > 0) { - JS_SetProperty(cx, jsRet, key, &dictElement); + JS_SetProperty(cx, jsRet, key, dictElement); } } return OBJECT_TO_JSVAL(jsRet); @@ -1635,7 +1669,7 @@ JSBool jsval_to_ccdictionary(JSContext* cx, jsval v, Dictionary** ret) { dict = Dictionary::create(); } - jsval value; + JS::RootedValue value(cx); JS_GetPropertyById(cx, tmp, idp, &value); if (value.isObject()) { @@ -1699,7 +1733,12 @@ JSBool jsval_to_ccdictionary(JSContext* cx, jsval v, Dictionary** ret) { JSBool jsval_to_ccaffinetransform(JSContext* cx, jsval v, AffineTransform* ret) { JSObject *tmp; - jsval jsa, jsb, jsc, jsd, jstx, jsty; + JS::RootedValue jsa(cx); + JS::RootedValue jsb(cx); + JS::RootedValue jsc(cx); + JS::RootedValue jsd(cx); + JS::RootedValue jstx(cx); + JS::RootedValue jsty(cx); double a, b, c, d, tx, ty; JSBool ok = JS_ValueToObject(cx, v, &tmp) && JS_GetProperty(cx, tmp, "a", &jsa) && @@ -2145,11 +2184,12 @@ JSBool JSBDebug_BufferWrite(JSContext* cx, unsigned argc, jsval* vp) void ScriptingCore::enableDebugger() { - JS_SetDebugMode(_cx, JS_TRUE); - if (_debugGlobal == NULL) { JSAutoCompartment ac0(_cx, _global); + + JS_SetDebugMode(_cx, JS_TRUE); + _debugGlobal = NewGlobalObject(_cx, true); JS_WrapObject(_cx, &_debugGlobal); JSAutoCompartment ac(_cx, _debugGlobal); @@ -2182,7 +2222,10 @@ void ScriptingCore::enableDebugger() JSObject* NewGlobalObject(JSContext* cx, bool debug) { - JSObject* glob = JS_NewGlobalObject(cx, &global_class, NULL); + JS::CompartmentOptions options; + options.setVersion(JSVERSION_LATEST); + + JS::RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, NULL, JS::DontFireOnNewGlobalHook, options)); if (!glob) { return NULL; } @@ -2196,6 +2239,8 @@ JSObject* NewGlobalObject(JSContext* cx, bool debug) if (!ok) return NULL; + JS_FireOnNewGlobalObject(cx, glob); + return glob; } @@ -2251,7 +2296,7 @@ void jsb_remove_proxy(js_proxy_t* nativeProxy, js_proxy_t* jsProxy) static Color3B getColorFromJSObject(JSContext *cx, JSObject *colorObject) { - jsval jsr; + JS::RootedValue jsr(cx); Color3B out; JS_GetProperty(cx, colorObject, "r", &jsr); double fontR = 0.0; @@ -2275,7 +2320,7 @@ static Color3B getColorFromJSObject(JSContext *cx, JSObject *colorObject) Size getSizeFromJSObject(JSContext *cx, JSObject *sizeObject) { - jsval jsr; + JS::RootedValue jsr(cx); Size out; JS_GetProperty(cx, sizeObject, "width", &jsr); double width = 0.0; @@ -2316,7 +2361,7 @@ JSBool jsval_to_FontDefinition( JSContext *cx, jsval vp, FontDefinition *out ) out->_fontFillColor = Color3B::WHITE; // font name - jsval jsr; + JS::RootedValue jsr(cx); JS_GetProperty(cx, jsobj, "fontName", &jsr); JS_ValueToString(cx, jsr); JSStringWrapper wrapper(jsr); diff --git a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_auto_classes_registration.h b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_auto_classes_registration.h index da26c49bb3..6435be96f6 100644 --- a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_auto_classes_registration.h +++ b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_auto_classes_registration.h @@ -6,24 +6,24 @@ #include "js_bindings_config.h" #ifdef JSB_INCLUDE_CHIPMUNK -JSB_cpConstraint_createClass(_cx, chipmunk, "Constraint"); -JSB_cpGrooveJoint_createClass(_cx, chipmunk, "GrooveJoint"); -JSB_cpSimpleMotor_createClass(_cx, chipmunk, "SimpleMotor"); -JSB_cpPivotJoint_createClass(_cx, chipmunk, "PivotJoint"); -JSB_cpPinJoint_createClass(_cx, chipmunk, "PinJoint"); -JSB_cpSlideJoint_createClass(_cx, chipmunk, "SlideJoint"); -JSB_cpGearJoint_createClass(_cx, chipmunk, "GearJoint"); -JSB_cpDampedRotarySpring_createClass(_cx, chipmunk, "DampedRotarySpring"); -JSB_cpDampedSpring_createClass(_cx, chipmunk, "DampedSpring"); -JSB_cpRatchetJoint_createClass(_cx, chipmunk, "RatchetJoint"); -JSB_cpRotaryLimitJoint_createClass(_cx, chipmunk, "RotaryLimitJoint"); -JSB_cpArbiter_createClass(_cx, chipmunk, "Arbiter"); -JSB_cpSpace_createClass(_cx, chipmunk, "Space"); -JSB_cpBody_createClass(_cx, chipmunk, "Body"); -JSB_cpShape_createClass(_cx, chipmunk, "Shape"); -JSB_cpCircleShape_createClass(_cx, chipmunk, "CircleShape"); -JSB_cpSegmentShape_createClass(_cx, chipmunk, "SegmentShape"); -JSB_cpPolyShape_createClass(_cx, chipmunk, "PolyShape"); +JSB_cpConstraint_createClass(cx, chipmunk, "Constraint"); +JSB_cpGrooveJoint_createClass(cx, chipmunk, "GrooveJoint"); +JSB_cpSimpleMotor_createClass(cx, chipmunk, "SimpleMotor"); +JSB_cpPivotJoint_createClass(cx, chipmunk, "PivotJoint"); +JSB_cpPinJoint_createClass(cx, chipmunk, "PinJoint"); +JSB_cpSlideJoint_createClass(cx, chipmunk, "SlideJoint"); +JSB_cpGearJoint_createClass(cx, chipmunk, "GearJoint"); +JSB_cpDampedRotarySpring_createClass(cx, chipmunk, "DampedRotarySpring"); +JSB_cpDampedSpring_createClass(cx, chipmunk, "DampedSpring"); +JSB_cpRatchetJoint_createClass(cx, chipmunk, "RatchetJoint"); +JSB_cpRotaryLimitJoint_createClass(cx, chipmunk, "RotaryLimitJoint"); +JSB_cpArbiter_createClass(cx, chipmunk, "Arbiter"); +JSB_cpSpace_createClass(cx, chipmunk, "Space"); +JSB_cpBody_createClass(cx, chipmunk, "Body"); +JSB_cpShape_createClass(cx, chipmunk, "Shape"); +JSB_cpCircleShape_createClass(cx, chipmunk, "CircleShape"); +JSB_cpSegmentShape_createClass(cx, chipmunk, "SegmentShape"); +JSB_cpPolyShape_createClass(cx, chipmunk, "PolyShape"); #endif // JSB_INCLUDE_CHIPMUNK diff --git a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_functions_registration.h b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_functions_registration.h index 2d84087c28..20e87592f9 100644 --- a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_functions_registration.h +++ b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_functions_registration.h @@ -7,279 +7,279 @@ #ifdef JSB_INCLUDE_CHIPMUNK #include "js_bindings_chipmunk_manual.h" -JS_DefineFunction(_cx, chipmunk, "arbiterGetCount", JSB_cpArbiterGetCount, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterGetDepth", JSB_cpArbiterGetDepth, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterGetElasticity", JSB_cpArbiterGetElasticity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterGetFriction", JSB_cpArbiterGetFriction, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterGetNormal", JSB_cpArbiterGetNormal, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterGetPoint", JSB_cpArbiterGetPoint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterGetSurfaceVelocity", JSB_cpArbiterGetSurfaceVelocity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterIgnore", JSB_cpArbiterIgnore, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterIsFirstContact", JSB_cpArbiterIsFirstContact, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterSetElasticity", JSB_cpArbiterSetElasticity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterSetFriction", JSB_cpArbiterSetFriction, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterSetSurfaceVelocity", JSB_cpArbiterSetSurfaceVelocity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterTotalImpulse", JSB_cpArbiterTotalImpulse, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterTotalImpulseWithFriction", JSB_cpArbiterTotalImpulseWithFriction, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "arbiterTotalKE", JSB_cpArbiterTotalKE, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "areaForCircle", JSB_cpAreaForCircle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "areaForSegment", JSB_cpAreaForSegment, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBArea", JSB_cpBBArea, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBClampVect", JSB_cpBBClampVect, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBContainsBB", JSB_cpBBContainsBB, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBContainsVect", JSB_cpBBContainsVect, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBExpand", JSB_cpBBExpand, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBIntersects", JSB_cpBBIntersects, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBIntersectsSegment", JSB_cpBBIntersectsSegment, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBMerge", JSB_cpBBMerge, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBMergedArea", JSB_cpBBMergedArea, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBNew", JSB_cpBBNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBNewForCircle", JSB_cpBBNewForCircle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBSegmentQuery", JSB_cpBBSegmentQuery, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bBWrapVect", JSB_cpBBWrapVect, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyActivate", JSB_cpBodyActivate, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyActivateStatic", JSB_cpBodyActivateStatic, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyApplyForce", JSB_cpBodyApplyForce, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyApplyImpulse", JSB_cpBodyApplyImpulse, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyDestroy", JSB_cpBodyDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyFree", JSB_cpBodyFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetAngVel", JSB_cpBodyGetAngVel, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetAngVelLimit", JSB_cpBodyGetAngVelLimit, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetAngle", JSB_cpBodyGetAngle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetForce", JSB_cpBodyGetForce, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetMass", JSB_cpBodyGetMass, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetMoment", JSB_cpBodyGetMoment, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetPos", JSB_cpBodyGetPos, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetRot", JSB_cpBodyGetRot, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetSpace", JSB_cpBodyGetSpace, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetTorque", JSB_cpBodyGetTorque, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetVel", JSB_cpBodyGetVel, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetVelAtLocalPoint", JSB_cpBodyGetVelAtLocalPoint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetVelAtWorldPoint", JSB_cpBodyGetVelAtWorldPoint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyGetVelLimit", JSB_cpBodyGetVelLimit, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyInit", JSB_cpBodyInit, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyInitStatic", JSB_cpBodyInitStatic, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyIsRogue", JSB_cpBodyIsRogue, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyIsSleeping", JSB_cpBodyIsSleeping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyIsStatic", JSB_cpBodyIsStatic, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyKineticEnergy", JSB_cpBodyKineticEnergy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyLocal2World", JSB_cpBodyLocal2World, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyNew", JSB_cpBodyNew, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyNewStatic", JSB_cpBodyNewStatic, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyResetForces", JSB_cpBodyResetForces, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetAngVel", JSB_cpBodySetAngVel, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetAngVelLimit", JSB_cpBodySetAngVelLimit, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetAngle", JSB_cpBodySetAngle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetForce", JSB_cpBodySetForce, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetMass", JSB_cpBodySetMass, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetMoment", JSB_cpBodySetMoment, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetPos", JSB_cpBodySetPos, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetTorque", JSB_cpBodySetTorque, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetVel", JSB_cpBodySetVel, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySetVelLimit", JSB_cpBodySetVelLimit, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySleep", JSB_cpBodySleep, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodySleepWithGroup", JSB_cpBodySleepWithGroup, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyUpdatePosition", JSB_cpBodyUpdatePosition, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyUpdateVelocity", JSB_cpBodyUpdateVelocity, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "bodyWorld2Local", JSB_cpBodyWorld2Local, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "boxShapeNew", JSB_cpBoxShapeNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "boxShapeNew2", JSB_cpBoxShapeNew2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "circleShapeGetOffset", JSB_cpCircleShapeGetOffset, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "circleShapeGetRadius", JSB_cpCircleShapeGetRadius, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "circleShapeNew", JSB_cpCircleShapeNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintActivateBodies", JSB_cpConstraintActivateBodies, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintDestroy", JSB_cpConstraintDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintFree", JSB_cpConstraintFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetA", JSB_cpConstraintGetA, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetB", JSB_cpConstraintGetB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetErrorBias", JSB_cpConstraintGetErrorBias, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetImpulse", JSB_cpConstraintGetImpulse, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetMaxBias", JSB_cpConstraintGetMaxBias, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetMaxForce", JSB_cpConstraintGetMaxForce, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintGetSpace", JSB_cpConstraintGetSpace, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintSetErrorBias", JSB_cpConstraintSetErrorBias, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintSetMaxBias", JSB_cpConstraintSetMaxBias, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "constraintSetMaxForce", JSB_cpConstraintSetMaxForce, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringGetDamping", JSB_cpDampedRotarySpringGetDamping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringGetRestAngle", JSB_cpDampedRotarySpringGetRestAngle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringGetStiffness", JSB_cpDampedRotarySpringGetStiffness, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringNew", JSB_cpDampedRotarySpringNew, 5, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringSetDamping", JSB_cpDampedRotarySpringSetDamping, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringSetRestAngle", JSB_cpDampedRotarySpringSetRestAngle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedRotarySpringSetStiffness", JSB_cpDampedRotarySpringSetStiffness, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringGetAnchr1", JSB_cpDampedSpringGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringGetAnchr2", JSB_cpDampedSpringGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringGetDamping", JSB_cpDampedSpringGetDamping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringGetRestLength", JSB_cpDampedSpringGetRestLength, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringGetStiffness", JSB_cpDampedSpringGetStiffness, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringNew", JSB_cpDampedSpringNew, 7, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringSetAnchr1", JSB_cpDampedSpringSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringSetAnchr2", JSB_cpDampedSpringSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringSetDamping", JSB_cpDampedSpringSetDamping, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringSetRestLength", JSB_cpDampedSpringSetRestLength, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "dampedSpringSetStiffness", JSB_cpDampedSpringSetStiffness, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "gearJointGetPhase", JSB_cpGearJointGetPhase, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "gearJointGetRatio", JSB_cpGearJointGetRatio, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "gearJointNew", JSB_cpGearJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "gearJointSetPhase", JSB_cpGearJointSetPhase, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "gearJointSetRatio", JSB_cpGearJointSetRatio, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointGetAnchr2", JSB_cpGrooveJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointGetGrooveA", JSB_cpGrooveJointGetGrooveA, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointGetGrooveB", JSB_cpGrooveJointGetGrooveB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointNew", JSB_cpGrooveJointNew, 5, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointSetAnchr2", JSB_cpGrooveJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointSetGrooveA", JSB_cpGrooveJointSetGrooveA, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "grooveJointSetGrooveB", JSB_cpGrooveJointSetGrooveB, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "initChipmunk", JSB_cpInitChipmunk, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "momentForBox", JSB_cpMomentForBox, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "momentForBox2", JSB_cpMomentForBox2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "momentForCircle", JSB_cpMomentForCircle, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "momentForSegment", JSB_cpMomentForSegment, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointGetAnchr1", JSB_cpPinJointGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointGetAnchr2", JSB_cpPinJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointGetDist", JSB_cpPinJointGetDist, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointNew", JSB_cpPinJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointSetAnchr1", JSB_cpPinJointSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointSetAnchr2", JSB_cpPinJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pinJointSetDist", JSB_cpPinJointSetDist, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pivotJointGetAnchr1", JSB_cpPivotJointGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pivotJointGetAnchr2", JSB_cpPivotJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pivotJointNew", JSB_cpPivotJointNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pivotJointNew2", JSB_cpPivotJointNew2, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pivotJointSetAnchr1", JSB_cpPivotJointSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "pivotJointSetAnchr2", JSB_cpPivotJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "polyShapeGetNumVerts", JSB_cpPolyShapeGetNumVerts, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "polyShapeGetVert", JSB_cpPolyShapeGetVert, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointGetAngle", JSB_cpRatchetJointGetAngle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointGetPhase", JSB_cpRatchetJointGetPhase, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointGetRatchet", JSB_cpRatchetJointGetRatchet, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointNew", JSB_cpRatchetJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointSetAngle", JSB_cpRatchetJointSetAngle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointSetPhase", JSB_cpRatchetJointSetPhase, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "ratchetJointSetRatchet", JSB_cpRatchetJointSetRatchet, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "resetShapeIdCounter", JSB_cpResetShapeIdCounter, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "rotaryLimitJointGetMax", JSB_cpRotaryLimitJointGetMax, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "rotaryLimitJointGetMin", JSB_cpRotaryLimitJointGetMin, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "rotaryLimitJointNew", JSB_cpRotaryLimitJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "rotaryLimitJointSetMax", JSB_cpRotaryLimitJointSetMax, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "rotaryLimitJointSetMin", JSB_cpRotaryLimitJointSetMin, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "segmentShapeGetA", JSB_cpSegmentShapeGetA, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "segmentShapeGetB", JSB_cpSegmentShapeGetB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "segmentShapeGetNormal", JSB_cpSegmentShapeGetNormal, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "segmentShapeGetRadius", JSB_cpSegmentShapeGetRadius, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "segmentShapeNew", JSB_cpSegmentShapeNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "segmentShapeSetNeighbors", JSB_cpSegmentShapeSetNeighbors, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeCacheBB", JSB_cpShapeCacheBB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeDestroy", JSB_cpShapeDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeFree", JSB_cpShapeFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetBB", JSB_cpShapeGetBB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetBody", JSB_cpShapeGetBody, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetCollisionType", JSB_cpShapeGetCollisionType, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetElasticity", JSB_cpShapeGetElasticity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetFriction", JSB_cpShapeGetFriction, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetGroup", JSB_cpShapeGetGroup, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetLayers", JSB_cpShapeGetLayers, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetSensor", JSB_cpShapeGetSensor, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetSpace", JSB_cpShapeGetSpace, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeGetSurfaceVelocity", JSB_cpShapeGetSurfaceVelocity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapePointQuery", JSB_cpShapePointQuery, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetBody", JSB_cpShapeSetBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetCollisionType", JSB_cpShapeSetCollisionType, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetElasticity", JSB_cpShapeSetElasticity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetFriction", JSB_cpShapeSetFriction, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetGroup", JSB_cpShapeSetGroup, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetLayers", JSB_cpShapeSetLayers, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetSensor", JSB_cpShapeSetSensor, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeSetSurfaceVelocity", JSB_cpShapeSetSurfaceVelocity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "shapeUpdate", JSB_cpShapeUpdate, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "simpleMotorGetRate", JSB_cpSimpleMotorGetRate, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "simpleMotorNew", JSB_cpSimpleMotorNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "simpleMotorSetRate", JSB_cpSimpleMotorSetRate, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointGetAnchr1", JSB_cpSlideJointGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointGetAnchr2", JSB_cpSlideJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointGetMax", JSB_cpSlideJointGetMax, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointGetMin", JSB_cpSlideJointGetMin, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointNew", JSB_cpSlideJointNew, 6, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointSetAnchr1", JSB_cpSlideJointSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointSetAnchr2", JSB_cpSlideJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointSetMax", JSB_cpSlideJointSetMax, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "slideJointSetMin", JSB_cpSlideJointSetMin, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceActivateShapesTouchingShape", JSB_cpSpaceActivateShapesTouchingShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceAddBody", JSB_cpSpaceAddBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceAddConstraint", JSB_cpSpaceAddConstraint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceAddShape", JSB_cpSpaceAddShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceAddStaticShape", JSB_cpSpaceAddStaticShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceContainsBody", JSB_cpSpaceContainsBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceContainsConstraint", JSB_cpSpaceContainsConstraint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceContainsShape", JSB_cpSpaceContainsShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceDestroy", JSB_cpSpaceDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceFree", JSB_cpSpaceFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetCollisionBias", JSB_cpSpaceGetCollisionBias, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetCollisionPersistence", JSB_cpSpaceGetCollisionPersistence, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetCollisionSlop", JSB_cpSpaceGetCollisionSlop, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetCurrentTimeStep", JSB_cpSpaceGetCurrentTimeStep, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetDamping", JSB_cpSpaceGetDamping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetEnableContactGraph", JSB_cpSpaceGetEnableContactGraph, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetGravity", JSB_cpSpaceGetGravity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetIdleSpeedThreshold", JSB_cpSpaceGetIdleSpeedThreshold, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetIterations", JSB_cpSpaceGetIterations, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetSleepTimeThreshold", JSB_cpSpaceGetSleepTimeThreshold, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceGetStaticBody", JSB_cpSpaceGetStaticBody, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceInit", JSB_cpSpaceInit, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceIsLocked", JSB_cpSpaceIsLocked, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceNew", JSB_cpSpaceNew, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spacePointQueryFirst", JSB_cpSpacePointQueryFirst, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceReindexShape", JSB_cpSpaceReindexShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceReindexShapesForBody", JSB_cpSpaceReindexShapesForBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceReindexStatic", JSB_cpSpaceReindexStatic, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceRemoveBody", JSB_cpSpaceRemoveBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceRemoveConstraint", JSB_cpSpaceRemoveConstraint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceRemoveShape", JSB_cpSpaceRemoveShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceRemoveStaticShape", JSB_cpSpaceRemoveStaticShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetCollisionBias", JSB_cpSpaceSetCollisionBias, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetCollisionPersistence", JSB_cpSpaceSetCollisionPersistence, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetCollisionSlop", JSB_cpSpaceSetCollisionSlop, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetDamping", JSB_cpSpaceSetDamping, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetEnableContactGraph", JSB_cpSpaceSetEnableContactGraph, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetGravity", JSB_cpSpaceSetGravity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetIdleSpeedThreshold", JSB_cpSpaceSetIdleSpeedThreshold, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetIterations", JSB_cpSpaceSetIterations, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceSetSleepTimeThreshold", JSB_cpSpaceSetSleepTimeThreshold, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceStep", JSB_cpSpaceStep, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "spaceUseSpatialHash", JSB_cpSpaceUseSpatialHash, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "fabs", JSB_cpfabs, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "fclamp", JSB_cpfclamp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "fclamp01", JSB_cpfclamp01, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "flerp", JSB_cpflerp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "flerpconst", JSB_cpflerpconst, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "fmax", JSB_cpfmax, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "fmin", JSB_cpfmin, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vadd", JSB_cpvadd, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vclamp", JSB_cpvclamp, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vcross", JSB_cpvcross, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vdist", JSB_cpvdist, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vdistsq", JSB_cpvdistsq, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vdot", JSB_cpvdot, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "veql", JSB_cpveql, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vforangle", JSB_cpvforangle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vlength", JSB_cpvlength, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vlengthsq", JSB_cpvlengthsq, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vlerp", JSB_cpvlerp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vlerpconst", JSB_cpvlerpconst, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vmult", JSB_cpvmult, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vnear", JSB_cpvnear, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vneg", JSB_cpvneg, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vnormalize", JSB_cpvnormalize, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vnormalize_safe", JSB_cpvnormalize_safe, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vperp", JSB_cpvperp, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vproject", JSB_cpvproject, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vrotate", JSB_cpvrotate, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vrperp", JSB_cpvrperp, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vslerp", JSB_cpvslerp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vslerpconst", JSB_cpvslerpconst, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vsub", JSB_cpvsub, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vtoangle", JSB_cpvtoangle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); -JS_DefineFunction(_cx, chipmunk, "vunrotate", JSB_cpvunrotate, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetCount", JSB_cpArbiterGetCount, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetDepth", JSB_cpArbiterGetDepth, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetElasticity", JSB_cpArbiterGetElasticity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetFriction", JSB_cpArbiterGetFriction, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetNormal", JSB_cpArbiterGetNormal, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetPoint", JSB_cpArbiterGetPoint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterGetSurfaceVelocity", JSB_cpArbiterGetSurfaceVelocity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterIgnore", JSB_cpArbiterIgnore, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterIsFirstContact", JSB_cpArbiterIsFirstContact, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterSetElasticity", JSB_cpArbiterSetElasticity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterSetFriction", JSB_cpArbiterSetFriction, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterSetSurfaceVelocity", JSB_cpArbiterSetSurfaceVelocity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterTotalImpulse", JSB_cpArbiterTotalImpulse, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterTotalImpulseWithFriction", JSB_cpArbiterTotalImpulseWithFriction, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "arbiterTotalKE", JSB_cpArbiterTotalKE, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "areaForCircle", JSB_cpAreaForCircle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "areaForSegment", JSB_cpAreaForSegment, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBArea", JSB_cpBBArea, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBClampVect", JSB_cpBBClampVect, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBContainsBB", JSB_cpBBContainsBB, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBContainsVect", JSB_cpBBContainsVect, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBExpand", JSB_cpBBExpand, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBIntersects", JSB_cpBBIntersects, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBIntersectsSegment", JSB_cpBBIntersectsSegment, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBMerge", JSB_cpBBMerge, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBMergedArea", JSB_cpBBMergedArea, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBNew", JSB_cpBBNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBNewForCircle", JSB_cpBBNewForCircle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBSegmentQuery", JSB_cpBBSegmentQuery, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bBWrapVect", JSB_cpBBWrapVect, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyActivate", JSB_cpBodyActivate, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyActivateStatic", JSB_cpBodyActivateStatic, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyApplyForce", JSB_cpBodyApplyForce, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyApplyImpulse", JSB_cpBodyApplyImpulse, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyDestroy", JSB_cpBodyDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyFree", JSB_cpBodyFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetAngVel", JSB_cpBodyGetAngVel, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetAngVelLimit", JSB_cpBodyGetAngVelLimit, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetAngle", JSB_cpBodyGetAngle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetForce", JSB_cpBodyGetForce, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetMass", JSB_cpBodyGetMass, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetMoment", JSB_cpBodyGetMoment, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetPos", JSB_cpBodyGetPos, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetRot", JSB_cpBodyGetRot, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetSpace", JSB_cpBodyGetSpace, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetTorque", JSB_cpBodyGetTorque, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetVel", JSB_cpBodyGetVel, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetVelAtLocalPoint", JSB_cpBodyGetVelAtLocalPoint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetVelAtWorldPoint", JSB_cpBodyGetVelAtWorldPoint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyGetVelLimit", JSB_cpBodyGetVelLimit, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyInit", JSB_cpBodyInit, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyInitStatic", JSB_cpBodyInitStatic, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyIsRogue", JSB_cpBodyIsRogue, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyIsSleeping", JSB_cpBodyIsSleeping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyIsStatic", JSB_cpBodyIsStatic, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyKineticEnergy", JSB_cpBodyKineticEnergy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyLocal2World", JSB_cpBodyLocal2World, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyNew", JSB_cpBodyNew, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyNewStatic", JSB_cpBodyNewStatic, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyResetForces", JSB_cpBodyResetForces, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetAngVel", JSB_cpBodySetAngVel, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetAngVelLimit", JSB_cpBodySetAngVelLimit, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetAngle", JSB_cpBodySetAngle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetForce", JSB_cpBodySetForce, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetMass", JSB_cpBodySetMass, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetMoment", JSB_cpBodySetMoment, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetPos", JSB_cpBodySetPos, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetTorque", JSB_cpBodySetTorque, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetVel", JSB_cpBodySetVel, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySetVelLimit", JSB_cpBodySetVelLimit, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySleep", JSB_cpBodySleep, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodySleepWithGroup", JSB_cpBodySleepWithGroup, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyUpdatePosition", JSB_cpBodyUpdatePosition, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyUpdateVelocity", JSB_cpBodyUpdateVelocity, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "bodyWorld2Local", JSB_cpBodyWorld2Local, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "boxShapeNew", JSB_cpBoxShapeNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "boxShapeNew2", JSB_cpBoxShapeNew2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "circleShapeGetOffset", JSB_cpCircleShapeGetOffset, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "circleShapeGetRadius", JSB_cpCircleShapeGetRadius, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "circleShapeNew", JSB_cpCircleShapeNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintActivateBodies", JSB_cpConstraintActivateBodies, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintDestroy", JSB_cpConstraintDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintFree", JSB_cpConstraintFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetA", JSB_cpConstraintGetA, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetB", JSB_cpConstraintGetB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetErrorBias", JSB_cpConstraintGetErrorBias, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetImpulse", JSB_cpConstraintGetImpulse, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetMaxBias", JSB_cpConstraintGetMaxBias, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetMaxForce", JSB_cpConstraintGetMaxForce, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintGetSpace", JSB_cpConstraintGetSpace, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintSetErrorBias", JSB_cpConstraintSetErrorBias, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintSetMaxBias", JSB_cpConstraintSetMaxBias, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "constraintSetMaxForce", JSB_cpConstraintSetMaxForce, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringGetDamping", JSB_cpDampedRotarySpringGetDamping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringGetRestAngle", JSB_cpDampedRotarySpringGetRestAngle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringGetStiffness", JSB_cpDampedRotarySpringGetStiffness, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringNew", JSB_cpDampedRotarySpringNew, 5, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringSetDamping", JSB_cpDampedRotarySpringSetDamping, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringSetRestAngle", JSB_cpDampedRotarySpringSetRestAngle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedRotarySpringSetStiffness", JSB_cpDampedRotarySpringSetStiffness, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringGetAnchr1", JSB_cpDampedSpringGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringGetAnchr2", JSB_cpDampedSpringGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringGetDamping", JSB_cpDampedSpringGetDamping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringGetRestLength", JSB_cpDampedSpringGetRestLength, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringGetStiffness", JSB_cpDampedSpringGetStiffness, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringNew", JSB_cpDampedSpringNew, 7, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringSetAnchr1", JSB_cpDampedSpringSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringSetAnchr2", JSB_cpDampedSpringSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringSetDamping", JSB_cpDampedSpringSetDamping, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringSetRestLength", JSB_cpDampedSpringSetRestLength, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "dampedSpringSetStiffness", JSB_cpDampedSpringSetStiffness, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "gearJointGetPhase", JSB_cpGearJointGetPhase, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "gearJointGetRatio", JSB_cpGearJointGetRatio, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "gearJointNew", JSB_cpGearJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "gearJointSetPhase", JSB_cpGearJointSetPhase, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "gearJointSetRatio", JSB_cpGearJointSetRatio, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointGetAnchr2", JSB_cpGrooveJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointGetGrooveA", JSB_cpGrooveJointGetGrooveA, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointGetGrooveB", JSB_cpGrooveJointGetGrooveB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointNew", JSB_cpGrooveJointNew, 5, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointSetAnchr2", JSB_cpGrooveJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointSetGrooveA", JSB_cpGrooveJointSetGrooveA, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "grooveJointSetGrooveB", JSB_cpGrooveJointSetGrooveB, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "initChipmunk", JSB_cpInitChipmunk, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "momentForBox", JSB_cpMomentForBox, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "momentForBox2", JSB_cpMomentForBox2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "momentForCircle", JSB_cpMomentForCircle, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "momentForSegment", JSB_cpMomentForSegment, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointGetAnchr1", JSB_cpPinJointGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointGetAnchr2", JSB_cpPinJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointGetDist", JSB_cpPinJointGetDist, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointNew", JSB_cpPinJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointSetAnchr1", JSB_cpPinJointSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointSetAnchr2", JSB_cpPinJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pinJointSetDist", JSB_cpPinJointSetDist, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pivotJointGetAnchr1", JSB_cpPivotJointGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pivotJointGetAnchr2", JSB_cpPivotJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pivotJointNew", JSB_cpPivotJointNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pivotJointNew2", JSB_cpPivotJointNew2, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pivotJointSetAnchr1", JSB_cpPivotJointSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "pivotJointSetAnchr2", JSB_cpPivotJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "polyShapeGetNumVerts", JSB_cpPolyShapeGetNumVerts, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "polyShapeGetVert", JSB_cpPolyShapeGetVert, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointGetAngle", JSB_cpRatchetJointGetAngle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointGetPhase", JSB_cpRatchetJointGetPhase, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointGetRatchet", JSB_cpRatchetJointGetRatchet, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointNew", JSB_cpRatchetJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointSetAngle", JSB_cpRatchetJointSetAngle, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointSetPhase", JSB_cpRatchetJointSetPhase, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "ratchetJointSetRatchet", JSB_cpRatchetJointSetRatchet, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "resetShapeIdCounter", JSB_cpResetShapeIdCounter, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "rotaryLimitJointGetMax", JSB_cpRotaryLimitJointGetMax, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "rotaryLimitJointGetMin", JSB_cpRotaryLimitJointGetMin, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "rotaryLimitJointNew", JSB_cpRotaryLimitJointNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "rotaryLimitJointSetMax", JSB_cpRotaryLimitJointSetMax, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "rotaryLimitJointSetMin", JSB_cpRotaryLimitJointSetMin, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "segmentShapeGetA", JSB_cpSegmentShapeGetA, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "segmentShapeGetB", JSB_cpSegmentShapeGetB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "segmentShapeGetNormal", JSB_cpSegmentShapeGetNormal, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "segmentShapeGetRadius", JSB_cpSegmentShapeGetRadius, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "segmentShapeNew", JSB_cpSegmentShapeNew, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "segmentShapeSetNeighbors", JSB_cpSegmentShapeSetNeighbors, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeCacheBB", JSB_cpShapeCacheBB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeDestroy", JSB_cpShapeDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeFree", JSB_cpShapeFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetBB", JSB_cpShapeGetBB, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetBody", JSB_cpShapeGetBody, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetCollisionType", JSB_cpShapeGetCollisionType, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetElasticity", JSB_cpShapeGetElasticity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetFriction", JSB_cpShapeGetFriction, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetGroup", JSB_cpShapeGetGroup, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetLayers", JSB_cpShapeGetLayers, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetSensor", JSB_cpShapeGetSensor, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetSpace", JSB_cpShapeGetSpace, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeGetSurfaceVelocity", JSB_cpShapeGetSurfaceVelocity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapePointQuery", JSB_cpShapePointQuery, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetBody", JSB_cpShapeSetBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetCollisionType", JSB_cpShapeSetCollisionType, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetElasticity", JSB_cpShapeSetElasticity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetFriction", JSB_cpShapeSetFriction, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetGroup", JSB_cpShapeSetGroup, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetLayers", JSB_cpShapeSetLayers, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetSensor", JSB_cpShapeSetSensor, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeSetSurfaceVelocity", JSB_cpShapeSetSurfaceVelocity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "shapeUpdate", JSB_cpShapeUpdate, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "simpleMotorGetRate", JSB_cpSimpleMotorGetRate, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "simpleMotorNew", JSB_cpSimpleMotorNew, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "simpleMotorSetRate", JSB_cpSimpleMotorSetRate, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointGetAnchr1", JSB_cpSlideJointGetAnchr1, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointGetAnchr2", JSB_cpSlideJointGetAnchr2, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointGetMax", JSB_cpSlideJointGetMax, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointGetMin", JSB_cpSlideJointGetMin, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointNew", JSB_cpSlideJointNew, 6, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointSetAnchr1", JSB_cpSlideJointSetAnchr1, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointSetAnchr2", JSB_cpSlideJointSetAnchr2, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointSetMax", JSB_cpSlideJointSetMax, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "slideJointSetMin", JSB_cpSlideJointSetMin, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceActivateShapesTouchingShape", JSB_cpSpaceActivateShapesTouchingShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceAddBody", JSB_cpSpaceAddBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceAddConstraint", JSB_cpSpaceAddConstraint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceAddShape", JSB_cpSpaceAddShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceAddStaticShape", JSB_cpSpaceAddStaticShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceContainsBody", JSB_cpSpaceContainsBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceContainsConstraint", JSB_cpSpaceContainsConstraint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceContainsShape", JSB_cpSpaceContainsShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceDestroy", JSB_cpSpaceDestroy, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceFree", JSB_cpSpaceFree, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetCollisionBias", JSB_cpSpaceGetCollisionBias, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetCollisionPersistence", JSB_cpSpaceGetCollisionPersistence, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetCollisionSlop", JSB_cpSpaceGetCollisionSlop, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetCurrentTimeStep", JSB_cpSpaceGetCurrentTimeStep, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetDamping", JSB_cpSpaceGetDamping, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetEnableContactGraph", JSB_cpSpaceGetEnableContactGraph, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetGravity", JSB_cpSpaceGetGravity, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetIdleSpeedThreshold", JSB_cpSpaceGetIdleSpeedThreshold, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetIterations", JSB_cpSpaceGetIterations, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetSleepTimeThreshold", JSB_cpSpaceGetSleepTimeThreshold, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceGetStaticBody", JSB_cpSpaceGetStaticBody, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceInit", JSB_cpSpaceInit, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceIsLocked", JSB_cpSpaceIsLocked, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceNew", JSB_cpSpaceNew, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spacePointQueryFirst", JSB_cpSpacePointQueryFirst, 4, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceReindexShape", JSB_cpSpaceReindexShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceReindexShapesForBody", JSB_cpSpaceReindexShapesForBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceReindexStatic", JSB_cpSpaceReindexStatic, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceRemoveBody", JSB_cpSpaceRemoveBody, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceRemoveConstraint", JSB_cpSpaceRemoveConstraint, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceRemoveShape", JSB_cpSpaceRemoveShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceRemoveStaticShape", JSB_cpSpaceRemoveStaticShape, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetCollisionBias", JSB_cpSpaceSetCollisionBias, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetCollisionPersistence", JSB_cpSpaceSetCollisionPersistence, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetCollisionSlop", JSB_cpSpaceSetCollisionSlop, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetDamping", JSB_cpSpaceSetDamping, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetEnableContactGraph", JSB_cpSpaceSetEnableContactGraph, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetGravity", JSB_cpSpaceSetGravity, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetIdleSpeedThreshold", JSB_cpSpaceSetIdleSpeedThreshold, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetIterations", JSB_cpSpaceSetIterations, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceSetSleepTimeThreshold", JSB_cpSpaceSetSleepTimeThreshold, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceStep", JSB_cpSpaceStep, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "spaceUseSpatialHash", JSB_cpSpaceUseSpatialHash, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "fabs", JSB_cpfabs, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "fclamp", JSB_cpfclamp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "fclamp01", JSB_cpfclamp01, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "flerp", JSB_cpflerp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "flerpconst", JSB_cpflerpconst, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "fmax", JSB_cpfmax, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "fmin", JSB_cpfmin, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vadd", JSB_cpvadd, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vclamp", JSB_cpvclamp, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vcross", JSB_cpvcross, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vdist", JSB_cpvdist, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vdistsq", JSB_cpvdistsq, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vdot", JSB_cpvdot, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "veql", JSB_cpveql, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vforangle", JSB_cpvforangle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vlength", JSB_cpvlength, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vlengthsq", JSB_cpvlengthsq, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vlerp", JSB_cpvlerp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vlerpconst", JSB_cpvlerpconst, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vmult", JSB_cpvmult, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vnear", JSB_cpvnear, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vneg", JSB_cpvneg, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vnormalize", JSB_cpvnormalize, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vnormalize_safe", JSB_cpvnormalize_safe, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vperp", JSB_cpvperp, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vproject", JSB_cpvproject, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vrotate", JSB_cpvrotate, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vrperp", JSB_cpvrperp, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vslerp", JSB_cpvslerp, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vslerpconst", JSB_cpvslerpconst, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vsub", JSB_cpvsub, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vtoangle", JSB_cpvtoangle, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); +JS_DefineFunction(cx, chipmunk, "vunrotate", JSB_cpvunrotate, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); #endif // JSB_INCLUDE_CHIPMUNK diff --git a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_manual.cpp b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_manual.cpp index 14a88c87bb..197a270e91 100644 --- a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_manual.cpp +++ b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_manual.cpp @@ -473,13 +473,13 @@ void JSPROXY_CCPhysicsSprite_createClass(JSContext *cx, JSObject* globalObj) void register_CCPhysicsSprite(JSContext *cx, JSObject *obj) { - jsval nsval; + JS::RootedValue nsval(cx); JSObject *ns; JS_GetProperty(cx, obj, "cc", &nsval); if (nsval == JSVAL_VOID) { ns = JS_NewObject(cx, NULL, NULL, NULL); nsval = OBJECT_TO_JSVAL(ns); - JS_SetProperty(cx, obj, "cc", &nsval); + JS_SetProperty(cx, obj, "cc", nsval); } else { JS_ValueToObject(cx, nsval, &ns); } @@ -488,13 +488,13 @@ void register_CCPhysicsSprite(JSContext *cx, JSObject *obj) { } void register_CCPhysicsDebugNode(JSContext *cx, JSObject *obj) { - jsval nsval; + JS::RootedValue nsval(cx); JSObject *ns; JS_GetProperty(cx, obj, "cc", &nsval); if (nsval == JSVAL_VOID) { ns = JS_NewObject(cx, NULL, NULL, NULL); nsval = OBJECT_TO_JSVAL(ns); - JS_SetProperty(cx, obj, "cc", &nsval); + JS_SetProperty(cx, obj, "cc", nsval); } else { JS_ValueToObject(cx, nsval, &ns); } @@ -509,7 +509,10 @@ JSBool jsval_to_cpBB( JSContext *cx, jsval vp, cpBB *ret ) JSB_PRECONDITION( ok, "Error converting value to object"); JSB_PRECONDITION( jsobj, "Not a valid JS object"); - jsval vall, valb, valr, valt; + JS::RootedValue vall(cx); + JS::RootedValue valb(cx); + JS::RootedValue valr(cx); + JS::RootedValue valt(cx); ok = JS_TRUE; ok &= JS_GetProperty(cx, jsobj, "l", &vall); ok &= JS_GetProperty(cx, jsobj, "b", &valb); diff --git a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_registration.cpp b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_registration.cpp index a96434eace..6a31f800e6 100644 --- a/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_registration.cpp +++ b/cocos/scripting/javascript/bindings/chipmunk/js_bindings_chipmunk_registration.cpp @@ -36,32 +36,34 @@ #include "js_bindings_chipmunk_manual.h" -void jsb_register_chipmunk(JSContext *_cx, JSObject *object) +void jsb_register_chipmunk(JSContext* cx, JSObject *object) { // // Chipmunk // - JSObject *chipmunk = JS_NewObject(_cx, NULL, NULL, NULL); - jsval chipmunkVal = OBJECT_TO_JSVAL(chipmunk); - JS_SetProperty(_cx, object, "cp", &chipmunkVal); + JSObject *chipmunk = JS_NewObject(cx, NULL, NULL, NULL); + JS::RootedValue chipmunkVal(cx); + + chipmunkVal = OBJECT_TO_JSVAL(chipmunk); + JS_SetProperty(cx, object, "cp", chipmunkVal); - JSB_cpBase_createClass(_cx, chipmunk, "Base"); // manual base class registration + JSB_cpBase_createClass(cx, chipmunk, "Base"); // manual base class registration #include "js_bindings_chipmunk_auto_classes_registration.h" #include "js_bindings_chipmunk_functions_registration.h" // manual - JS_DefineFunction(_cx, chipmunk, "spaceAddCollisionHandler", JSB_cpSpaceAddCollisionHandler, 8, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "spaceRemoveCollisionHandler", JSB_cpSpaceRemoveCollisionHandler, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "arbiterGetBodies", JSB_cpArbiterGetBodies, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "arbiterGetShapes", JSB_cpArbiterGetShapes, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "bodyGetUserData", JSB_cpBodyGetUserData, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "bodySetUserData", JSB_cpBodySetUserData, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "spaceAddCollisionHandler", JSB_cpSpaceAddCollisionHandler, 8, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "spaceRemoveCollisionHandler", JSB_cpSpaceRemoveCollisionHandler, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "arbiterGetBodies", JSB_cpArbiterGetBodies, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "arbiterGetShapes", JSB_cpArbiterGetShapes, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "bodyGetUserData", JSB_cpBodyGetUserData, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "bodySetUserData", JSB_cpBodySetUserData, 2, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "areaForPoly", JSB_cpAreaForPoly, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "momentForPoly", JSB_cpMomentForPoly, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "centroidForPoly", JSB_cpCentroidForPoly, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - JS_DefineFunction(_cx, chipmunk, "recenterPoly", JSB_cpRecenterPoly, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); - register_CCPhysicsSprite(_cx, object); - register_CCPhysicsDebugNode(_cx, object); + JS_DefineFunction(cx, chipmunk, "areaForPoly", JSB_cpAreaForPoly, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "momentForPoly", JSB_cpMomentForPoly, 3, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "centroidForPoly", JSB_cpCentroidForPoly, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + JS_DefineFunction(cx, chipmunk, "recenterPoly", JSB_cpRecenterPoly, 1, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ); + register_CCPhysicsSprite(cx, object); + register_CCPhysicsDebugNode(cx, object); } diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index 3237461ed0..4308bf2a80 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -d88cc721a9477ddfd6f690121991a620cbd260e6 \ No newline at end of file +8a34b565b95d3bdd2cf1dad5b70729544004a35d \ No newline at end of file diff --git a/cocos/scripting/javascript/bindings/cocosbuilder/js_bindings_ccbreader.cpp b/cocos/scripting/javascript/bindings/cocosbuilder/js_bindings_ccbreader.cpp index 733ac47b45..66f6819df3 100644 --- a/cocos/scripting/javascript/bindings/cocosbuilder/js_bindings_ccbreader.cpp +++ b/cocos/scripting/javascript/bindings/cocosbuilder/js_bindings_ccbreader.cpp @@ -303,13 +303,13 @@ extern JSObject* jsb_CCBReader_prototype; extern JSObject* jsb_CCBAnimationManager_prototype; void register_CCBuilderReader(JSContext *cx, JSObject *obj) { - jsval nsval; + JS::RootedValue nsval(cx); JSObject *ns; JS_GetProperty(cx, obj, "cc", &nsval); if (nsval == JSVAL_VOID) { ns = JS_NewObject(cx, NULL, NULL, NULL); nsval = OBJECT_TO_JSVAL(ns); - JS_SetProperty(cx, obj, "cc", &nsval); + JS_SetProperty(cx, obj, "cc", nsval); } else { JS_ValueToObject(cx, nsval, &ns); } diff --git a/cocos/scripting/javascript/bindings/cocosjs_manual_conversions.cpp b/cocos/scripting/javascript/bindings/cocosjs_manual_conversions.cpp index 22e075684c..56bd017069 100644 --- a/cocos/scripting/javascript/bindings/cocosjs_manual_conversions.cpp +++ b/cocos/scripting/javascript/bindings/cocosjs_manual_conversions.cpp @@ -18,7 +18,8 @@ JSBool jsval_to_CCPoint( JSContext *cx, jsval vp, Point *ret ) JSB_PRECONDITION( jsobj, "Not a valid JS object"); - jsval valx, valy; + JS::RootedValue valx(cx); + JS::RootedValue valy(cx); JSBool ok = JS_TRUE; ok &= JS_GetProperty(cx, jsobj, "x", &valx); ok &= JS_GetProperty(cx, jsobj, "y", &valy); @@ -65,7 +66,8 @@ JSBool jsval_to_CGPoint( JSContext *cx, jsval vp, cpVect *ret ) JSB_PRECONDITION( jsobj, "Not a valid JS object"); - jsval valx, valy; + JS::RootedValue valx(cx); + JS::RootedValue valy(cx); JSBool ok = JS_TRUE; ok &= JS_GetProperty(cx, jsobj, "x", &valx); ok &= JS_GetProperty(cx, jsobj, "y", &valy); diff --git a/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp b/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp index 9f2ab82470..e46bc688f8 100644 --- a/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp +++ b/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp @@ -322,12 +322,14 @@ private: js_proxy_t * p = jsb_get_native_proxy(table); if (!p) return false; + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); + JSBool hasAction; - jsval temp_retval; + JS::RootedValue temp_retval(cx); jsval dataVal = OBJECT_TO_JSVAL(p->obj); - JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* obj = _JSTableViewDataSource; + JSAutoCompartment ac(cx, obj); if (JS_HasProperty(cx, obj, jsFunctionName.c_str(), &hasAction) && hasAction) { @@ -340,7 +342,6 @@ private: return false; } - JSAutoCompartment ac(cx, obj); JS_CallFunctionName(cx, obj, jsFunctionName.c_str(), 1, &dataVal, &retVal); return true; @@ -353,15 +354,15 @@ private: js_proxy_t * p = jsb_get_native_proxy(table); if (!p) return false; - + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSBool hasAction; - jsval temp_retval; + JS::RootedValue temp_retval(cx); jsval dataVal[2]; dataVal[0] = OBJECT_TO_JSVAL(p->obj); dataVal[1] = INT_TO_JSVAL(idx); - JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* obj = _JSTableViewDataSource; + JSAutoCompartment ac(cx, obj); if (JS_HasProperty(cx, obj, jsFunctionName.c_str(), &hasAction) && hasAction) { @@ -375,7 +376,6 @@ private: return false; } - JSAutoCompartment ac(cx, obj); JS_CallFunctionName(cx, obj, jsFunctionName.c_str(), 2, dataVal, &retVal); return true; diff --git a/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp b/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp index dfde6ba278..6b08243875 100644 --- a/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp +++ b/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp @@ -13,11 +13,12 @@ void GLNode::draw() { JSB_ENSURE_AUTOCOMPARTMENT(cx, jsObj); JS_HasProperty(cx, jsObj, "draw", &found); if (found == JS_TRUE) { - jsval rval, fval; - jsval *argv = NULL; unsigned argc=0; - - JS_GetProperty(cx, jsObj, "draw", &fval); - JS_CallFunctionValue(cx, jsObj, fval, argc, argv, &rval); + JS::RootedValue rval(cx); + JS::RootedValue fval(cx); + jsval *argv = NULL; unsigned argc=0; + + JS_GetProperty(cx, jsObj, "draw", &fval); + JS_CallFunctionValue(cx, jsObj, fval, argc, argv, rval.address()); } } } diff --git a/cocos/scripting/javascript/bindings/jsb_helper.h b/cocos/scripting/javascript/bindings/jsb_helper.h index 4ffa7c3d4c..664d7f4f28 100644 --- a/cocos/scripting/javascript/bindings/jsb_helper.h +++ b/cocos/scripting/javascript/bindings/jsb_helper.h @@ -53,10 +53,10 @@ out = OBJECT_TO_JSVAL(obj); \ JS_FN(#name, klass##_func_##name, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT) #define JS_BINDED_PROP_GET(klass, propName) \ -JSBool _js_get_##propName(JSContext *cx, JSHandleId id, JSMutableHandleValue vp) +JSBool _js_get_##propName(JSContext *cx, JS::HandleId id, JS::MutableHandleValue vp) #define JS_BINDED_PROP_GET_IMPL(klass, propName) \ -static JSBool _js_get_##klass##_##propName(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp) { \ +static JSBool _js_get_##klass##_##propName(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { \ klass* cobj = (klass*)JS_GetPrivate(obj); \ if (cobj) { \ return cobj->_js_get_##propName(cx, id, vp); \ @@ -64,13 +64,13 @@ return cobj->_js_get_##propName(cx, id, vp); \ JS_ReportError(cx, "Invalid getter call for property %s", #propName); \ return JS_FALSE; \ } \ -JSBool klass::_js_get_##propName(JSContext *cx, JSHandleId id, JSMutableHandleValue vp) +JSBool klass::_js_get_##propName(JSContext *cx, JS::HandleId id, JS::MutableHandleValue vp) #define JS_BINDED_PROP_SET(klass, propName) \ -JSBool _js_set_##propName(JSContext *cx, JSHandleId id, JSBool strict, JSMutableHandleValue vp) +JSBool _js_set_##propName(JSContext *cx, JS::HandleId id, JSBool strict, JS::MutableHandleValue vp) #define JS_BINDED_PROP_SET_IMPL(klass, propName) \ -static JSBool _js_set_##klass##_##propName(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp) { \ +static JSBool _js_set_##klass##_##propName(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JSBool strict, JS::MutableHandleValue vp) { \ klass* cobj = (klass*)JS_GetPrivate(obj); \ if (cobj) { \ return cobj->_js_set_##propName(cx, id, strict, vp); \ @@ -78,7 +78,7 @@ return cobj->_js_set_##propName(cx, id, strict, vp); \ JS_ReportError(cx, "Invalid setter call for property %s", #propName); \ return JS_FALSE; \ } \ -JSBool klass::_js_set_##propName(JSContext *cx, JSHandleId id, JSBool strict, JSMutableHandleValue vp) +JSBool klass::_js_set_##propName(JSContext *cx, JS::HandleId id, JSBool strict, JS::MutableHandleValue vp) #define JS_BINDED_PROP_ACCESSOR(klass, propName) \ JS_BINDED_PROP_GET(klass, propName); \ diff --git a/cocos/scripting/javascript/bindings/jsb_opengl_registration.cpp b/cocos/scripting/javascript/bindings/jsb_opengl_registration.cpp index 434737f24b..ad3fee9a24 100644 --- a/cocos/scripting/javascript/bindings/jsb_opengl_registration.cpp +++ b/cocos/scripting/javascript/bindings/jsb_opengl_registration.cpp @@ -39,16 +39,18 @@ void JSB_register_opengl(JSContext *_cx, JSObject *object) // gl // JSObject *opengl = JS_NewObject(_cx, NULL, NULL, NULL); - jsval openglVal = OBJECT_TO_JSVAL(opengl); - JS_SetProperty(_cx, object, "gl", &openglVal); + + JS::RootedValue openglVal(_cx); + openglVal = OBJECT_TO_JSVAL(opengl); + JS_SetProperty(_cx, object, "gl", openglVal); - jsval nsval; + JS::RootedValue nsval(_cx); JSObject *ccns; JS_GetProperty(_cx, object, "cc", &nsval); if (nsval == JSVAL_VOID) { ccns = JS_NewObject(_cx, NULL, NULL, NULL); nsval = OBJECT_TO_JSVAL(ccns); - JS_SetProperty(_cx, object, "cc", &nsval); + JS_SetProperty(_cx, object, "cc", nsval); } else { JS_ValueToObject(_cx, nsval, &ccns); } diff --git a/cocos/scripting/javascript/bindings/localstorage/js_bindings_system_registration.cpp b/cocos/scripting/javascript/bindings/localstorage/js_bindings_system_registration.cpp index bf55e188f0..785b869e39 100644 --- a/cocos/scripting/javascript/bindings/localstorage/js_bindings_system_registration.cpp +++ b/cocos/scripting/javascript/bindings/localstorage/js_bindings_system_registration.cpp @@ -37,14 +37,16 @@ void jsb_register_system( JSContext *_cx, JSObject *object) // sys // JSObject *sys = JS_NewObject(_cx, NULL, NULL, NULL); - jsval systemVal = OBJECT_TO_JSVAL(sys); - JS_SetProperty(_cx, object, "sys", &systemVal); + JS::RootedValue systemVal(_cx); + systemVal = OBJECT_TO_JSVAL(sys); + JS_SetProperty(_cx, object, "sys", systemVal); // sys.localStorage JSObject *ls = JS_NewObject(_cx, NULL, NULL, NULL); - jsval lsVal = OBJECT_TO_JSVAL(ls); - JS_SetProperty(_cx, sys, "localStorage", &lsVal); + JS::RootedValue lsVal(_cx); + lsVal = OBJECT_TO_JSVAL(ls); + JS_SetProperty(_cx, sys, "localStorage", lsVal); // sys.localStorage functions JSObject *system = ls; diff --git a/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp b/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp index cc7b72c586..1879b5417d 100644 --- a/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp +++ b/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp @@ -327,8 +327,9 @@ JS_BINDED_PROP_GET_IMPL(MinXmlHttpRequest, onreadystatechange) if (_onreadystateCallback) { JSString *tmpstr = JS_NewStringCopyZ(cx, "1"); - jsval tmpval = STRING_TO_JSVAL(tmpstr); - JS_SetProperty(cx, _onreadystateCallback, "readyState", &tmpval); + JS::RootedValue tmpval(cx); + tmpval = STRING_TO_JSVAL(tmpstr); + JS_SetProperty(cx, _onreadystateCallback, "readyState", tmpval); jsval out = OBJECT_TO_JSVAL(_onreadystateCallback); vp.set(out); @@ -563,7 +564,7 @@ JS_BINDED_PROP_GET_IMPL(MinXmlHttpRequest, response) if (_responseType == ResponseType::JSON) { - jsval outVal; + JS::RootedValue outVal(cx); jsval strVal = std_string_to_jsval(cx, _data.str()); if (JS_ParseJSON(cx, JS_GetStringCharsZ(cx, JSVAL_TO_STRING(strVal)), _dataSize, &outVal)) diff --git a/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp b/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp index b5083ad268..8497cd35e3 100644 --- a/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp +++ b/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp @@ -69,8 +69,9 @@ public: JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); - jsval vp = c_string_to_jsval(cx, "open"); - JS_SetProperty(cx, jsobj, "type", &vp); + JS::RootedValue vp(cx); + vp = c_string_to_jsval(cx, "open"); + JS_SetProperty(cx, jsobj, "type", vp); jsval args = OBJECT_TO_JSVAL(jsobj); @@ -84,8 +85,9 @@ public: JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); - jsval vp = c_string_to_jsval(cx, "message"); - JS_SetProperty(cx, jsobj, "type", &vp); + JS::RootedValue vp(cx); + vp = c_string_to_jsval(cx, "message"); + JS_SetProperty(cx, jsobj, "type", vp); jsval args = OBJECT_TO_JSVAL(jsobj); @@ -94,13 +96,15 @@ public: JSObject* buffer = JS_NewArrayBuffer(cx, data.len); uint8_t* bufdata = JS_GetArrayBufferData(buffer); memcpy((void*)bufdata, (void*)data.bytes, data.len); - jsval dataVal = OBJECT_TO_JSVAL(buffer); - JS_SetProperty(cx, jsobj, "data", &dataVal); + JS::RootedValue dataVal(cx); + dataVal = OBJECT_TO_JSVAL(buffer); + JS_SetProperty(cx, jsobj, "data", dataVal); } else {// data is string - jsval dataVal = c_string_to_jsval(cx, data.bytes); - JS_SetProperty(cx, jsobj, "data", &dataVal); + JS::RootedValue dataVal(cx); + dataVal = c_string_to_jsval(cx, data.bytes); + JS_SetProperty(cx, jsobj, "data", dataVal); } ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate), "onmessage", 1, &args); @@ -113,8 +117,9 @@ public: JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); - jsval vp = c_string_to_jsval(cx, "close"); - JS_SetProperty(cx, jsobj, "type", &vp); + JS::RootedValue vp(cx); + vp = c_string_to_jsval(cx, "close"); + JS_SetProperty(cx, jsobj, "type", vp); jsval args = OBJECT_TO_JSVAL(jsobj); ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate), "onclose", 1, &args); @@ -132,8 +137,9 @@ public: JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); - jsval vp = c_string_to_jsval(cx, "error"); - JS_SetProperty(cx, jsobj, "type", &vp); + JS::RootedValue vp(cx); + vp = c_string_to_jsval(cx, "error"); + JS_SetProperty(cx, jsobj, "type", vp); jsval args = OBJECT_TO_JSVAL(jsobj); @@ -308,7 +314,7 @@ JSBool js_cocos2dx_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, return JS_FALSE; } -static JSBool js_cocos2dx_extension_WebSocket_get_readyState(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp) +static JSBool js_cocos2dx_extension_WebSocket_get_readyState(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { JSObject* jsobj = obj.get(); js_proxy_t *proxy = jsb_get_js_proxy(jsobj); From d1b88b0a7877c0349689d0b024b961267499ab92 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 30 Oct 2013 22:08:28 +0800 Subject: [PATCH 083/144] [sp v25] Updating auto-generated and bindings-generated submodules. --- cocos/scripting/auto-generated | 2 +- tools/bindings-generator | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index 4fd4e14912..c1da46eabb 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit 4fd4e14912165a2c8a5a6faacda2626035af6f36 +Subproject commit c1da46eabb46727a66daa4d64d9841b09fa6d63c diff --git a/tools/bindings-generator b/tools/bindings-generator index 0c5ff684fb..b6f97d9fc2 160000 --- a/tools/bindings-generator +++ b/tools/bindings-generator @@ -1 +1 @@ -Subproject commit 0c5ff684fb8176f4da5313dbb9d35e112f99cd39 +Subproject commit b6f97d9fc2d3450426423583c7a6aaf4a366a99d From a81998ccf6fed3fc36b3d93d259c49e778ee5aa5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 10:20:45 +0800 Subject: [PATCH 084/144] [sp v25] Debugger script, loading file is ok. --- .../javascript/script/debugger/actors/root.js | 29 +- .../script/debugger/actors/script.js | 2948 ----------------- .../debugger/actors/script.js.REMOVED.git-id | 1 + .../javascript/script/debugger/main.js | 213 +- .../javascript/script/debugger/transport.js | 68 +- 5 files changed, 249 insertions(+), 3010 deletions(-) delete mode 100644 cocos/scripting/javascript/script/debugger/actors/script.js create mode 100644 cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id diff --git a/cocos/scripting/javascript/script/debugger/actors/root.js b/cocos/scripting/javascript/script/debugger/actors/root.js index aa0d85342b..93fc857c0b 100644 --- a/cocos/scripting/javascript/script/debugger/actors/root.js +++ b/cocos/scripting/javascript/script/debugger/actors/root.js @@ -164,7 +164,7 @@ RootActor.prototype = { */ sayHello: function() { return { - from: "root", + from: this.actorID, applicationType: this.applicationType, /* This is not in the spec, but it's used by tests. */ testConnectionPrefix: this.conn.prefix, @@ -174,6 +174,16 @@ RootActor.prototype = { }; }, + /** + * This is true for the root actor only, used by some child actors + */ + get isRootActor() true, + + /** + * The (chrome) window, for use by child actors + */ + get window() Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType), + /** * Disconnects the actor from the browser window. */ @@ -195,10 +205,9 @@ RootActor.prototype = { * the next listTabs request. */ onListTabs: function() { - let tabList = this._parameters.tabList; if (!tabList) { - return { from: "root", error: "noTabs", + return { from: this.actorID, error: "noTabs", message: "This root actor has no browser tabs." }; } @@ -235,9 +244,9 @@ RootActor.prototype = { this.conn.addActorPool(this._tabActorPool); let reply = { - "from": "root", + "from": this.actorID, "selected": selected || 0, - "tabs": [actor.grip() for (actor of tabActorList)] + "tabs": [actor.grip() for (actor of tabActorList)], }; /* DebuggerServer.addGlobalActor support: name actors in 'listTabs' reply. */ @@ -254,13 +263,19 @@ RootActor.prototype = { }, onTabListChanged: function () { - this.conn.send({ from:"root", type:"tabListChanged" }); + this.conn.send({ from: this.actorID, type:"tabListChanged" }); /* It's a one-shot notification; no need to watch any more. */ this._parameters.tabList.onListChanged = null; }, /* This is not in the spec, but it's used by tests. */ - onEcho: (aRequest) => aRequest, + onEcho: function (aRequest) { + /* + * Request packets are frozen. Copy aRequest, so that + * DebuggerServerConnection.onPacket can attach a 'from' property. + */ + return JSON.parse(JSON.stringify(aRequest)); + }, /* Support for DebuggerServer.addGlobalActor. */ _createExtraActors: CommonCreateExtraActors, diff --git a/cocos/scripting/javascript/script/debugger/actors/script.js b/cocos/scripting/javascript/script/debugger/actors/script.js deleted file mode 100644 index 7ddade2b54..0000000000 --- a/cocos/scripting/javascript/script/debugger/actors/script.js +++ /dev/null @@ -1,2948 +0,0 @@ -/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; js-indent-level: 2; -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -/** - * JSD2 actors. - */ -/** - * Creates a ThreadActor. - * - * ThreadActors manage a JSInspector object and manage execution/inspection - * of debuggees. - * - * @param aHooks object - * An object with preNest and postNest methods for calling when entering - * and exiting a nested event loop, addToParentPool and - * removeFromParentPool methods for handling the lifetime of actors that - * will outlive the thread, like breakpoints. - * @param aGlobal object [optional] - * An optional (for content debugging only) reference to the content - * window. - */ -function ThreadActor(aHooks, aGlobal) -{ - this._state = "detached"; - this._frameActors = []; - this._environmentActors = []; - this._hooks = aHooks; - this.global = aGlobal; - - this.findGlobals = this.globalManager.findGlobals.bind(this); - this.onNewGlobal = this.globalManager.onNewGlobal.bind(this); - this.onNewSource = this.onNewSource.bind(this); - - this._options = { - useSourceMaps: false - }; -} - -/** - * The breakpoint store must be shared across instances of ThreadActor so that - * page reloads don't blow away all of our breakpoints. - */ -ThreadActor._breakpointStore = {}; - -ThreadActor.prototype = { - actorPrefix: "context", - - get state() { return this._state; }, - get attached() this.state == "attached" || - this.state == "running" || - this.state == "paused", - - get _breakpointStore() { return ThreadActor._breakpointStore; }, - - get threadLifetimePool() { - if (!this._threadLifetimePool) { - this._threadLifetimePool = new ActorPool(this.conn); - this.conn.addActorPool(this._threadLifetimePool); - this._threadLifetimePool.objectActors = new WeakMap(); - } - return this._threadLifetimePool; - }, - - get sources() { - if (!this._sources) { - this._sources = new ThreadSources(this, this._options.useSourceMaps, - this._allowSource, this.onNewSource); - } - return this._sources; - }, - - clearDebuggees: function TA_clearDebuggees() { - if (this.dbg) { - this.dbg.removeAllDebuggees(); - } - this.conn.removeActorPool(this._threadLifetimePool || undefined); - this._threadLifetimePool = null; - this._sources = null; - }, - - /** - * Add a debuggee global to the Debugger object. - */ - addDebuggee: function TA_addDebuggee(aGlobal) { - try { - this.dbg.addDebuggee(aGlobal); - } catch (e) { - // Ignore attempts to add the debugger's compartment as a debuggee. - dumpn("Ignoring request to add the debugger's compartment as a debuggee"); - } - }, - - /** - * Initialize the Debugger. - */ - _initDebugger: function TA__initDebugger() { - this.dbg = new Debugger(); - this.dbg.uncaughtExceptionHook = this.uncaughtExceptionHook.bind(this); - this.dbg.onDebuggerStatement = this.onDebuggerStatement.bind(this); - this.dbg.onNewScript = this.onNewScript.bind(this); - this.dbg.onNewGlobalObject = this.globalManager.onNewGlobal.bind(this); - // Keep the debugger disabled until a client attaches. - this.dbg.enabled = this._state != "detached"; - }, - - /** - * Remove a debuggee global from the JSInspector. - */ - removeDebugee: function TA_removeDebuggee(aGlobal) { - try { - this.dbg.removeDebuggee(aGlobal); - } catch(ex) { - // XXX: This debuggee has code currently executing on the stack, - // we need to save this for later. - } - }, - - /** - * Add the provided window and all windows in its frame tree as debuggees. - */ - _addDebuggees: function TA__addDebuggees(aWindow) { - this.addDebuggee(aWindow); - let frames = aWindow.frames; - if (frames) { - for (let i = 0; i < frames.length; i++) { - this._addDebuggees(frames[i]); - } - } - }, - - /** - * An object that will be used by ThreadActors to tailor their behavior - * depending on the debugging context being required (chrome or content). - */ - globalManager: { - findGlobals: function TA_findGlobals() { - this._addDebuggees(this.global); - }, - - /** - * A function that the engine calls when a new global object has been - * created. - * - * @param aGlobal Debugger.Object - * The new global object that was created. - */ - onNewGlobal: function TA_onNewGlobal(aGlobal) { - // Content debugging only cares about new globals in the contant window, - // like iframe children. - if (aGlobal.hostAnnotations && - aGlobal.hostAnnotations.type == "document" && - aGlobal.hostAnnotations.element === this.global) { - this.addDebuggee(aGlobal); - // Notify the client. - this.conn.send({ - from: this.actorID, - type: "newGlobal", - // TODO: after bug 801084 lands see if we need to JSONify this. - hostAnnotations: aGlobal.hostAnnotations - }); - } - } - }, - - disconnect: function TA_disconnect() { - dumpn("in ThreadActor.prototype.disconnect"); - if (this._state == "paused") { - this.onResume(); - } - - this._state = "exited"; - - this.clearDebuggees(); - - if (!this.dbg) { - return; - } - this.dbg.enabled = false; - this.dbg = null; - }, - - /** - * Disconnect the debugger and put the actor in the exited state. - */ - exit: function TA_exit() { - this.disconnect(); - }, - - // Request handlers - onAttach: function TA_onAttach(aRequest) { - if (this.state === "exited") { - return { type: "exited" }; - } - - if (this.state !== "detached") { - return { error: "wrongState" }; - } - - this._state = "attached"; - - update(this._options, aRequest.options || {}); - - if (!this.dbg) { - this._initDebugger(); - } - this.findGlobals(); - this.dbg.enabled = true; - try { - // Put ourselves in the paused state. - let packet = this._paused(); - if (!packet) { - return { error: "notAttached" }; - } - packet.why = { type: "attached" }; - - this._restoreBreakpoints(); - - // Send the response to the attach request now (rather than - // returning it), because we're going to start a nested event loop - // here. - this.conn.send(packet); - - // Start a nested event loop. - this._nest(); - - // We already sent a response to this request, don't send one - // now. - return null; - } catch (e) { - reportError(e); - return { error: "notAttached", message: e.toString() }; - } - }, - - onDetach: function TA_onDetach(aRequest) { - this.disconnect(); - dumpn("ThreadActor.prototype.onDetach: returning 'detached' packet"); - return { - type: "detached" - }; - }, - - onReconfigure: function TA_onReconfigure(aRequest) { - if (this.state == "exited") { - return { error: "wrongState" }; - } - - update(this._options, aRequest.options || {}); - // Clear existing sources, so they can be recreated on next access. - this._sources = null; - - return {}; - }, - - /** - * Pause the debuggee, by entering a nested event loop, and return a 'paused' - * packet to the client. - * - * @param Debugger.Frame aFrame - * The newest debuggee frame in the stack. - * @param object aReason - * An object with a 'type' property containing the reason for the pause. - * @param function onPacket - * Hook to modify the packet before it is sent. Feel free to return a - * promise. - */ - _pauseAndRespond: function TA__pauseAndRespond(aFrame, aReason, - onPacket=function (k) k) { - try { - let packet = this._paused(aFrame); - if (!packet) { - return undefined; - } - packet.why = aReason; - resolve(onPacket(packet)).then(this.conn.send.bind(this.conn)); - return this._nest(); - } catch(e) { - let msg = "Got an exception during TA__pauseAndRespond: " + e + - ": " + e.stack; - // Cu.reportError(msg); - dumpn(msg); - return undefined; - } - }, - - /** - * Handle a protocol request to resume execution of the debuggee. - */ - onResume: function TA_onResume(aRequest) { - if (this._state !== "paused") { - return { - error: "wrongState", - message: "Can't resume when debuggee isn't paused. Current state is '" - + this._state + "'" - }; - } - - // In case of multiple nested event loops (due to multiple debuggers open in - // different tabs or multiple debugger clients connected to the same tab) - // only allow resumption in a LIFO order. - if (DebuggerServer.xpcInspector.eventLoopNestLevel() > 1) { - log("DebuggerServer.xpcInspector.eventLoopNestLevel: "+DebuggerServer.xpcInspector.eventLoopNestLevel()); - // let lastNestRequestor = DebuggerServer.xpcInspector.lastNestRequestor; - // if (lastNestRequestor.connection != this.conn) { - // return { error: "wrongOrder", - // message: "trying to resume in the wrong order.", - // lastPausedUrl: lastNestRequestor.url }; - // } - } - - if (aRequest && aRequest.forceCompletion) { - // TODO: remove this when Debugger.Frame.prototype.pop is implemented in - // bug 736733. - if (typeof this.frame.pop != "function") { - return { error: "notImplemented", - message: "forced completion is not yet implemented." }; - } - - this.dbg.getNewestFrame().pop(aRequest.completionValue); - let packet = this._resumed(); - DebuggerServer.xpcInspector.exitNestedEventLoop(); - return { type: "resumeLimit", frameFinished: aRequest.forceCompletion }; - } - - if (aRequest && aRequest.resumeLimit) { - log("resumeLimit..."); - // Bind these methods because some of the hooks are called with 'this' - // set to the current frame. - let pauseAndRespond = (aFrame, onPacket=function (k) k) => { - this._pauseAndRespond(aFrame, { type: "resumeLimit" }, onPacket); - }; - let createValueGrip = this.createValueGrip.bind(this); - - let startFrame = this.youngestFrame; - let startLine; - if (this.youngestFrame.script) { - let offset = this.youngestFrame.offset; - startLine = this.youngestFrame.script.getOffsetLine(offset); - } - - // Define the JS hook functions for stepping. - - let onEnterFrame = aFrame => { - if (this.sources.isBlackBoxed(aFrame.script.url)) { - return undefined; - } - return pauseAndRespond(aFrame); - }; - - let thread = this; - - let onPop = function TA_onPop(aCompletion) { - // onPop is called with 'this' set to the current frame. - if (thread.sources.isBlackBoxed(this.script.url)) { - return undefined; - } - - // Note that we're popping this frame; we need to watch for - // subsequent step events on its caller. - this.reportedPop = true; - - return pauseAndRespond(this, (aPacket) => { - aPacket.why.frameFinished = {}; - if (!aCompletion) { - aPacket.why.frameFinished.terminated = true; - } else if (aCompletion.hasOwnProperty("return")) { - aPacket.why.frameFinished.return = createValueGrip(aCompletion.return); - } else if (aCompletion.hasOwnProperty("yield")) { - aPacket.why.frameFinished.return = createValueGrip(aCompletion.yield); - } else { - aPacket.why.frameFinished.throw = createValueGrip(aCompletion.throw); - } - return aPacket; - }); - }; - - let onStep = function TA_onStep() { - // onStep is called with 'this' set to the current frame. - - if (thread.sources.isBlackBoxed(this.script.url)) { - return undefined; - } - - // If we've changed frame or line, then report that. - if (this !== startFrame || - (this.script && - this.script.getOffsetLine(this.offset) != startLine)) { - return pauseAndRespond(this); - } - - // Otherwise, let execution continue. - return undefined; - }; - - let steppingType = aRequest.resumeLimit.type; - if (["step", "next", "finish"].indexOf(steppingType) == -1) { - return { error: "badParameterType", - message: "Unknown resumeLimit type" }; - } - // Make sure there is still a frame on the stack if we are to continue - // stepping. - let stepFrame = this._getNextStepFrame(startFrame); - if (stepFrame) { - switch (steppingType) { - case "step": - log("--> step..."); - this.dbg.onEnterFrame = onEnterFrame; - // Fall through. - case "next": - log("--> next..."); - stepFrame.onStep = onStep; - stepFrame.onPop = onPop; - break; - case "finish": - log("--> finish..."); - stepFrame.onPop = onPop; - } - } - - } - - if (aRequest && aRequest.pauseOnExceptions) { - this.dbg.onExceptionUnwind = this.onExceptionUnwind.bind(this); - } - let packet = this._resumed(); - DebuggerServer.xpcInspector.exitNestedEventLoop(); - return packet; - }, - - /** - * Helper method that returns the next frame when stepping. - */ - _getNextStepFrame: function TA__getNextStepFrame(aFrame) { - let stepFrame = aFrame.reportedPop ? aFrame.older : aFrame; - if (!stepFrame || !stepFrame.script) { - stepFrame = null; - } - return stepFrame; - }, - - onClientEvaluate: function TA_onClientEvaluate(aRequest) { - if (this.state !== "paused") { - return { error: "wrongState", - message: "Debuggee must be paused to evaluate code." }; - }; - - let frame = this._requestFrame(aRequest.frame); - if (!frame) { - return { error: "unknownFrame", - message: "Evaluation frame not found" }; - } - - if (!frame.environment) { - return { error: "notDebuggee", - message: "cannot access the environment of this frame." }; - }; - - // We'll clobber the youngest frame if the eval causes a pause, so - // save our frame now to be restored after eval returns. - // XXX: or we could just start using dbg.getNewestFrame() now that it - // works as expected. - let youngest = this.youngestFrame; - - // Put ourselves back in the running state and inform the client. - let resumedPacket = this._resumed(); - this.conn.send(resumedPacket); - - // Run the expression. - // XXX: test syntax errors - let completion = frame.eval(aRequest.expression); - - // Put ourselves back in the pause state. - let packet = this._paused(youngest); - packet.why = { type: "clientEvaluated", - frameFinished: this.createProtocolCompletionValue(completion) }; - - // Return back to our previous pause's event loop. - return packet; - }, - - onFrames: function TA_onFrames(aRequest) { - if (this.state !== "paused") { - return { error: "wrongState", - message: "Stack frames are only available while the debuggee is paused."}; - } - - let start = aRequest.start ? aRequest.start : 0; - let count = aRequest.count; - - // Find the starting frame... - let frame = this.youngestFrame; - let i = 0; - while (frame && (i < start)) { - frame = frame.older; - i++; - } - - // Return request.count frames, or all remaining - // frames if count is not defined. - let frames = []; - let promises = []; - for (; frame && (!count || i < (start + count)); i++, frame=frame.older) { - let form = this._createFrameActor(frame).form(); - form.depth = i; - frames.push(form); - - let promise = this.sources.getOriginalLocation(form.where.url, - form.where.line) - .then(function (aOrigLocation) { - form.where = aOrigLocation; - }); - promises.push(promise); - } - - return all(promises).then(function () { - return { frames: frames }; - }); - }, - - onReleaseMany: function TA_onReleaseMany(aRequest) { - if (!aRequest.actors) { - return { error: "missingParameter", - message: "no actors were specified" }; - } - - let res; - for each (let actorID in aRequest.actors) { - let actor = this.threadLifetimePool.get(actorID); - if (!actor) { - if (!res) { - res = { error: "notReleasable", - message: "Only thread-lifetime actors can be released." }; - } - continue; - } - actor.onRelease(); - } - return res ? res : {}; - }, - - /** - * Handle a protocol request to set a breakpoint. - */ - onSetBreakpoint: function TA_onSetBreakpoint(aRequest) { - if (this.state !== "paused") { - return { error: "wrongState", - message: "Breakpoints can only be set while the debuggee is paused."}; - } - - // XXX: `originalColumn` is never used. See bug 827639. - let { url: originalSource, - line: originalLine, - column: originalColumn } = aRequest.location; - - let locationPromise = this.sources.getGeneratedLocation(originalSource, - originalLine) - return locationPromise.then((aLocation) => { - let line = aLocation.line; - if (this.dbg.findScripts({ url: aLocation.url }).length == 0 || - line < 0 || - line == null) { - return { error: "noScript" }; - } - - // Add the breakpoint to the store for later reuse, in case it belongs to a - // script that hasn't appeared yet. - if (!this._breakpointStore[aLocation.url]) { - this._breakpointStore[aLocation.url] = []; - } - let scriptBreakpoints = this._breakpointStore[aLocation.url]; - scriptBreakpoints[line] = { - url: aLocation.url, - line: line, - column: aLocation.column - }; - - let response = this._setBreakpoint(aLocation); - // If the original location of our generated location is different from - // the original location we attempted to set the breakpoint on, we will - // need to know so that we can set actualLocation on the response. - let originalLocation = this.sources.getOriginalLocation(aLocation.url, - aLocation.line); - - return all([response, originalLocation]) - .then(([aResponse, {url, line}]) => { - if (aResponse.actualLocation) { - let actualOrigLocation = this.sources.getOriginalLocation( - aResponse.actualLocation.url, aResponse.actualLocation.line); - return actualOrigLocation.then(function ({ url, line }) { - if (url !== originalSource || line !== originalLine) { - aResponse.actualLocation = { url: url, line: line }; - } - return aResponse; - }); - } - - if (url !== originalSource || line !== originalLine) { - aResponse.actualLocation = { url: url, line: line }; - } - - return aResponse; - }); - }); - }, - - /** - * Set a breakpoint using the jsdbg2 API. If the line on which the breakpoint - * is being set contains no code, then the breakpoint will slide down to the - * next line that has runnable code. In this case the server breakpoint cache - * will be updated, so callers that iterate over the breakpoint cache should - * take that into account. - * - * @param object aLocation - * The location of the breakpoint as specified in the protocol. - */ - _setBreakpoint: function TA__setBreakpoint(aLocation) { - let breakpoints = this._breakpointStore[aLocation.url]; - - // Get or create the breakpoint actor for the given location - let actor; - if (breakpoints[aLocation.line].actor) { - actor = breakpoints[aLocation.line].actor; - } else { - actor = breakpoints[aLocation.line].actor = new BreakpointActor(this, { - url: aLocation.url, - line: aLocation.line - }); - this._hooks.addToParentPool(actor); - } - - // Find all scripts matching the given location - let scripts = this.dbg.findScripts(aLocation); - if (scripts.length == 0) { - return { - error: "noScript", - actor: actor.actorID - }; - } - - /** - * For each script, if the given line has at least one entry point, set - * breakpoint on the bytecode offet for each of them. - */ - let found = false; - for (let script of scripts) { - let offsets = script.getLineOffsets(aLocation.line); - if (offsets.length > 0) { - for (let offset of offsets) { - script.setBreakpoint(offset, actor); - } - actor.addScript(script, this); - found = true; - } - } - if (found) { - return { - actor: actor.actorID - }; - } - - /** - * If we get here, no breakpoint was set. This is because the given line - * has no entry points, for example because it is empty. As a fallback - * strategy, we try to set the breakpoint on the smallest line greater - * than or equal to the given line that as at least one entry point. - */ - - // Find all innermost scripts matching the given location - let scripts = this.dbg.findScripts({ - url: aLocation.url, - line: aLocation.line, - innermost: true - }); - - /** - * For each innermost script, look for the smallest line greater than or - * equal to the given line that has one or more entry points. If found, set - * a breakpoint on the bytecode offset for each of its entry points. - */ - let actualLocation; - let found = false; - for (let script of scripts) { - let offsets = script.getAllOffsets(); - for (let line = aLocation.line; line < offsets.length; ++line) { - if (offsets[line]) { - for (let offset of offsets[line]) { - script.setBreakpoint(offset, actor); - } - actor.addScript(script, this); - if (!actualLocation) { - actualLocation = { - url: aLocation.url, - line: line, - column: 0 - }; - } - found = true; - break; - } - } - } - if (found) { - if (breakpoints[actualLocation.line] && - breakpoints[actualLocation.line].actor) { - /** - * We already have a breakpoint actor for the actual location, so - * actor we created earlier is now redundant. Delete it, update the - * breakpoint store, and return the actor for the actual location. - */ - actor.onDelete(); - delete breakpoints[aLocation.line]; - return { - actor: breakpoints[actualLocation.line].actor.actorID, - actualLocation: actualLocation - }; - } else { - /** - * We don't have a breakpoint actor for the actual location yet. - * Instead or creating a new actor, reuse the actor we created earlier, - * and update the breakpoint store. - */ - actor.location = actualLocation; - breakpoints[actualLocation.line] = breakpoints[aLocation.line]; - delete breakpoints[aLocation.line]; - // WARNING: This overwrites aLocation.line - breakpoints[actualLocation.line].line = actualLocation.line; - return { - actor: actor.actorID, - actualLocation: actualLocation - }; - } - } - - /** - * If we get here, no line matching the given line was found, so just - * epically. - */ - return { - error: "noCodeAtLineColumn", - actor: actor.actorID - }; - }, - - /** - * Get the script and source lists from the debugger. - * - * TODO bug 637572: we should be dealing with sources directly, not inferring - * them through scripts. - */ - _discoverSources: function TA__discoverSources() { - // Only get one script per url. - let scriptsByUrl = {}; - for (let s of this.dbg.findScripts()) { - scriptsByUrl[s.url] = s; - } - - return all([this.sources.sourcesForScript(scriptsByUrl[s]) - for (s of Object.keys(scriptsByUrl))]); - }, - - onSources: function TA_onSources(aRequest) { - return this._discoverSources().then(() => { - return { - sources: [s.form() for (s of this.sources.iter())] - }; - }); - }, - - /** - * Disassociate all breakpoint actors from their scripts and clear the - * breakpoint handlers. This method can be used when the thread actor intends - * to keep the breakpoint store, but needs to clear any actual breakpoints, - * e.g. due to a page navigation. This way the breakpoint actors' script - * caches won't hold on to the Debugger.Script objects leaking memory. - */ - disableAllBreakpoints: function () { - for (let url in this._breakpointStore) { - for (let line in this._breakpointStore[url]) { - let bp = this._breakpointStore[url][line]; - bp.actor.removeScripts(); - } - } - }, - - /** - * Handle a protocol request to pause the debuggee. - */ - onInterrupt: function TA_onInterrupt(aRequest) { - if (this.state == "exited") { - return { type: "exited" }; - } else if (this.state == "paused") { - // TODO: return the actual reason for the existing pause. - return { type: "paused", why: { type: "alreadyPaused" } }; - } else if (this.state != "running") { - return { error: "wrongState", - message: "Received interrupt request in " + this.state + - " state." }; - } - - try { - // Put ourselves in the paused state. - let packet = this._paused(); - if (!packet) { - return { error: "notInterrupted" }; - } - packet.why = { type: "interrupted" }; - - // Send the response to the interrupt request now (rather than - // returning it), because we're going to start a nested event loop - // here. - this.conn.send(packet); - - // Start a nested event loop. - this._nest(); - - // We already sent a response to this request, don't send one - // now. - return null; - } catch (e) { - reportError(e); - return { error: "notInterrupted", message: e.toString() }; - } - }, - - /** - * Return the Debug.Frame for a frame mentioned by the protocol. - */ - _requestFrame: function TA_requestFrame(aFrameID) { - if (!aFrameID) { - return this.youngestFrame; - } - - if (this._framePool.has(aFrameID)) { - return this._framePool.get(aFrameID).frame; - } - - return undefined; - }, - - _paused: function TA_paused(aFrame) { - // We don't handle nested pauses correctly. Don't try - if we're - // paused, just continue running whatever code triggered the pause. - // We don't want to actually have nested pauses (although we - // have nested event loops). If code runs in the debuggee during - // a pause, it should cause the actor to resume (dropping - // pause-lifetime actors etc) and then repause when complete. - - if (this.state === "paused") { - return undefined; - } - - // Clear stepping hooks. - this.dbg.onEnterFrame = undefined; - this.dbg.onExceptionUnwind = undefined; - if (aFrame) { - aFrame.onStep = undefined; - aFrame.onPop = undefined; - } - - this._state = "paused"; - - // Save the pause frame (if any) as the youngest frame for - // stack viewing. - this.youngestFrame = aFrame; - - // Create the actor pool that will hold the pause actor and its - // children. - dbg_assert(!this._pausePool); - this._pausePool = new ActorPool(this.conn); - this.conn.addActorPool(this._pausePool); - - // Give children of the pause pool a quick link back to the - // thread... - this._pausePool.threadActor = this; - - // Create the pause actor itself... - dbg_assert(!this._pauseActor); - this._pauseActor = new PauseActor(this._pausePool); - this._pausePool.addActor(this._pauseActor); - - // Update the list of frames. - let poppedFrames = this._updateFrames(); - - // Send off the paused packet and spin an event loop. - let packet = { from: this.actorID, - type: "paused", - actor: this._pauseActor.actorID }; - if (aFrame) { - packet.frame = this._createFrameActor(aFrame).form(); - } - - if (poppedFrames) { - packet.poppedFrames = poppedFrames; - } - - return packet; - }, - - _nest: function TA_nest() { - if (this._hooks.preNest) { - var nestData = this._hooks.preNest(); - } - - let requestor = Object.create(null); - requestor.url = this._hooks.url; - requestor.connection = this.conn; - DebuggerServer.xpcInspector.enterNestedEventLoop(requestor); - - dbg_assert(this.state === "running"); - - if (this._hooks.postNest) { - this._hooks.postNest(nestData) - } - - // "continue" resumption value. - return undefined; - }, - - _resumed: function TA_resumed() { - this._state = "running"; - - // Drop the actors in the pause actor pool. - this.conn.removeActorPool(this._pausePool); - - this._pausePool = null; - this._pauseActor = null; - this.youngestFrame = null; - - return { from: this.actorID, type: "resumed" }; - }, - - /** - * Expire frame actors for frames that have been popped. - * - * @returns A list of actor IDs whose frames have been popped. - */ - _updateFrames: function TA_updateFrames() { - let popped = []; - - // Create the actor pool that will hold the still-living frames. - let framePool = new ActorPool(this.conn); - let frameList = []; - - for each (let frameActor in this._frameActors) { - if (frameActor.frame.live) { - framePool.addActor(frameActor); - frameList.push(frameActor); - } else { - popped.push(frameActor.actorID); - } - } - - // Remove the old frame actor pool, this will expire - // any actors that weren't added to the new pool. - if (this._framePool) { - this.conn.removeActorPool(this._framePool); - } - - this._frameActors = frameList; - this._framePool = framePool; - this.conn.addActorPool(framePool); - - return popped; - }, - - _createFrameActor: function TA_createFrameActor(aFrame) { - if (aFrame.actor) { - return aFrame.actor; - } - - let actor = new FrameActor(aFrame, this); - this._frameActors.push(actor); - this._framePool.addActor(actor); - aFrame.actor = actor; - - return actor; - }, - - /** - * Create and return an environment actor that corresponds to the provided - * Debugger.Environment. - * @param Debugger.Environment aEnvironment - * The lexical environment we want to extract. - * @param object aPool - * The pool where the newly-created actor will be placed. - * @return The EnvironmentActor for aEnvironment or undefined for host - * functions or functions scoped to a non-debuggee global. - */ - createEnvironmentActor: - function TA_createEnvironmentActor(aEnvironment, aPool) { - if (!aEnvironment) { - return undefined; - } - - if (aEnvironment.actor) { - return aEnvironment.actor; - } - - let actor = new EnvironmentActor(aEnvironment, this); - this._environmentActors.push(actor); - aPool.addActor(actor); - aEnvironment.actor = actor; - - return actor; - }, - - /** - * Create a grip for the given debuggee value. If the value is an - * object, will create an actor with the given lifetime. - */ - createValueGrip: function TA_createValueGrip(aValue, aPool=false) { - if (!aPool) { - aPool = this._pausePool; - } - let type = typeof(aValue); - - if (type === "string" && this._stringIsLong(aValue)) { - return this.longStringGrip(aValue, aPool); - } - - if (type === "boolean" || type === "string" || type === "number") { - return aValue; - } - - if (aValue === null) { - return { type: "null" }; - } - - if (aValue === undefined) { - return { type: "undefined" } - } - - if (typeof(aValue) === "object") { - return this.objectGrip(aValue, aPool); - } - - dbg_assert(false, "Failed to provide a grip for: " + aValue); - return null; - }, - - /** - * Return a protocol completion value representing the given - * Debugger-provided completion value. - */ - createProtocolCompletionValue: - function TA_createProtocolCompletionValue(aCompletion) { - let protoValue = {}; - if ("return" in aCompletion) { - protoValue.return = this.createValueGrip(aCompletion.return); - } else if ("yield" in aCompletion) { - protoValue.return = this.createValueGrip(aCompletion.yield); - } else if ("throw" in aCompletion) { - protoValue.throw = this.createValueGrip(aCompletion.throw); - } else { - protoValue.terminated = true; - } - return protoValue; - }, - - /** - * Create a grip for the given debuggee object. - * - * @param aValue Debugger.Object - * The debuggee object value. - * @param aPool ActorPool - * The actor pool where the new object actor will be added. - */ - objectGrip: function TA_objectGrip(aValue, aPool) { - if (!aPool.objectActors) { - aPool.objectActors = new WeakMap(); - } - - if (aPool.objectActors.has(aValue)) { - return aPool.objectActors.get(aValue).grip(); - } else if (this.threadLifetimePool.objectActors.has(aValue)) { - return this.threadLifetimePool.objectActors.get(aValue).grip(); - } - - let actor = new PauseScopedObjectActor(aValue, this); - aPool.addActor(actor); - aPool.objectActors.set(aValue, actor); - return actor.grip(); - }, - - /** - * Create a grip for the given debuggee object with a pause lifetime. - * - * @param aValue Debugger.Object - * The debuggee object value. - */ - pauseObjectGrip: function TA_pauseObjectGrip(aValue) { - if (!this._pausePool) { - throw "Object grip requested while not paused."; - } - - return this.objectGrip(aValue, this._pausePool); - }, - - /** - * Extend the lifetime of the provided object actor to thread lifetime. - * - * @param aActor object - * The object actor. - */ - threadObjectGrip: function TA_threadObjectGrip(aActor) { - // We want to reuse the existing actor ID, so we just remove it from the - // current pool's weak map and then let pool.addActor do the rest. - aActor.registeredPool.objectActors.delete(aActor.obj); - this.threadLifetimePool.addActor(aActor); - this.threadLifetimePool.objectActors.set(aActor.obj, aActor); - }, - - /** - * Handle a protocol request to promote multiple pause-lifetime grips to - * thread-lifetime grips. - * - * @param aRequest object - * The protocol request object. - */ - onThreadGrips: function OA_onThreadGrips(aRequest) { - if (this.state != "paused") { - return { error: "wrongState" }; - } - - if (!aRequest.actors) { - return { error: "missingParameter", - message: "no actors were specified" }; - } - - for (let actorID of aRequest.actors) { - let actor = this._pausePool.get(actorID); - if (actor) { - this.threadObjectGrip(actor); - } - } - return {}; - }, - - /** - * Create a grip for the given string. - * - * @param aString String - * The string we are creating a grip for. - * @param aPool ActorPool - * The actor pool where the new actor will be added. - */ - longStringGrip: function TA_longStringGrip(aString, aPool) { - if (!aPool.longStringActors) { - aPool.longStringActors = {}; - } - - if (aPool.longStringActors.hasOwnProperty(aString)) { - return aPool.longStringActors[aString].grip(); - } - - let actor = new LongStringActor(aString, this); - aPool.addActor(actor); - aPool.longStringActors[aString] = actor; - return actor.grip(); - }, - - /** - * Create a long string grip that is scoped to a pause. - * - * @param aString String - * The string we are creating a grip for. - */ - pauseLongStringGrip: function TA_pauseLongStringGrip (aString) { - return this.longStringGrip(aString, this._pausePool); - }, - - /** - * Create a long string grip that is scoped to a thread. - * - * @param aString String - * The string we are creating a grip for. - */ - threadLongStringGrip: function TA_pauseLongStringGrip (aString) { - return this.longStringGrip(aString, this._threadLifetimePool); - }, - - /** - * Returns true if the string is long enough to use a LongStringActor instead - * of passing the value directly over the protocol. - * - * @param aString String - * The string we are checking the length of. - */ - _stringIsLong: function TA__stringIsLong(aString) { - return aString.length >= DebuggerServer.LONG_STRING_LENGTH; - }, - - // JS Debugger API hooks. - - /** - * A function that the engine calls when a call to a debug event hook, - * breakpoint handler, watchpoint handler, or similar function throws some - * exception. - * - * @param aException exception - * The exception that was thrown in the debugger code. - */ - uncaughtExceptionHook: function TA_uncaughtExceptionHook(aException) { - dumpn("Got an exception: " + aException.message + "\n" + aException.stack); - }, - - /** - * A function that the engine calls when a debugger statement has been - * executed in the specified frame. - * - * @param aFrame Debugger.Frame - * The stack frame that contained the debugger statement. - */ - onDebuggerStatement: function TA_onDebuggerStatement(aFrame) { - if (this.sources.isBlackBoxed(aFrame.script.url)) { - return undefined; - } - return this._pauseAndRespond(aFrame, { type: "debuggerStatement" }); - }, - - /** - * A function that the engine calls when an exception has been thrown and has - * propagated to the specified frame. - * - * @param aFrame Debugger.Frame - * The youngest remaining stack frame. - * @param aValue object - * The exception that was thrown. - */ - onExceptionUnwind: function TA_onExceptionUnwind(aFrame, aValue) { - if (this.sources.isBlackBoxed(aFrame.script.url)) { - return undefined; - } - try { - let packet = this._paused(aFrame); - if (!packet) { - return undefined; - } - - packet.why = { type: "exception", - exception: this.createValueGrip(aValue) }; - this.conn.send(packet); - return this._nest(); - } catch(e) { - log("Got an exception during TA_onExceptionUnwind: " + e + - ": " + e.stack); - return undefined; - } - }, - - /** - * A function that the engine calls when a new script has been loaded into the - * scope of the specified debuggee global. - * - * @param aScript Debugger.Script - * The source script that has been loaded into a debuggee compartment. - * @param aGlobal Debugger.Object - * A Debugger.Object instance whose referent is the global object. - */ - onNewScript: function TA_onNewScript(aScript, aGlobal) { - this._addScript(aScript); - this.sources.sourcesForScript(aScript); - }, - - onNewSource: function TA_onNewSource(aSource) { - this.conn.send({ - from: this.actorID, - type: "newSource", - source: aSource.form() - }); - }, - - /** - * Check if scripts from the provided source URL are allowed to be stored in - * the cache. - * - * @param aSourceUrl String - * The url of the script's source that will be stored. - * @returns true, if the script can be added, false otherwise. - */ - _allowSource: function TA__allowSource(aSourceUrl) { - // Ignore anything we don't have a URL for (eval scripts, for example). - if (!aSourceUrl) - return false; - // Ignore XBL bindings for content debugging. - if (aSourceUrl.indexOf("chrome://") == 0) { - return false; - } - // Ignore about:* pages for content debugging. - if (aSourceUrl.indexOf("about:") == 0) { - return false; - } - return true; - }, - - /** - * Restore any pre-existing breakpoints to the scripts that we have access to. - */ - _restoreBreakpoints: function TA__restoreBreakpoints() { - for (let s of this.dbg.findScripts()) { - this._addScript(s); - } - }, - - /** - * Add the provided script to the server cache. - * - * @param aScript Debugger.Script - * The source script that will be stored. - * @returns true, if the script was added; false otherwise. - */ - _addScript: function TA__addScript(aScript) { - if (!this._allowSource(aScript.url)) { - return false; - } - - // Set any stored breakpoints. - let existing = this._breakpointStore[aScript.url]; - if (existing) { - let endLine = aScript.startLine + aScript.lineCount - 1; - // Iterate over the lines backwards, so that sliding breakpoints don't - // affect the loop. - for (let line = existing.length - 1; line >= aScript.startLine; line--) { - let bp = existing[line]; - // Only consider breakpoints that are not already associated with - // scripts, and limit search to the line numbers contained in the new - // script. - if (bp && !bp.actor.scripts.length && line <= endLine) { - this._setBreakpoint(bp); - } - } - } - return true; - }, - -}; - -ThreadActor.prototype.requestTypes = { - "attach": ThreadActor.prototype.onAttach, - "detach": ThreadActor.prototype.onDetach, - "reconfigure": ThreadActor.prototype.onReconfigure, - "resume": ThreadActor.prototype.onResume, - "clientEvaluate": ThreadActor.prototype.onClientEvaluate, - "frames": ThreadActor.prototype.onFrames, - "interrupt": ThreadActor.prototype.onInterrupt, - "releaseMany": ThreadActor.prototype.onReleaseMany, - "setBreakpoint": ThreadActor.prototype.onSetBreakpoint, - "sources": ThreadActor.prototype.onSources, - "threadGrips": ThreadActor.prototype.onThreadGrips -}; - - -/** - * Creates a PauseActor. - * - * PauseActors exist for the lifetime of a given debuggee pause. Used to - * scope pause-lifetime grips. - * - * @param ActorPool aPool - * The actor pool created for this pause. - */ -function PauseActor(aPool) -{ - this.pool = aPool; -} - -PauseActor.prototype = { - actorPrefix: "pause" -}; - - -/** - * A base actor for any actors that should only respond receive messages in the - * paused state. Subclasses may expose a `threadActor` which is used to help - * determine when we are in a paused state. Subclasses should set their own - * "constructor" property if they want better error messages. You should never - * instantiate a PauseScopedActor directly, only through subclasses. - */ -function PauseScopedActor() -{ -} - -/** - * A function decorator for creating methods to handle protocol messages that - * should only be received while in the paused state. - * - * @param aMethod Function - * The function we are decorating. - */ -PauseScopedActor.withPaused = function PSA_withPaused(aMethod) { - return function () { - if (this.isPaused()) { - return aMethod.apply(this, arguments); - } else { - return this._wrongState(); - } - }; -}; - -PauseScopedActor.prototype = { - - /** - * Returns true if we are in the paused state. - */ - isPaused: function PSA_isPaused() { - // When there is not a ThreadActor available (like in the webconsole) we - // have to be optimistic and assume that we are paused so that we can - // respond to requests. - return this.threadActor ? this.threadActor.state === "paused" : true; - }, - - /** - * Returns the wrongState response packet for this actor. - */ - _wrongState: function PSA_wrongState() { - return { - error: "wrongState", - message: this.constructor.name + - " actors can only be accessed while the thread is paused." - }; - } -}; - - -/** - * A SourceActor provides information about the source of a script. - * - * @param aUrl String - * The url of the source we are representing. - * @param aThreadActor ThreadActor - * The current thread actor. - * @param aSourceMap SourceMapConsumer - * Optional. The source map that introduced this source, if available. - */ -function SourceActor(aUrl, aThreadActor, aSourceMap=null) { - this._threadActor = aThreadActor; - this._url = aUrl; - this._sourceMap = aSourceMap; -} - -SourceActor.prototype = { - constructor: SourceActor, - actorPrefix: "source", - - get threadActor() this._threadActor, - get url() this._url, - - form: function SA_form() { - return { - actor: this.actorID, - url: this._url, - isBlackBoxed: this.threadActor.sources.isBlackBoxed(this.url) - // TODO bug 637572: introductionScript - }; - }, - - disconnect: function LSA_disconnect() { - if (this.registeredPool && this.registeredPool.sourceActors) { - delete this.registeredPool.sourceActors[this.actorID]; - } - }, - - /** - * Handler for the "source" packet. - */ - onSource: function SA_onSource(aRequest) { - let sourceContent = null; - if (this._sourceMap) { - sourceContent = this._sourceMap.sourceContentFor(this._url); - } - - if (sourceContent) { - return { - from: this.actorID, - source: this.threadActor.createValueGrip( - sourceContent, this.threadActor.threadLifetimePool) - }; - } - - // XXX bug 865252: Don't load from the cache if this is a source mapped - // source because we can't guarantee that the cache has the most up to date - // content for this source like we can if it isn't source mapped. - return fetch(this._url, { loadFromCache: !this._sourceMap }) - .then((aSource) => { - return this.threadActor.createValueGrip( - aSource, this.threadActor.threadLifetimePool); - }) - .then((aSourceGrip) => { - return { - from: this.actorID, - source: aSourceGrip - }; - }, (aError) => { - let msg = "Got an exception during SA_onSource: " + aError + - "\n" + aError.stack; - // Cu.reportError(msg); - dumpn(msg); - return { - "from": this.actorID, - "error": "loadSourceError", - "message": "Could not load the source for " + this._url + "." - }; - }); - }, - - /** - * Handler for the "blackbox" packet. - */ - onBlackBox: function SA_onBlackBox(aRequest) { - this.threadActor.sources.blackBox(this.url); - let packet = { - from: this.actorID - }; - if (this.threadActor.state == "paused" - && this.threadActor.youngestFrame - && this.threadActor.youngestFrame.script.url == this.url) { - packet.pausedInSource = true; - } - return packet; - }, - - /** - * Handler for the "unblackbox" packet. - */ - onUnblackBox: function SA_onUnblackBox(aRequest) { - this.threadActor.sources.unblackBox(this.url); - return { - from: this.actorID - }; - } -}; - -SourceActor.prototype.requestTypes = { - "source": SourceActor.prototype.onSource, - "blackbox": SourceActor.prototype.onBlackBox, - "unblackbox": SourceActor.prototype.onUnblackBox -}; - - -/** - * Creates an actor for the specified object. - * - * @param aObj Debugger.Object - * The debuggee object. - * @param aThreadActor ThreadActor - * The parent thread actor for this object. - */ -function ObjectActor(aObj, aThreadActor) -{ - this.obj = aObj; - this.threadActor = aThreadActor; -} - -ObjectActor.prototype = { - actorPrefix: "obj", - - /** - * Returns a grip for this actor for returning in a protocol message. - */ - grip: function OA_grip() { - let g = { - "type": "object", - "class": this.obj.class, - "actor": this.actorID, - "extensible": this.obj.isExtensible(), - "frozen": this.obj.isFrozen(), - "sealed": this.obj.isSealed() - }; - - // Add additional properties for functions. - if (this.obj.class === "Function") { - if (this.obj.name) { - g.name = this.obj.name; - } else if (this.obj.displayName) { - g.displayName = this.obj.displayName; - } - - // Check if the developer has added a de-facto standard displayName - // property for us to use. - let desc = this.obj.getOwnPropertyDescriptor("displayName"); - if (desc && desc.value && typeof desc.value == "string") { - g.userDisplayName = this.threadActor.createValueGrip(desc.value); - } - } - - return g; - }, - - /** - * Releases this actor from the pool. - */ - release: function OA_release() { - if (this.registeredPool.objectActors) { - this.registeredPool.objectActors.delete(this.obj); - } - this.registeredPool.removeActor(this); - }, - - /** - * Handle a protocol request to provide the names of the properties defined on - * the object and not its prototype. - * - * @param aRequest object - * The protocol request object. - */ - onOwnPropertyNames: function OA_onOwnPropertyNames(aRequest) { - return { from: this.actorID, - ownPropertyNames: this.obj.getOwnPropertyNames() }; - }, - - /** - * Handle a protocol request to provide the prototype and own properties of - * the object. - * - * @param aRequest object - * The protocol request object. - */ - onPrototypeAndProperties: function OA_onPrototypeAndProperties(aRequest) { - let ownProperties = Object.create(null); - let names; - try { - names = this.obj.getOwnPropertyNames(); - } catch (ex) { - // The above can throw if this.obj points to a dead object. - // TODO: we should use Cu.isDeadWrapper() - see bug 885800. - return { from: this.actorID, - prototype: this.threadActor.createValueGrip(null), - ownProperties: ownProperties, - safeGetterValues: Object.create(null) }; - } - for (let name of names) { - ownProperties[name] = this._propertyDescriptor(name); - } - return { from: this.actorID, - prototype: this.threadActor.createValueGrip(this.obj.proto), - ownProperties: ownProperties, - safeGetterValues: this._findSafeGetterValues(ownProperties) }; - }, - - /** - * Find the safe getter values for the current Debugger.Object, |this.obj|. - * - * @private - * @param object aOwnProperties - * The object that holds the list of known ownProperties for - * |this.obj|. - * @return object - * An object that maps property names to safe getter descriptors as - * defined by the remote debugging protocol. - */ - _findSafeGetterValues: function OA__findSafeGetterValues(aOwnProperties) - { - let safeGetterValues = Object.create(null); - let obj = this.obj; - let level = 0; - - while (obj) { - let getters = this._findSafeGetters(obj); - for (let name of getters) { - // Avoid overwriting properties from prototypes closer to this.obj. Also - // avoid providing safeGetterValues from prototypes if property |name| - // is already defined as an own property. - if (name in safeGetterValues || - (obj != this.obj && name in aOwnProperties)) { - continue; - } - - let desc = null, getter = null; - try { - desc = obj.getOwnPropertyDescriptor(name); - getter = desc.get; - } catch (ex) { - // The above can throw if the cache becomes stale. - } - if (!getter) { - obj._safeGetters = null; - continue; - } - - let result = getter.call(this.obj); - if (result && !("throw" in result)) { - let getterValue = undefined; - if ("return" in result) { - getterValue = result.return; - } else if ("yield" in result) { - getterValue = result.yield; - } - // WebIDL attributes specified with the LenientThis extended attribute - // return undefined and should be ignored. - if (getterValue !== undefined) { - safeGetterValues[name] = { - getterValue: this.threadActor.createValueGrip(getterValue), - getterPrototypeLevel: level, - enumerable: desc.enumerable, - writable: level == 0 ? desc.writable : true, - }; - } - } - } - - obj = obj.proto; - level++; - } - - return safeGetterValues; - }, - - /** - * Find the safe getters for a given Debugger.Object. Safe getters are native - * getters which are safe to execute. - * - * @private - * @param Debugger.Object aObject - * The Debugger.Object where you want to find safe getters. - * @return Set - * A Set of names of safe getters. This result is cached for each - * Debugger.Object. - */ - _findSafeGetters: function OA__findSafeGetters(aObject) - { - if (aObject._safeGetters) { - return aObject._safeGetters; - } - - let getters = new Set(); - for (let name of aObject.getOwnPropertyNames()) { - let desc = null; - try { - desc = aObject.getOwnPropertyDescriptor(name); - } catch (e) { - // Calling getOwnPropertyDescriptor on wrapped native prototypes is not - // allowed (bug 560072). - } - if (!desc || desc.value !== undefined || !("get" in desc)) { - continue; - } - - let fn = desc.get; - if (fn && fn.callable && fn.class == "Function" && - fn.script === undefined) { - getters.add(name); - } - } - - aObject._safeGetters = getters; - return getters; - }, - - /** - * Handle a protocol request to provide the prototype of the object. - * - * @param aRequest object - * The protocol request object. - */ - onPrototype: function OA_onPrototype(aRequest) { - return { from: this.actorID, - prototype: this.threadActor.createValueGrip(this.obj.proto) }; - }, - - /** - * Handle a protocol request to provide the property descriptor of the - * object's specified property. - * - * @param aRequest object - * The protocol request object. - */ - onProperty: function OA_onProperty(aRequest) { - if (!aRequest.name) { - return { error: "missingParameter", - message: "no property name was specified" }; - } - - return { from: this.actorID, - descriptor: this._propertyDescriptor(aRequest.name) }; - }, - - /** - * A helper method that creates a property descriptor for the provided object, - * properly formatted for sending in a protocol response. - * - * @param string aName - * The property that the descriptor is generated for. - */ - _propertyDescriptor: function OA_propertyDescriptor(aName) { - let desc; - try { - desc = this.obj.getOwnPropertyDescriptor(aName); - } catch (e) { - // Calling getOwnPropertyDescriptor on wrapped native prototypes is not - // allowed (bug 560072). Inform the user with a bogus, but hopefully - // explanatory, descriptor. - return { - configurable: false, - writable: false, - enumerable: false, - value: e.name - }; - } - - let retval = { - configurable: desc.configurable, - enumerable: desc.enumerable - }; - - if ("value" in desc) { - retval.writable = desc.writable; - retval.value = this.threadActor.createValueGrip(desc.value); - } else { - if ("get" in desc) { - retval.get = this.threadActor.createValueGrip(desc.get); - } - if ("set" in desc) { - retval.set = this.threadActor.createValueGrip(desc.set); - } - } - return retval; - }, - - /** - * Handle a protocol request to provide the source code of a function. - * - * @param aRequest object - * The protocol request object. - */ - onDecompile: function OA_onDecompile(aRequest) { - if (this.obj.class !== "Function") { - return { error: "objectNotFunction", - message: "decompile request is only valid for object grips " + - "with a 'Function' class." }; - } - - return { from: this.actorID, - decompiledCode: this.obj.decompile(!!aRequest.pretty) }; - }, - - /** - * Handle a protocol request to provide the parameters of a function. - * - * @param aRequest object - * The protocol request object. - */ - onParameterNames: function OA_onParameterNames(aRequest) { - if (this.obj.class !== "Function") { - return { error: "objectNotFunction", - message: "'parameterNames' request is only valid for object " + - "grips with a 'Function' class." }; - } - - return { parameterNames: this.obj.parameterNames }; - }, - - /** - * Handle a protocol request to release a thread-lifetime grip. - * - * @param aRequest object - * The protocol request object. - */ - onRelease: function OA_onRelease(aRequest) { - this.release(); - return {}; - }, -}; - -ObjectActor.prototype.requestTypes = { - "parameterNames": ObjectActor.prototype.onParameterNames, - "prototypeAndProperties": ObjectActor.prototype.onPrototypeAndProperties, - "prototype": ObjectActor.prototype.onPrototype, - "property": ObjectActor.prototype.onProperty, - "ownPropertyNames": ObjectActor.prototype.onOwnPropertyNames, - "decompile": ObjectActor.prototype.onDecompile, - "release": ObjectActor.prototype.onRelease, -}; - - -/** - * Creates a pause-scoped actor for the specified object. - * @see ObjectActor - */ -function PauseScopedObjectActor() -{ - ObjectActor.apply(this, arguments); -} - -PauseScopedObjectActor.prototype = Object.create(PauseScopedActor.prototype); - -update(PauseScopedObjectActor.prototype, ObjectActor.prototype); - -update(PauseScopedObjectActor.prototype, { - constructor: PauseScopedObjectActor, - - onOwnPropertyNames: - PauseScopedActor.withPaused(ObjectActor.prototype.onOwnPropertyNames), - - onPrototypeAndProperties: - PauseScopedActor.withPaused(ObjectActor.prototype.onPrototypeAndProperties), - - onPrototype: PauseScopedActor.withPaused(ObjectActor.prototype.onPrototype), - onProperty: PauseScopedActor.withPaused(ObjectActor.prototype.onProperty), - onDecompile: PauseScopedActor.withPaused(ObjectActor.prototype.onDecompile), - - onParameterNames: - PauseScopedActor.withPaused(ObjectActor.prototype.onParameterNames), - - /** - * Handle a protocol request to provide the lexical scope of a function. - * - * @param aRequest object - * The protocol request object. - */ - onScope: PauseScopedActor.withPaused(function OA_onScope(aRequest) { - if (this.obj.class !== "Function") { - return { error: "objectNotFunction", - message: "scope request is only valid for object grips with a" + - " 'Function' class." }; - } - - let envActor = this.threadActor.createEnvironmentActor(this.obj.environment, - this.registeredPool); - if (!envActor) { - return { error: "notDebuggee", - message: "cannot access the environment of this function." }; - } - - return { from: this.actorID, scope: envActor.form() }; - }), - - /** - * Handle a protocol request to promote a pause-lifetime grip to a - * thread-lifetime grip. - * - * @param aRequest object - * The protocol request object. - */ - onThreadGrip: PauseScopedActor.withPaused(function OA_onThreadGrip(aRequest) { - this.threadActor.threadObjectGrip(this); - return {}; - }), - - /** - * Handle a protocol request to release a thread-lifetime grip. - * - * @param aRequest object - * The protocol request object. - */ - onRelease: PauseScopedActor.withPaused(function OA_onRelease(aRequest) { - if (this.registeredPool !== this.threadActor.threadLifetimePool) { - return { error: "notReleasable", - message: "Only thread-lifetime actors can be released." }; - } - - this.release(); - return {}; - }), -}); - -update(PauseScopedObjectActor.prototype.requestTypes, { - "scope": PauseScopedObjectActor.prototype.onScope, - "threadGrip": PauseScopedObjectActor.prototype.onThreadGrip, -}); - - -/** - * Creates an actor for the specied "very long" string. "Very long" is specified - * at the server's discretion. - * - * @param aString String - * The string. - */ -function LongStringActor(aString) -{ - this.string = aString; - this.stringLength = aString.length; -} - -LongStringActor.prototype = { - - actorPrefix: "longString", - - disconnect: function LSA_disconnect() { - // Because longStringActors is not a weak map, we won't automatically leave - // it so we need to manually leave on disconnect so that we don't leak - // memory. - if (this.registeredPool && this.registeredPool.longStringActors) { - delete this.registeredPool.longStringActors[this.actorID]; - } - }, - - /** - * Returns a grip for this actor for returning in a protocol message. - */ - grip: function LSA_grip() { - return { - "type": "longString", - "initial": this.string.substring( - 0, DebuggerServer.LONG_STRING_INITIAL_LENGTH), - "length": this.stringLength, - "actor": this.actorID - }; - }, - - /** - * Handle a request to extract part of this actor's string. - * - * @param aRequest object - * The protocol request object. - */ - onSubstring: function LSA_onSubString(aRequest) { - return { - "from": this.actorID, - "substring": this.string.substring(aRequest.start, aRequest.end) - }; - }, - - /** - * Handle a request to release this LongStringActor instance. - */ - onRelease: function LSA_onRelease() { - // TODO: also check if registeredPool === threadActor.threadLifetimePool - // when the web console moves aray from manually releasing pause-scoped - // actors. - if (this.registeredPool.longStringActors) { - delete this.registeredPool.longStringActors[this.actorID]; - } - this.registeredPool.removeActor(this); - return {}; - }, -}; - -LongStringActor.prototype.requestTypes = { - "substring": LongStringActor.prototype.onSubstring, - "release": LongStringActor.prototype.onRelease -}; - - -/** - * Creates an actor for the specified stack frame. - * - * @param aFrame Debugger.Frame - * The debuggee frame. - * @param aThreadActor ThreadActor - * The parent thread actor for this frame. - */ -function FrameActor(aFrame, aThreadActor) -{ - this.frame = aFrame; - this.threadActor = aThreadActor; -} - -FrameActor.prototype = { - actorPrefix: "frame", - - /** - * A pool that contains frame-lifetime objects, like the environment. - */ - _frameLifetimePool: null, - get frameLifetimePool() { - if (!this._frameLifetimePool) { - this._frameLifetimePool = new ActorPool(this.conn); - this.conn.addActorPool(this._frameLifetimePool); - } - return this._frameLifetimePool; - }, - - /** - * Finalization handler that is called when the actor is being evicted from - * the pool. - */ - disconnect: function FA_disconnect() { - this.conn.removeActorPool(this._frameLifetimePool); - this._frameLifetimePool = null; - }, - - /** - * Returns a frame form for use in a protocol message. - */ - form: function FA_form() { - let form = { actor: this.actorID, - type: this.frame.type }; - if (this.frame.type === "call") { - form.callee = this.threadActor.createValueGrip(this.frame.callee); - } - - if (this.frame.environment) { - let envActor = this.threadActor - .createEnvironmentActor(this.frame.environment, - this.frameLifetimePool); - form.environment = envActor.form(); - } - form.this = this.threadActor.createValueGrip(this.frame.this); - form.arguments = this._args(); - if (this.frame.script) { - form.where = { url: this.frame.script.url, - line: this.frame.script.getOffsetLine(this.frame.offset) }; - form.isBlackBoxed = this.threadActor.sources.isBlackBoxed(this.frame.script.url) - } - - if (!this.frame.older) { - form.oldest = true; - } - - return form; - }, - - _args: function FA__args() { - if (!this.frame.arguments) { - return []; - } - - return [this.threadActor.createValueGrip(arg) - for each (arg in this.frame.arguments)]; - }, - - /** - * Handle a protocol request to pop this frame from the stack. - * - * @param aRequest object - * The protocol request object. - */ - onPop: function FA_onPop(aRequest) { - // TODO: remove this when Debugger.Frame.prototype.pop is implemented - if (typeof this.frame.pop != "function") { - return { error: "notImplemented", - message: "Popping frames is not yet implemented." }; - } - - while (this.frame != this.threadActor.dbg.getNewestFrame()) { - this.threadActor.dbg.getNewestFrame().pop(); - } - this.frame.pop(aRequest.completionValue); - - // TODO: return the watches property when frame pop watch actors are - // implemented. - return { from: this.actorID }; - } -}; - -FrameActor.prototype.requestTypes = { - "pop": FrameActor.prototype.onPop, -}; - - -/** - * Creates a BreakpointActor. BreakpointActors exist for the lifetime of their - * containing thread and are responsible for deleting breakpoints, handling - * breakpoint hits and associating breakpoints with scripts. - * - * @param ThreadActor aThreadActor - * The parent thread actor that contains this breakpoint. - * @param object aLocation - * The location of the breakpoint as specified in the protocol. - */ -function BreakpointActor(aThreadActor, aLocation) -{ - this.scripts = []; - this.threadActor = aThreadActor; - this.location = aLocation; -} - -BreakpointActor.prototype = { - actorPrefix: "breakpoint", - - /** - * Called when this same breakpoint is added to another Debugger.Script - * instance, in the case of a page reload. - * - * @param aScript Debugger.Script - * The new source script on which the breakpoint has been set. - * @param ThreadActor aThreadActor - * The parent thread actor that contains this breakpoint. - */ - addScript: function BA_addScript(aScript, aThreadActor) { - this.threadActor = aThreadActor; - this.scripts.push(aScript); - }, - - /** - * Remove the breakpoints from associated scripts and clear the script cache. - */ - removeScripts: function () { - for (let script of this.scripts) { - script.clearBreakpoint(this); - } - this.scripts = []; - }, - - /** - * A function that the engine calls when a breakpoint has been hit. - * - * @param aFrame Debugger.Frame - * The stack frame that contained the breakpoint. - */ - hit: function BA_hit(aFrame) { - if (this.threadActor.sources.isBlackBoxed(this.location.url)) { - return undefined; - } - - // TODO: add the rest of the breakpoints on that line (bug 676602). - let reason = { type: "breakpoint", actors: [ this.actorID ] }; - return this.threadActor._pauseAndRespond(aFrame, reason, (aPacket) => { - log("pause callback ..."); - - let { url, line } = aPacket.frame.where; - return this.threadActor.sources.getOriginalLocation(url, line) - .then(function (aOrigPosition) { - aPacket.frame.where = aOrigPosition; - return aPacket; - }); - }); - }, - - /** - * Handle a protocol request to remove this breakpoint. - * - * @param aRequest object - * The protocol request object. - */ - onDelete: function BA_onDelete(aRequest) { - // Remove from the breakpoint store. - let scriptBreakpoints = this.threadActor._breakpointStore[this.location.url]; - delete scriptBreakpoints[this.location.line]; - this.threadActor._hooks.removeFromParentPool(this); - // Remove the actual breakpoint from the associated scripts. - this.removeScripts(); - - return { from: this.actorID }; - } -}; - -BreakpointActor.prototype.requestTypes = { - "delete": BreakpointActor.prototype.onDelete -}; - - -/** - * Creates an EnvironmentActor. EnvironmentActors are responsible for listing - * the bindings introduced by a lexical environment and assigning new values to - * those identifier bindings. - * - * @param Debugger.Environment aEnvironment - * The lexical environment that will be used to create the actor. - * @param ThreadActor aThreadActor - * The parent thread actor that contains this environment. - */ -function EnvironmentActor(aEnvironment, aThreadActor) -{ - this.obj = aEnvironment; - this.threadActor = aThreadActor; -} - -EnvironmentActor.prototype = { - actorPrefix: "environment", - - /** - * Return an environment form for use in a protocol message. - */ - form: function EA_form() { - let form = { actor: this.actorID }; - - // What is this environment's type? - if (this.obj.type == "declarative") { - form.type = this.obj.callee ? "function" : "block"; - } else { - form.type = this.obj.type; - } - - // Does this environment have a parent? - if (this.obj.parent) { - form.parent = (this.threadActor - .createEnvironmentActor(this.obj.parent, - this.registeredPool) - .form()); - } - - // Does this environment reflect the properties of an object as variables? - if (this.obj.type == "object" || this.obj.type == "with") { - form.object = this.threadActor.createValueGrip(this.obj.object); - } - - // Is this the environment created for a function call? - if (this.obj.callee) { - form.function = this.threadActor.createValueGrip(this.obj.callee); - } - - // Shall we list this environment's bindings? - if (this.obj.type == "declarative") { - form.bindings = this._bindings(); - } - - return form; - }, - - /** - * Return the identifier bindings object as required by the remote protocol - * specification. - */ - _bindings: function EA_bindings() { - let bindings = { arguments: [], variables: {} }; - - // TODO: this part should be removed in favor of the commented-out part - // below when getVariableDescriptor lands (bug 725815). - if (typeof this.obj.getVariable != "function") { - //if (typeof this.obj.getVariableDescriptor != "function") { - return bindings; - } - - let parameterNames; - if (this.obj.callee) { - parameterNames = this.obj.callee.parameterNames; - } - for each (let name in parameterNames) { - let arg = {}; - // TODO: this part should be removed in favor of the commented-out part - // below when getVariableDescriptor lands (bug 725815). - let desc = { - value: this.obj.getVariable(name), - configurable: false, - writable: true, - enumerable: true - }; - - // let desc = this.obj.getVariableDescriptor(name); - let descForm = { - enumerable: true, - configurable: desc.configurable - }; - if ("value" in desc) { - descForm.value = this.threadActor.createValueGrip(desc.value); - descForm.writable = desc.writable; - } else { - descForm.get = this.threadActor.createValueGrip(desc.get); - descForm.set = this.threadActor.createValueGrip(desc.set); - } - arg[name] = descForm; - bindings.arguments.push(arg); - } - - for each (let name in this.obj.names()) { - if (bindings.arguments.some(function exists(element) { - return !!element[name]; - })) { - continue; - } - - // TODO: this part should be removed in favor of the commented-out part - // below when getVariableDescriptor lands. - let desc = { - configurable: false, - writable: true, - enumerable: true - }; - try { - desc.value = this.obj.getVariable(name); - } catch (e) { - // Avoid "Debugger scope is not live" errors for |arguments|, introduced - // in bug 746601. - if (name != "arguments") { - throw e; - } - } - //let desc = this.obj.getVariableDescriptor(name); - let descForm = { - enumerable: true, - configurable: desc.configurable - }; - if ("value" in desc) { - descForm.value = this.threadActor.createValueGrip(desc.value); - descForm.writable = desc.writable; - } else { - descForm.get = this.threadActor.createValueGrip(desc.get); - descForm.set = this.threadActor.createValueGrip(desc.set); - } - bindings.variables[name] = descForm; - } - - return bindings; - }, - - /** - * Handle a protocol request to change the value of a variable bound in this - * lexical environment. - * - * @param aRequest object - * The protocol request object. - */ - onAssign: function EA_onAssign(aRequest) { - // TODO: enable the commented-out part when getVariableDescriptor lands - // (bug 725815). - /*let desc = this.obj.getVariableDescriptor(aRequest.name); - - if (!desc.writable) { - return { error: "immutableBinding", - message: "Changing the value of an immutable binding is not " + - "allowed" }; - }*/ - - try { - this.obj.setVariable(aRequest.name, aRequest.value); - } catch (e) { - if (e instanceof Debugger.DebuggeeWouldRun) { - return { error: "threadWouldRun", - cause: e.cause ? e.cause : "setter", - message: "Assigning a value would cause the debuggee to run" }; - } - // This should never happen, so let it complain loudly if it does. - throw e; - } - return { from: this.actorID }; - }, - - /** - * Handle a protocol request to fully enumerate the bindings introduced by the - * lexical environment. - * - * @param aRequest object - * The protocol request object. - */ - onBindings: function EA_onBindings(aRequest) { - return { from: this.actorID, - bindings: this._bindings() }; - } -}; - -EnvironmentActor.prototype.requestTypes = { - "assign": EnvironmentActor.prototype.onAssign, - "bindings": EnvironmentActor.prototype.onBindings -}; - -/** - * Override the toString method in order to get more meaningful script output - * for debugging the debugger. - */ -Debugger.Script.prototype.toString = function() { - let output = ""; - if (this.url) { - output += this.url; - } - if (typeof this.startLine != "undefined") { - output += ":" + this.startLine; - if (this.lineCount && this.lineCount > 1) { - output += "-" + (this.startLine + this.lineCount - 1); - } - } - if (this.strictMode) { - output += ":strict"; - } - return output; -}; - -/** - * Helper property for quickly getting to the line number a stack frame is - * currently paused at. - */ -Object.defineProperty(Debugger.Frame.prototype, "line", { - configurable: true, - get: function() { - if (this.script) { - return this.script.getOffsetLine(this.offset); - } else { - return null; - } - } -}); - - -/** - * Creates an actor for handling chrome debugging. ChromeDebuggerActor is a - * thin wrapper over ThreadActor, slightly changing some of its behavior. - * - * @param aConnection object - * The DebuggerServerConnection with which this ChromeDebuggerActor - * is associated. (Currently unused, but required to make this - * constructor usable with addGlobalActor.) - * - * @param aHooks object - * An object with preNest and postNest methods for calling when entering - * and exiting a nested event loop and also addToParentPool and - * removeFromParentPool methods for handling the lifetime of actors that - * will outlive the thread, like breakpoints. - */ -function ChromeDebuggerActor(aConnection, aHooks) -{ - ThreadActor.call(this, aHooks); -} - -ChromeDebuggerActor.prototype = Object.create(ThreadActor.prototype); - -update(ChromeDebuggerActor.prototype, { - constructor: ChromeDebuggerActor, - - // A constant prefix that will be used to form the actor ID by the server. - actorPrefix: "chromeDebugger", - - /** - * Override the eligibility check for scripts and sources to make sure every - * script and source with a URL is stored when debugging chrome. - */ - _allowSource: function(aSourceURL) !!aSourceURL, - - /** - * An object that will be used by ThreadActors to tailor their behavior - * depending on the debugging context being required (chrome or content). - * The methods that this object provides must be bound to the ThreadActor - * before use. - */ - globalManager: { - findGlobals: function CDA_findGlobals() { - // Add every global known to the debugger as debuggee. - this.dbg.addAllGlobalsAsDebuggees(); - }, - - /** - * A function that the engine calls when a new global object has been - * created. - * - * @param aGlobal Debugger.Object - * The new global object that was created. - */ - onNewGlobal: function CDA_onNewGlobal(aGlobal) { - this.addDebuggee(aGlobal); - // Notify the client. - this.conn.send({ - from: this.actorID, - type: "newGlobal", - // TODO: after bug 801084 lands see if we need to JSONify this. - hostAnnotations: aGlobal.hostAnnotations - }); - } - } -}); - - -/** - * Manages the sources for a thread. Handles source maps, locations in the - * sources, etc for ThreadActors. - */ -function ThreadSources(aThreadActor, aUseSourceMaps, aAllowPredicate, - aOnNewSource) { - this._thread = aThreadActor; - this._useSourceMaps = aUseSourceMaps; - this._allow = aAllowPredicate; - this._onNewSource = aOnNewSource; - - // source map URL --> promise of SourceMapConsumer - this._sourceMaps = Object.create(null); - // generated source url --> promise of SourceMapConsumer - this._sourceMapsByGeneratedSource = Object.create(null); - // original source url --> promise of SourceMapConsumer - this._sourceMapsByOriginalSource = Object.create(null); - // source url --> SourceActor - this._sourceActors = Object.create(null); - // original url --> generated url - this._generatedUrlsByOriginalUrl = Object.create(null); -} - -/** - * Must be a class property because it needs to persist across reloads, same as - * the breakpoint store. - */ -ThreadSources._blackBoxedSources = new Set(); - -ThreadSources.prototype = { - /** - * Return the source actor representing |aURL|, creating one if none - * exists already. Returns null if |aURL| is not allowed by the 'allow' - * predicate. - * - * Right now this takes a URL, but in the future it should - * take a Debugger.Source. See bug 637572. - * - * @param String aURL - * The source URL. - * @param optional SourceMapConsumer aSourceMap - * The source map that introduced this source, if any. - * @returns a SourceActor representing the source at aURL or null. - */ - source: function TS_source(aURL, aSourceMap=null) { - if (!this._allow(aURL)) { - return null; - } - - if (aURL in this._sourceActors) { - return this._sourceActors[aURL]; - } - - let actor = new SourceActor(aURL, this._thread, aSourceMap); - this._thread.threadLifetimePool.addActor(actor); - this._sourceActors[aURL] = actor; - try { - this._onNewSource(actor); - } catch (e) { - reportError(e); - } - return actor; - }, - - /** - * Return a promise of an array of source actors representing all the - * sources of |aScript|. - * - * If source map handling is enabled and |aScript| has a source map, then - * use it to find all of |aScript|'s *original* sources; return a promise - * of an array of source actors for those. - */ - sourcesForScript: function TS_sourcesForScript(aScript) { - if (!this._useSourceMaps || !aScript.sourceMapURL) { - return resolve([this.source(aScript.url)].filter(isNotNull)); - } - - return this.sourceMap(aScript) - .then((aSourceMap) => { - return [ - this.source(s, aSourceMap) for (s of aSourceMap.sources) - ]; - }) - .then(null, (e) => { - reportError(e); - delete this._sourceMaps[this._normalize(aScript.sourceMapURL, aScript.url)]; - delete this._sourceMapsByGeneratedSource[aScript.url]; - return [this.source(aScript.url)]; - }) - .then(function (aSources) { - return aSources.filter(isNotNull); - }); - }, - - /** - * Return a promise of a SourceMapConsumer for the source map for - * |aScript|; if we already have such a promise extant, return that. - * |aScript| must have a non-null sourceMapURL. - */ - sourceMap: function TS_sourceMap(aScript) { - if (aScript.url in this._sourceMapsByGeneratedSource) { - return this._sourceMapsByGeneratedSource[aScript.url]; - } - dbg_assert(aScript.sourceMapURL); - let sourceMapURL = this._normalize(aScript.sourceMapURL, aScript.url); - let map = this._fetchSourceMap(sourceMapURL) - .then((aSourceMap) => { - for (let s of aSourceMap.sources) { - this._generatedUrlsByOriginalUrl[s] = aScript.url; - this._sourceMapsByOriginalSource[s] = resolve(aSourceMap); - } - return aSourceMap; - }); - this._sourceMapsByGeneratedSource[aScript.url] = map; - return map; - }, - - /** - * Return a promise of a SourceMapConsumer for the source map located at - * |aAbsSourceMapURL|, which must be absolute. If there is already such a - * promise extant, return it. - */ - _fetchSourceMap: function TS__fetchSourceMap(aAbsSourceMapURL) { - if (aAbsSourceMapURL in this._sourceMaps) { - return this._sourceMaps[aAbsSourceMapURL]; - } else { - let promise = fetch(aAbsSourceMapURL).then((rawSourceMap) => { - let map = new SourceMapConsumer(rawSourceMap); - let base = aAbsSourceMapURL.replace(/\/[^\/]+$/, '/'); - if (base.indexOf("data:") !== 0) { - map.sourceRoot = map.sourceRoot - ? this._normalize(map.sourceRoot, base) - : base; - } - return map; - }); - this._sourceMaps[aAbsSourceMapURL] = promise; - return promise; - } - }, - - /** - * Returns a promise of the location in the original source if the source is - * source mapped, otherwise a promise of the same location. - * - * TODO bug 637572: take/return a column - */ - getOriginalLocation: function TS_getOriginalLocation(aSourceUrl, aLine) { - if (aSourceUrl in this._sourceMapsByGeneratedSource) { - return this._sourceMapsByGeneratedSource[aSourceUrl] - .then(function (aSourceMap) { - let { source, line } = aSourceMap.originalPositionFor({ - source: aSourceUrl, - line: aLine, - column: Infinity - }); - return { - url: source, - line: line - }; - }); - } - - // No source map - return resolve({ - url: aSourceUrl, - line: aLine - }); - }, - - /** - * Returns a promise of the location in the generated source corresponding to - * the original source and line given. - * - * When we pass a script S representing generated code to |sourceMap|, - * above, that returns a promise P. The process of resolving P populates - * the tables this function uses; thus, it won't know that S's original - * source URLs map to S until P is resolved. - * - * TODO bug 637572: take/return a column - */ - getGeneratedLocation: function TS_getGeneratedLocation(aSourceUrl, aLine) { - if (aSourceUrl in this._sourceMapsByOriginalSource) { - return this._sourceMapsByOriginalSource[aSourceUrl] - .then((aSourceMap) => { - let { line } = aSourceMap.generatedPositionFor({ - source: aSourceUrl, - line: aLine, - column: Infinity - }); - return { - url: this._generatedUrlsByOriginalUrl[aSourceUrl], - line: line - }; - }); - } - - // No source map - return resolve({ - url: aSourceUrl, - line: aLine - }); - }, - - /** - * Returns true if URL for the given source is black boxed. - * - * @param aURL String - * The URL of the source which we are checking whether it is black - * boxed or not. - */ - isBlackBoxed: function TS_isBlackBoxed(aURL) { - return ThreadSources._blackBoxedSources.has(aURL); - }, - - /** - * Add the given source URL to the set of sources that are black boxed. If the - * thread is currently paused and we are black boxing the yougest frame's - * source, this will force a step. - * - * @param aURL String - * The URL of the source which we are black boxing. - */ - blackBox: function TS_blackBox(aURL) { - ThreadSources._blackBoxedSources.add(aURL); - }, - - /** - * Remove the given source URL to the set of sources that are black boxed. - * - * @param aURL String - * The URL of the source which we are no longer black boxing. - */ - unblackBox: function TS_unblackBox(aURL) { - ThreadSources._blackBoxedSources.delete(aURL); - }, - - /** - * Normalize multiple relative paths towards the base paths on the right. - */ - _normalize: function TS__normalize(...aURLs) { - dbg_assert(aURLs.length > 1); - let base = Services.io.newURI(aURLs.pop(), null, null); - let url; - while ((url = aURLs.pop())) { - base = Services.io.newURI(url, null, base); - } - return base.spec; - }, - - iter: function TS_iter() { - for (let url in this._sourceActors) { - yield this._sourceActors[url]; - } - } -}; - -// Utility functions. - -/** - * Utility function for updating an object with the properties of another - * object. - * - * @param aTarget Object - * The object being updated. - * @param aNewAttrs Object - * The new attributes being set on the target. - */ -function update(aTarget, aNewAttrs) { - for (let key in aNewAttrs) { - let desc = Object.getOwnPropertyDescriptor(aNewAttrs, key); - - if (desc) { - Object.defineProperty(aTarget, key, desc); - } - } -} - -/** - * Returns true if its argument is not null. - */ -function isNotNull(aThing) { - return aThing !== null; -} - -/** - * Performs a request to load the desired URL and returns a promise. - * - * @param aURL String - * The URL we will request. - * @returns Promise - * A promise of the document at that URL, as a string. - * - * XXX: It may be better to use nsITraceableChannel to get to the sources - * without relying on caching when we can (not for eval, etc.): - * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/ - */ -function fetch(aURL, aOptions={ loadFromCache: true }) { - let deferred = defer(); - let scheme; - let url = aURL.split(" -> ").pop(); - let charset; - let filePath = url; - // try { - // scheme = Services.io.extractScheme(url); - // } catch (e) { - // In the xpcshell tests, the script url is the absolute path of the test - // file, which will make a malformed URI error be thrown. Add the file - // scheme prefix ourselves. - url = "file://" + url; - // scheme = Services.io.extractScheme(url); - // } - scheme = "file"; - - switch (scheme) { - case "file": - case "chrome": - case "resource": - try { - // NetUtil.asyncFetch(url, function onFetch(aStream, aStatus) { - // if (!Components.isSuccessCode(aStatus)) { - // deferred.reject("Request failed: " + url); - // return; - // } - let cc = globalDebuggee.cc; - let fileUtils = cc.FileUtils.getInstance(); - let source = fileUtils.getStringFromFile(filePath);//NetUtil.readInputStreamToString(aStream, aStream.available()); - if (!source) - { - deferred.reject("Request failed: " + url); - } - else - { - deferred.resolve(source); - } - // aStream.close(); - // }); - } catch (ex) { - deferred.reject("Request failed: " + url); - } - break; - - default: - let channel; - try { - channel = Services.io.newChannel(url, null, null); - } catch (e if e.name == "NS_ERROR_UNKNOWN_PROTOCOL") { - // On Windows xpcshell tests, c:/foo/bar can pass as a valid URL, but - // newChannel won't be able to handle it. - url = "file:///" + url; - channel = Services.io.newChannel(url, null, null); - } - let chunks = []; - let streamListener = { - onStartRequest: function(aRequest, aContext, aStatusCode) { - if (!Components.isSuccessCode(aStatusCode)) { - deferred.reject("Request failed: " + url); - } - }, - onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) { - chunks.push(NetUtil.readInputStreamToString(aStream, aCount)); - }, - onStopRequest: function(aRequest, aContext, aStatusCode) { - if (!Components.isSuccessCode(aStatusCode)) { - deferred.reject("Request failed: " + url); - return; - } - - charset = channel.contentCharset; - deferred.resolve(chunks.join("")); - } - }; - - channel.loadFlags = aOptions.loadFromCache - ? channel.LOAD_FROM_CACHE - : channel.LOAD_BYPASS_CACHE; - channel.asyncOpen(streamListener, null); - break; - } - - return deferred.promise.then(function (source) { - return convertToUnicode(source, charset); - }); -} - -/** - * Convert a given string, encoded in a given character set, to unicode. - * - * @param string aString - * A string. - * @param string aCharset - * A character set. - */ -function convertToUnicode(aString, aCharset=null) { - // Decoding primitives. - // let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] - // .createInstance(Ci.nsIScriptableUnicodeConverter); - // try { - // converter.charset = aCharset || "UTF-8"; - // return converter.ConvertToUnicode(aString); - // } catch(e) { - return aString; - // } -} - -/** - * Report the given error in the error console and to stdout. - */ -function reportError(aError) { - // Cu.reportError(aError); - dumpn(aError.message + ":\n" + aError.stack); -} diff --git a/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id b/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id new file mode 100644 index 0000000000..8f144050f7 --- /dev/null +++ b/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id @@ -0,0 +1 @@ +c318c72ef4ee9c141e846d261e63250a0328bca4 \ No newline at end of file diff --git a/cocos/scripting/javascript/script/debugger/main.js b/cocos/scripting/javascript/script/debugger/main.js index f08009ade6..c6437e7922 100644 --- a/cocos/scripting/javascript/script/debugger/main.js +++ b/cocos/scripting/javascript/script/debugger/main.js @@ -10,26 +10,27 @@ * debugging global. */ -//const Ci = Components.interfaces; -//const Cc = Components.classes; -//const CC = Components.Constructor; -//const Cu = Components.utils; -//const Cr = Components.results; -//const DBG_STRINGS_URI = "chrome://global/locale/devtools/debugger.properties"; -// -//Cu.import("resource://gre/modules/Services.jsm"); -//Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -//let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log"); -// -//Cu.import("resource://gre/modules/jsdebugger.jsm"); -//addDebuggerToGlobal(this); -// -//Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js"); -//const { defer, resolve, reject, all } = Promise; -// -//Cu.import("resource://gre/modules/devtools/SourceMap.jsm"); -// -//loadSubScript.call(this, "resource://gre/modules/devtools/DevToolsUtils.js"); +/* +const Ci = Components.interfaces; +const Cc = Components.classes; +const CC = Components.Constructor; +const Cu = Components.utils; +const Cr = Components.results; +const DBG_STRINGS_URI = "chrome://global/locale/devtools/debugger.properties"; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log"); + +Cu.import("resource://gre/modules/jsdebugger.jsm"); +addDebuggerToGlobal(this); + +loadSubScript.call(this, "resource://gre/modules/commonjs/sdk/core/promise.js"); + +Cu.import("resource://gre/modules/devtools/SourceMap.jsm"); + +loadSubScript.call(this, "resource://gre/modules/devtools/DevToolsUtils.js"); +*/ let wantLogging = true; let debuggerServer = null; @@ -127,7 +128,7 @@ var DebuggerServer = { _initialized: false, _transportInitialized: false, xpcInspector: null, - _transport: null, + _transport: null, // James added // Number of currently open TCP connections. _socketConnections: 0, // Map of global actor names to actor constructors provided by extensions. @@ -145,6 +146,13 @@ var DebuggerServer = { */ _allowConnection: null, + /** + * The windowtype of the chrome window to use for actors that use the global + * window (i.e the global style editor). Set this to your main window type, + * for example "navigator:browser". + */ + chromeWindowType: null, + /** * Prompt the user to accept or decline the incoming connection. This is the * default implementation that products embedding the debugger server may @@ -217,11 +225,11 @@ var DebuggerServer = { get initialized() this._initialized, /** - * Performs cleanup tasks before shutting down the debugger server, if no - * connections are currently open. Such tasks include clearing any actor - * constructors added at runtime. This method should be called whenever a - * debugger server is no longer useful, to avoid memory leaks. After this - * method returns, the debugger server must be initialized again before use. + * Performs cleanup tasks before shutting down the debugger server. Such tasks + * include clearing any actor constructors added at runtime. This method + * should be called whenever a debugger server is no longer useful, to avoid + * memory leaks. After this method returns, the debugger server must be + * initialized again before use. */ destroy: function DS_destroy() { if (!this._initialized) { @@ -302,6 +310,7 @@ var DebuggerServer = { * Install Firefox-specific actors. */ addBrowserActors: function DS_addBrowserActors() { + this.chromeWindowType = "navigator:browser"; this.addActors("resource://gre/modules/devtools/server/actors/webbrowser.js"); this.addActors("resource://gre/modules/devtools/server/actors/script.js"); this.addGlobalActor(this.ChromeDebuggerActor, "chromeDebugger"); @@ -313,6 +322,27 @@ var DebuggerServer = { this.addActors("resource://gre/modules/devtools/server/actors/styleeditor.js"); this.addActors("resource://gre/modules/devtools/server/actors/webapps.js"); this.registerModule("devtools/server/actors/inspector"); + this.registerModule("devtools/server/actors/tracer"); + }, + + /** + * Install tab actors in documents loaded in content childs + */ + addChildActors: function () { + // In case of apps being loaded in parent process, DebuggerServer is already + // initialized and browser actors are already loaded, + // but childtab.js hasn't been loaded yet. + if (!("BrowserTabActor" in this)) { + this.addActors("resource://gre/modules/devtools/server/actors/webbrowser.js"); + this.addActors("resource://gre/modules/devtools/server/actors/script.js"); + this.addActors("resource://gre/modules/devtools/server/actors/webconsole.js"); + this.addActors("resource://gre/modules/devtools/server/actors/gcli.js"); + this.addActors("resource://gre/modules/devtools/server/actors/styleeditor.js"); + this.registerModule("devtools/server/actors/inspector"); + } + if (!("ContentTabActor" in DebuggerServer)) { + this.addActors("resource://gre/modules/devtools/server/actors/childtab.js"); + } }, /** @@ -339,7 +369,6 @@ var DebuggerServer = { // } let flags = 0; - try { let socket = new ServerSocket(aPort, flags, 4); socket.asyncListen(this); @@ -381,16 +410,19 @@ var DebuggerServer = { * transport. This connection results in straightforward calls to the onPacket * handlers of each side. * + * @param aPrefix string [optional] + * If given, all actors in this connection will have names starting + * with |aPrefix + ':'|. * @returns a client-side DebuggerTransport for communicating with - * the newly-created connection. + * the newly-created connection. */ - connectPipe: function DS_connectPipe() { + connectPipe: function DS_connectPipe(aPrefix) { this._checkInit(); let serverTransport = new LocalDebuggerTransport; let clientTransport = new LocalDebuggerTransport(serverTransport); serverTransport.other = clientTransport; - let connection = this._onConnection(serverTransport); + let connection = this._onConnection(serverTransport, aPrefix); // I'm putting this here because I trust you. // @@ -412,6 +444,22 @@ var DebuggerServer = { return clientTransport; }, + /** + * In a content child process, create a new connection that exchanges + * nsIMessageSender messages with our parent process. + * + * @param aPrefix + * The prefix we should use in our nsIMessageSender message names and + * actor names. This connection will use messages named + * "debug::packet", and all its actors will have names + * beginning with ":". + */ + connectToParent: function(aPrefix, aMessageManager) { + this._checkInit(); + + let transport = new ChildDebuggerTransport(aMessageManager, aPrefix); + return this._onConnection(transport, aPrefix, true); + }, // nsIServerSocketListener implementation @@ -446,23 +494,36 @@ var DebuggerServer = { }, /** - * Create a new debugger connection for the given transport. Called - * after connectPipe() or after an incoming socket connection. + * Create a new debugger connection for the given transport. Called after + * connectPipe(), from connectToParent, or from an incoming socket + * connection handler. + * + * If present, |aForwardingPrefix| is a forwarding prefix that a parent + * server is using to recognizes messages intended for this server. Ensure + * that all our actors have names beginning with |aForwardingPrefix + ':'|. + * In particular, the root actor's name will be |aForwardingPrefix + ':root'|. */ - _onConnection: function DS_onConnection(aTransport) { - log("DebuggerServer._onConnection...."); - + _onConnection: function DS_onConnection(aTransport, aForwardingPrefix, aNoRootActor = false) { + let connID; this._transport = aTransport; - - let connID = "conn" + this._nextConnID++ + '.'; + if (aForwardingPrefix) { + connID = aForwardingPrefix + ":"; + } else { + connID = "conn" + this._nextConnID++ + '.'; + } let conn = new DebuggerServerConnection(connID, aTransport); this._connections[connID] = conn; // Create a root actor for the connection and send the hello packet. - conn.rootActor = this.createRootActor(conn); - conn.addActor(conn.rootActor); - - aTransport.send(conn.rootActor.sayHello()); + if (!aNoRootActor) { + conn.rootActor = this.createRootActor(conn); + if (aForwardingPrefix) + conn.rootActor.actorID = aForwardingPrefix + ":root"; + else + conn.rootActor.actorID = "root"; + conn.addActor(conn.rootActor); + aTransport.send(conn.rootActor.sayHello()); + } aTransport.ready(); return conn; @@ -676,6 +737,14 @@ function DebuggerServerConnection(aPrefix, aTransport) this._actorPool = new ActorPool(this); this._extraPools = []; + + /* + * We can forward packets to other servers, if the actors on that server + * all use a distinct prefix on their names. This is a map from prefixes + * to transports: it maps a prefix P to a transport T if T conveys + * packets to the server whose actors' names all begin with P + ":". + */ + this._forwardingPrefixes = new Map; } DebuggerServerConnection.prototype = { @@ -788,6 +857,35 @@ DebuggerServerConnection.prototype = { }; }, + /* Forwarding packets to other transports based on actor name prefixes. */ + + /* + * Arrange to forward packets to another server. This is how we + * forward debugging connections to child processes. + * + * If we receive a packet for an actor whose name begins with |aPrefix| + * followed by ':', then we will forward that packet to |aTransport|. + * + * This overrides any prior forwarding for |aPrefix|. + * + * @param aPrefix string + * The actor name prefix, not including the ':'. + * @param aTransport object + * A packet transport to which we should forward packets to actors + * whose names begin with |(aPrefix + ':').| + */ + setForwarding: function(aPrefix, aTransport) { + this._forwardingPrefixes.set(aPrefix, aTransport); + }, + + /* + * Stop forwarding messages to actors whose names begin with + * |aPrefix+':'|. Such messages will now elicit 'noSuchActor' errors. + */ + cancelForwarding: function(aPrefix) { + this._forwardingPrefixes.delete(aPrefix); + }, + // Transport hooks. /** @@ -797,6 +895,26 @@ DebuggerServerConnection.prototype = { * The incoming packet. */ onPacket: function DSC_onPacket(aPacket) { + // If the actor's name begins with a prefix we've been asked to + // forward, do so. + // + // Note that the presence of a prefix alone doesn't indicate that + // forwarding is needed: in DebuggerServerConnection instances in child + // processes, every actor has a prefixed name. + + log("aPacket: " + aPacket); + + if (this._forwardingPrefixes.size > 0) { + let colon = aPacket.to.indexOf(':'); + if (colon >= 0) { + let forwardTo = this._forwardingPrefixes.get(aPacket.to.substring(0, colon)); + if (forwardTo) { + forwardTo.send(aPacket); + return; + } + } + } + let actor = this.getActor(aPacket.to); if (!actor) { this.transport.send({ from: aPacket.to ? aPacket.to : "root", @@ -824,7 +942,6 @@ DebuggerServerConnection.prototype = { } var ret = null; - // log("actor.requestTypes: "+actor.requestTypes+", cb: "+actor.requestTypes[aPacket.type]); // Dispatch the request to the actor. if (actor.requestTypes && actor.requestTypes[aPacket.type]) { try { @@ -851,18 +968,18 @@ DebuggerServerConnection.prototype = { } resolve(ret) - .then(null, (e) => { - return this._unknownError( - "error occurred while processing '" + aPacket.type, - e); - }) .then(function (aResponse) { if (!aResponse.from) { aResponse.from = aPacket.to; } return aResponse; }) - .then(this.transport.send.bind(this.transport)); + .then(this.transport.send.bind(this.transport)) + .then(null, (e) => { + return this._unknownError( + "error occurred while processing '" + aPacket.type, + e); + }); }, /** diff --git a/cocos/scripting/javascript/script/debugger/transport.js b/cocos/scripting/javascript/script/debugger/transport.js index 8676e367a8..b5de443a06 100644 --- a/cocos/scripting/javascript/script/debugger/transport.js +++ b/cocos/scripting/javascript/script/debugger/transport.js @@ -11,6 +11,8 @@ * An adapter that handles data transfers between the debugger client and * server. It can work with both nsIPipe and nsIServerSocket transports so * long as the properly created input and output streams are specified. + * (However, for intra-process connections, LocalDebuggerTransport, below, + * is more efficient than using an nsIPipe pair with DebuggerTransport.) * * @param aInput nsIInputStream * The input stream. @@ -20,12 +22,12 @@ * Given a DebuggerTransport instance dt: * 1) Set dt.hooks to a packet handler object (described below). * 2) Call dt.ready() to begin watching for input packets. - * 3) Send packets as you please, and handle incoming packets passed to - * hook.onPacket. + * 3) Call dt.send() to send packets as you please, and handle incoming + * packets passed to hook.onPacket. * 4) Call dt.close() to close the connection, and disengage from the event * loop. * - * A packet handler object is an object with two methods: + * A packet handler is an object with two methods: * * - onPacket(packet) - called when we have received a complete packet. * |Packet| is the parsed form of the packet --- a JavaScript value, not @@ -226,10 +228,11 @@ LocalDebuggerTransport.prototype = { send: function LDT_send(aPacket) { let serial = this._serial.count++; if (wantLogging) { - if (aPacket.to) { - dumpn("Packet " + serial + " sent to " + uneval(aPacket.to)); - } else if (aPacket.from) { + /* Check 'from' first, as 'echo' packets have both. */ + if (aPacket.from) { dumpn("Packet " + serial + " sent from " + uneval(aPacket.from)); + } else if (aPacket.to) { + dumpn("Packet " + serial + " sent to " + uneval(aPacket.to)); } } this._deepFreeze(aPacket); @@ -259,7 +262,11 @@ LocalDebuggerTransport.prototype = { other.close(); } if (this.hooks) { - this.hooks.onClosed(); + try { + this.hooks.onClosed(); + } catch(ex) { + Components.utils.reportError(ex); + } this.hooks = null; } }, @@ -286,3 +293,50 @@ LocalDebuggerTransport.prototype = { } } }; + +/** + * A transport for the debugging protocol that uses nsIMessageSenders to + * exchange packets with servers running in child processes. + * + * In the parent process, |aSender| should be the nsIMessageSender for the + * child process. In a child process, |aSender| should be the child process + * message manager, which sends packets to the parent. + * + * aPrefix is a string included in the message names, to distinguish + * multiple servers running in the same child process. + * + * This transport exchanges messages named 'debug::packet', where + * is |aPrefix|, whose data is the protocol packet. + */ +function ChildDebuggerTransport(aSender, aPrefix) { + this._sender = aSender.QueryInterface(Components.interfaces.nsIMessageSender); + this._messageName = "debug:" + aPrefix + ":packet"; +} + +/* + * To avoid confusion, we use 'message' to mean something that + * nsIMessageSender conveys, and 'packet' to mean a remote debugging + * protocol packet. + */ +ChildDebuggerTransport.prototype = { + constructor: ChildDebuggerTransport, + + hooks: null, + + ready: function () { + this._sender.addMessageListener(this._messageName, this); + }, + + close: function () { + this._sender.removeMessageListener(this._messageName, this); + this.hooks.onClosed(); + }, + + receiveMessage: function ({data}) { + this.hooks.onPacket(data); + }, + + send: function (packet) { + this._sender.sendAsyncMessage(this._messageName, packet); + } +}; From d2fc29dbfad3ba3d602949df816c8f3f23f2692e Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 10:29:20 +0800 Subject: [PATCH 085/144] [sp v25] Updating Debugger script. --- .../javascript/script/debugger/actors/script.js.REMOVED.git-id | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id b/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id index 8f144050f7..802edb4902 100644 --- a/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id +++ b/cocos/scripting/javascript/script/debugger/actors/script.js.REMOVED.git-id @@ -1 +1 @@ -c318c72ef4ee9c141e846d261e63250a0328bca4 \ No newline at end of file +85c713e3bdd74f54afb60036b9c11f754c55e267 \ No newline at end of file From 541a0478acbdc9a7574a2b5d27e32b0a0ac9cdfa Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 10:29:49 +0800 Subject: [PATCH 086/144] [sp v25] Removing unused comments in main.js --- cocos/scripting/javascript/script/debugger/main.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/cocos/scripting/javascript/script/debugger/main.js b/cocos/scripting/javascript/script/debugger/main.js index c6437e7922..2c57735dbf 100644 --- a/cocos/scripting/javascript/script/debugger/main.js +++ b/cocos/scripting/javascript/script/debugger/main.js @@ -902,8 +902,6 @@ DebuggerServerConnection.prototype = { // forwarding is needed: in DebuggerServerConnection instances in child // processes, every actor has a prefixed name. - log("aPacket: " + aPacket); - if (this._forwardingPrefixes.size > 0) { let colon = aPacket.to.indexOf(':'); if (colon >= 0) { From 0f7a99f8986c7e7d3961aab6f4c057c79dcec0b7 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 11:07:33 +0800 Subject: [PATCH 087/144] [sp v25] Don't use 'using namespace std;' to make android build happy. --- .../javascript/bindings/ScriptingCore.cpp | 20 +++++++++---------- .../javascript/bindings/ScriptingCore.h | 5 ++--- .../bindings/network/XMLHTTPRequest.h | 4 ++-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index 6a8ac7dd98..9756be492a 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -54,9 +54,9 @@ #define BYTE_CODE_FILE_EXT ".jsc" -static string inData; -static string outData; -static vector g_queue; +static std::string inData; +static std::string outData; +static std::vector g_queue; static std::mutex g_qMutex; static std::mutex g_rwMutex; static int clientSocket = -1; @@ -1964,8 +1964,8 @@ void SimpleRunLoop::update(float dt) while (size > 0) { g_qMutex.lock(); - vector::iterator first = g_queue.begin(); - string str = *first; + auto first = g_queue.begin(); + std::string str = *first; g_queue.erase(first); size = g_queue.size(); g_qMutex.unlock(); @@ -1974,7 +1974,7 @@ void SimpleRunLoop::update(float dt) } } -void ScriptingCore::debugProcessInput(string str) +void ScriptingCore::debugProcessInput(const std::string& str) { JSAutoCompartment ac(_cx, _debugGlobal); @@ -1994,8 +1994,8 @@ static bool NS_ProcessNextEvent() while (size > 0) { g_qMutex.lock(); - vector::iterator first = g_queue.begin(); - string str = *first; + auto first = g_queue.begin(); + std::string str = *first; g_queue.erase(first); size = g_queue.size(); g_qMutex.unlock(); @@ -2060,7 +2060,7 @@ static void _clientSocketWriteAndClearString(std::string& s) s.clear(); } -static void processInput(string data) { +static void processInput(const std::string& data) { std::lock_guard lk(g_qMutex); g_queue.push_back(data); } @@ -2087,7 +2087,7 @@ static void serverEntryPoint(void) hints.ai_socktype = SOCK_STREAM; // TCP stream sockets hints.ai_flags = AI_PASSIVE; // fill in my IP for me - stringstream portstr; + std::stringstream portstr; portstr << JSB_DEBUGGER_PORT; int err = 0; diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.h b/cocos/scripting/javascript/bindings/ScriptingCore.h index 769be86cfa..8df12fddc6 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.h +++ b/cocos/scripting/javascript/bindings/ScriptingCore.h @@ -21,7 +21,6 @@ void js_log(const char *format, ...); using namespace cocos2d; -using namespace std; typedef void (*sc_register_sth)(JSContext* cx, JSObject* global); @@ -189,7 +188,7 @@ public: /** * enable the debug environment */ - void debugProcessInput(string str); + void debugProcessInput(const std::string& str); void enableDebugger(); JSObject* getDebugGlobal() { return _debugGlobal; } JSObject* getGlobalObject() { return _global; } @@ -230,7 +229,7 @@ JSBool jsval_to_FontDefinition( JSContext *cx, jsval vp, FontDefinition* ret ); jsval int32_to_jsval( JSContext *cx, int32_t l); jsval uint32_to_jsval( JSContext *cx, uint32_t number ); jsval long_long_to_jsval(JSContext* cx, long long v); -jsval std_string_to_jsval(JSContext* cx, const string& v); +jsval std_string_to_jsval(JSContext* cx, const std::string& v); jsval c_string_to_jsval(JSContext* cx, const char* v, size_t length = -1); jsval ccpoint_to_jsval(JSContext* cx, const Point& v); jsval ccrect_to_jsval(JSContext* cx, const Rect& v); diff --git a/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.h b/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.h index 861e0a2536..93951313f4 100644 --- a/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.h +++ b/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.h @@ -105,8 +105,8 @@ private: network::HttpRequest* _httpRequest; bool _isNetwork; bool _withCredentialsValue; - std::map _httpHeader; - std::map _requestHeader; + std::map _httpHeader; + std::map _requestHeader; }; #endif From 69b02060187e5b51240484751bd77c0864053372 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 11:24:43 +0800 Subject: [PATCH 088/144] issue #2826: Updating vs project to link mozjs-25.lib --- .../AssetsManagerTest/proj.win32/AssetsManagerTest.vcxproj | 4 ++-- .../Javascript/CocosDragonJS/proj.win32/CocosDragonJS.vcxproj | 4 ++-- .../Javascript/CrystalCraze/proj.win32/CrystalCraze.vcxproj | 4 ++-- .../Javascript/MoonWarriors/proj.win32/MoonWarriors.vcxproj | 4 ++-- .../TestJavascript/proj.win32/TestJavascript.vcxproj | 4 ++-- .../WatermelonWithMe/proj.win32/WatermelonWithMe.vcxproj | 4 ++-- template/multi-platform-js/proj.win32/HelloJavascript.vcxproj | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/samples/Cpp/AssetsManagerTest/proj.win32/AssetsManagerTest.vcxproj b/samples/Cpp/AssetsManagerTest/proj.win32/AssetsManagerTest.vcxproj index b46bf264ae..7851565229 100644 --- a/samples/Cpp/AssetsManagerTest/proj.win32/AssetsManagerTest.vcxproj +++ b/samples/Cpp/AssetsManagerTest/proj.win32/AssetsManagerTest.vcxproj @@ -102,7 +102,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;libcurl_imp.lib;%(AdditionalDependencies) + mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;libcurl_imp.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -157,7 +157,7 @@ xcopy /Y /Q "$(EngineRoot)external\spidermonkey\prebuilt\win32\*.*" "$(OutDir)" - mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;libcurl_imp.lib;%(AdditionalDependencies) + mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;libcurl_imp.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 diff --git a/samples/Javascript/CocosDragonJS/proj.win32/CocosDragonJS.vcxproj b/samples/Javascript/CocosDragonJS/proj.win32/CocosDragonJS.vcxproj index 8483cb7237..2e7cc9a5d5 100644 --- a/samples/Javascript/CocosDragonJS/proj.win32/CocosDragonJS.vcxproj +++ b/samples/Javascript/CocosDragonJS/proj.win32/CocosDragonJS.vcxproj @@ -102,7 +102,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -157,7 +157,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 diff --git a/samples/Javascript/CrystalCraze/proj.win32/CrystalCraze.vcxproj b/samples/Javascript/CrystalCraze/proj.win32/CrystalCraze.vcxproj index 6194bc0354..36fd882002 100644 --- a/samples/Javascript/CrystalCraze/proj.win32/CrystalCraze.vcxproj +++ b/samples/Javascript/CrystalCraze/proj.win32/CrystalCraze.vcxproj @@ -102,7 +102,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -157,7 +157,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 diff --git a/samples/Javascript/MoonWarriors/proj.win32/MoonWarriors.vcxproj b/samples/Javascript/MoonWarriors/proj.win32/MoonWarriors.vcxproj index 08efa5fdba..d0dfa15e88 100644 --- a/samples/Javascript/MoonWarriors/proj.win32/MoonWarriors.vcxproj +++ b/samples/Javascript/MoonWarriors/proj.win32/MoonWarriors.vcxproj @@ -102,7 +102,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -155,7 +155,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 diff --git a/samples/Javascript/TestJavascript/proj.win32/TestJavascript.vcxproj b/samples/Javascript/TestJavascript/proj.win32/TestJavascript.vcxproj index 1af52eccb0..f6e517fc8f 100644 --- a/samples/Javascript/TestJavascript/proj.win32/TestJavascript.vcxproj +++ b/samples/Javascript/TestJavascript/proj.win32/TestJavascript.vcxproj @@ -103,7 +103,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -159,7 +159,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 diff --git a/samples/Javascript/WatermelonWithMe/proj.win32/WatermelonWithMe.vcxproj b/samples/Javascript/WatermelonWithMe/proj.win32/WatermelonWithMe.vcxproj index 48f07febfb..0f76fa0e57 100644 --- a/samples/Javascript/WatermelonWithMe/proj.win32/WatermelonWithMe.vcxproj +++ b/samples/Javascript/WatermelonWithMe/proj.win32/WatermelonWithMe.vcxproj @@ -102,7 +102,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -157,7 +157,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\spidermonkey\prebuilt\win32\*.*" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 diff --git a/template/multi-platform-js/proj.win32/HelloJavascript.vcxproj b/template/multi-platform-js/proj.win32/HelloJavascript.vcxproj index 26bab7731b..35da6b1ee0 100644 --- a/template/multi-platform-js/proj.win32/HelloJavascript.vcxproj +++ b/template/multi-platform-js/proj.win32/HelloJavascript.vcxproj @@ -102,7 +102,7 @@ xcopy /Y /Q "$(EngineRoot)external\spidermonkey\prebuilt\win32\*.*" "$(OutDir)" xcopy /Y /Q "$(EngineRoot)external\websockets\prebuilt\win32\*.*" "$(OutDir)" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -157,7 +157,7 @@ xcopy /Y /Q "$(EngineRoot)external\spidermonkey\prebuilt\win32\*.*" "$(OutDir)" xcopy /Y /Q "$(EngineRoot)external\websockets\prebuilt\win32\*.*" "$(OutDir)" - libcurl_imp.lib;mozjs-23.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) + libcurl_imp.lib;mozjs-25.0.lib;ws2_32.lib;sqlite3.lib;websockets.lib;%(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) Windows MachineX86 From c116d070d30aeaea499dd97fb81a4b9a6ad722d5 Mon Sep 17 00:00:00 2001 From: dingpinglv Date: Thu, 31 Oct 2013 14:16:42 +0800 Subject: [PATCH 089/144] Closed #3048: cc.rect can receiving different type parameters now --- cocos/scripting/javascript/script/jsb_cocos2d.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cocos/scripting/javascript/script/jsb_cocos2d.js b/cocos/scripting/javascript/script/jsb_cocos2d.js index 684eb386d9..3362e78650 100644 --- a/cocos/scripting/javascript/script/jsb_cocos2d.js +++ b/cocos/scripting/javascript/script/jsb_cocos2d.js @@ -235,7 +235,19 @@ cc.sizeEqualToSize = function (size1, size2) // cc.rect = function(x,y,w,h) { - return {x:x, y:y, width:w, height:h}; + if (arguments.length === 0) + return { x: 0, y: 0, width: 0, height: 0 }; + + if (arguments.length === 1) + return { x: x.x, y: x.y, width: x.width, height: x.height }; + + if (arguments.length === 2) + return { x: x.x, y: x.y, width: y.width, height: y.height }; + + if (arguments.length === 4) + return { x: x, y: y, width: w, height: h }; + + throw "unknown argument type"; }; cc._rect = function(x,y,w,h) { From f172abbc1418b726f0f627047d9bf4db8c335635 Mon Sep 17 00:00:00 2001 From: dingpinglv Date: Thu, 31 Oct 2013 14:31:25 +0800 Subject: [PATCH 090/144] fixed #3048: add some comments for cc.rect --- cocos/scripting/javascript/script/jsb_cocos2d.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cocos/scripting/javascript/script/jsb_cocos2d.js b/cocos/scripting/javascript/script/jsb_cocos2d.js index 3362e78650..a5dd86d282 100644 --- a/cocos/scripting/javascript/script/jsb_cocos2d.js +++ b/cocos/scripting/javascript/script/jsb_cocos2d.js @@ -230,9 +230,14 @@ cc.sizeEqualToSize = function (size1, size2) return ((size1.width == size2.width) && (size1.height == size2.height)); }; -// -// Rect -// +/** + * create a rect object + * @param {Number|cc.Point|cc.Rect} [x1] a Number value as x or a cc.Point object as origin or a cc.Rect clone object + * @param {Number|cc.Size} [y1] x1 a Number value as y or a cc.Size object as size + * @param {Number} [width1] + * @param {Number} [height1] + * @return {Object} a Rect object + */ cc.rect = function(x,y,w,h) { if (arguments.length === 0) From 7e8faed7aff38136491ee18387b453e26b22a93c Mon Sep 17 00:00:00 2001 From: dingpinglv Date: Thu, 31 Oct 2013 14:36:17 +0800 Subject: [PATCH 091/144] fixed #3048: rename some comments --- .../javascript/script/jsb_cocos2d.js | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/cocos/scripting/javascript/script/jsb_cocos2d.js b/cocos/scripting/javascript/script/jsb_cocos2d.js index a5dd86d282..5689a7a51e 100644 --- a/cocos/scripting/javascript/script/jsb_cocos2d.js +++ b/cocos/scripting/javascript/script/jsb_cocos2d.js @@ -231,25 +231,26 @@ cc.sizeEqualToSize = function (size1, size2) }; /** - * create a rect object - * @param {Number|cc.Point|cc.Rect} [x1] a Number value as x or a cc.Point object as origin or a cc.Rect clone object - * @param {Number|cc.Size} [y1] x1 a Number value as y or a cc.Size object as size - * @param {Number} [width1] - * @param {Number} [height1] - * @return {Object} a Rect object + * create a cc.rect object + * @param {Number|cc.point|cc.rect} [x] a Number value as x or a cc.point object as origin or a cc.rect clone object + * @param {Number|cc.size} [y] x1 a Number value as y or a cc.size object as size + * @param {Number} [w] + * @param {Number} [h] + * @return {Object} a cc.rect object */ cc.rect = function(x,y,w,h) { - if (arguments.length === 0) + var argLen = arguments.length; + if (argLen === 0) return { x: 0, y: 0, width: 0, height: 0 }; - if (arguments.length === 1) + if (argLen === 1) return { x: x.x, y: x.y, width: x.width, height: x.height }; - if (arguments.length === 2) + if (argLen === 2) return { x: x.x, y: x.y, width: y.width, height: y.height }; - if (arguments.length === 4) + if (argLen === 4) return { x: x, y: y, width: w, height: h }; throw "unknown argument type"; From a27975763ff00c41eed76b2c3348d1da03dbdc08 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 31 Oct 2013 00:04:39 -0700 Subject: [PATCH 092/144] Add MouseEvent to win32 build --- cocos/2d/cocos2d.vcxproj | 4 ++++ cocos/2d/cocos2d.vcxproj.filters | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/cocos/2d/cocos2d.vcxproj b/cocos/2d/cocos2d.vcxproj index a7f030bb9f..a59611bc90 100644 --- a/cocos/2d/cocos2d.vcxproj +++ b/cocos/2d/cocos2d.vcxproj @@ -243,7 +243,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou + + @@ -414,7 +416,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou + + diff --git a/cocos/2d/cocos2d.vcxproj.filters b/cocos/2d/cocos2d.vcxproj.filters index 2028e708c8..493e1dc747 100644 --- a/cocos/2d/cocos2d.vcxproj.filters +++ b/cocos/2d/cocos2d.vcxproj.filters @@ -572,6 +572,12 @@ support + + event_dispatcher + + + event_dispatcher + @@ -1152,5 +1158,11 @@ base + + event_dispatcher + + + event_dispatcher + \ No newline at end of file From 6f978c5cbd823fdcb87fcb1f5e5016cfc6dd5f87 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 15:13:49 +0800 Subject: [PATCH 093/144] issue #2826: Bug fixes after using Spidermonkey v25. Adding JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET macro. --- cocos/scripting/javascript/bindings/ScriptingCore.cpp | 9 ++++++++- .../bindings/cocos2d_specifics.cpp.REMOVED.git-id | 2 +- .../bindings/extension/jsb_cocos2dx_extension_manual.cpp | 1 + cocos/scripting/javascript/bindings/js_bindings_config.h | 3 +++ .../scripting/javascript/bindings/js_bindings_opengl.cpp | 3 +-- .../javascript/bindings/network/XMLHTTPRequest.cpp | 1 + .../javascript/bindings/network/jsb_websocket.cpp | 8 ++++++++ 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index 9756be492a..03c140036c 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -176,6 +176,8 @@ void ScriptingCore::executeJSFunctionWithThisObj(jsval thisObj, { if (callback != JSVAL_VOID || thisObj != JSVAL_VOID) { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + // Very important: The last parameter 'retVal' passed to 'JS_CallFunctionValue' should not be a NULL pointer. // If it's a NULL pointer, crash will be triggered in 'JS_CallFunctionValue'. To find out the reason of this crash is very difficult. // So we have to check the availability of 'retVal'. @@ -1076,6 +1078,8 @@ int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType, int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, Touch *pTouch, JSObject *obj) { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + jsval retval; std::string funcName; getTouchFuncName(eventType, funcName); @@ -1096,7 +1100,8 @@ int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, Touch *pTouch, JSObject *obj, jsval &retval) { - + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + std::string funcName; getTouchFuncName(eventType, funcName); @@ -1791,6 +1796,8 @@ jsval c_string_to_jsval(JSContext* cx, const char* v, size_t length /* = -1 */) return JSVAL_NULL; } + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + if (0 == length) { auto emptyStr = JS_NewStringCopyZ(cx, ""); diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index 4308bf2a80..39e01fd1ef 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -8a34b565b95d3bdd2cf1dad5b70729544004a35d \ No newline at end of file +c93df276adb92b5e076db49c4f9482b8eb37d45c \ No newline at end of file diff --git a/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp b/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp index e46bc688f8..5980940918 100644 --- a/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp +++ b/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp @@ -258,6 +258,7 @@ public: } if (ok) { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); Size size; JSBool isSucceed = jsval_to_ccsize(cx, ret, &size); diff --git a/cocos/scripting/javascript/bindings/js_bindings_config.h b/cocos/scripting/javascript/bindings/js_bindings_config.h index 98d5feb954..b4a5702029 100644 --- a/cocos/scripting/javascript/bindings/js_bindings_config.h +++ b/cocos/scripting/javascript/bindings/js_bindings_config.h @@ -144,6 +144,9 @@ JSAutoCompartment ac(cx, obj) #define JSB_ENSURE_AUTOCOMPARTMENT(cx, obj) #endif +#define JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET \ +JSAutoCompartment __jsb_ac(ScriptingCore::getInstance()->getGlobalContext(), ScriptingCore::getInstance()->getGlobalObject()); + /** * @def JSB_DEBUGGER_PORT * The port number, where the client will be listening on diff --git a/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp b/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp index 6b08243875..9fbf145647 100644 --- a/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp +++ b/cocos/scripting/javascript/bindings/js_bindings_opengl.cpp @@ -5,12 +5,11 @@ void GLNode::draw() { JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); proxy = js_get_or_create_proxy(cx, this); - //JSB_CCNode *proxy = objc_getAssociatedObject(self, &JSB_association_proxy_key); if( proxy ) { JSObject *jsObj = proxy->obj; if (jsObj) { JSBool found; - JSB_ENSURE_AUTOCOMPARTMENT(cx, jsObj); + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET JS_HasProperty(cx, jsObj, "draw", &found); if (found == JS_TRUE) { JS::RootedValue rval(cx); diff --git a/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp b/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp index 1879b5417d..e3a0ba5b18 100644 --- a/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp +++ b/cocos/scripting/javascript/bindings/network/XMLHTTPRequest.cpp @@ -231,6 +231,7 @@ void MinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, netw if (_onreadystateCallback) { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET //JS_IsExceptionPending(cx) && JS_ReportPendingException(cx); jsval fval = OBJECT_TO_JSVAL(_onreadystateCallback); jsval out; diff --git a/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp b/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp index 8497cd35e3..ae3b1c64ce 100644 --- a/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp +++ b/cocos/scripting/javascript/bindings/network/jsb_websocket.cpp @@ -67,6 +67,8 @@ public: js_proxy_t * p = jsb_get_native_proxy(ws); if (!p) return; + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); JS::RootedValue vp(cx); @@ -83,6 +85,8 @@ public: js_proxy_t * p = jsb_get_native_proxy(ws); if (!p) return; + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); JS::RootedValue vp(cx); @@ -115,6 +119,8 @@ public: js_proxy_t * p = jsb_get_native_proxy(ws); if (!p) return; + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); JS::RootedValue vp(cx); @@ -135,6 +141,8 @@ public: js_proxy_t * p = jsb_get_native_proxy(ws); if (!p) return; + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); JSObject* jsobj = JS_NewObject(cx, NULL, NULL, NULL); JS::RootedValue vp(cx); From f478e2d2a5ddb2c73db181841bbf382ab5e31151 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 15:15:52 +0800 Subject: [PATCH 094/144] issue #2826: Bug fixes for win32. --- cocos/scripting/javascript/bindings/ScriptingCore.cpp | 8 ++++++++ external/spidermonkey/include/win32/jspubtd.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index 03c140036c..59fe928dde 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -79,6 +79,14 @@ static std::map ports_sockets; // name ~> globals static std::map globals; +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) +namespace js { +bool IsInRequest(JSContext* cx) +{ + return true; +} +} +#endif static void ReportException(JSContext *cx) { diff --git a/external/spidermonkey/include/win32/jspubtd.h b/external/spidermonkey/include/win32/jspubtd.h index 96f5dd8297..3ff5b3428c 100644 --- a/external/spidermonkey/include/win32/jspubtd.h +++ b/external/spidermonkey/include/win32/jspubtd.h @@ -16,7 +16,7 @@ #include "jsprototypes.h" #include "jstypes.h" -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) +#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || (defined(DEBUG) && !defined(_WIN32)) # define JSGC_TRACK_EXACT_ROOTS #endif From faf3b30e9bfa35daa1db109c83e7d9f5e23373c2 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 15:20:53 +0800 Subject: [PATCH 095/144] issue #3069:Add LuaObjectCBridge and related test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- .../project.pbxproj.REMOVED.git-id | 2 +- .../bindings/platform/ios/CCLuaObjcBridge.mm | 2 +- cocos/scripting/lua/script/luaoc.lua | 28 +++++++ .../luaScript/LuaBridgeTest/LuaBridgeTest.lua | 30 ++++++- .../TestLua/Resources/luaScript/mainMenu.lua | 4 +- .../TestLua/proj.ios/LuaObjectCBridgeTest.h | 20 +++++ .../TestLua/proj.ios/LuaObjectCBridgeTest.mm | 81 +++++++++++++++++++ .../TestLua/proj.mac/LuaObjectCBridgeTest.h | 20 +++++ .../TestLua/proj.mac/LuaObjectCBridgeTest.mm | 81 +++++++++++++++++++ 10 files changed, 264 insertions(+), 6 deletions(-) create mode 100644 cocos/scripting/lua/script/luaoc.lua create mode 100644 samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.h create mode 100644 samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm create mode 100644 samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.h create mode 100644 samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 17e0cee1da..4b66f8ecfe 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b695026fc3d856d540590ff09112696f66379c22 \ No newline at end of file +2fc86c9b16a099b711aabd5d29f835c45a1690a4 \ No newline at end of file diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 70bb169acc..3a1978b2ff 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -83265c81797ca614f19372a96adf326aeb21b396 \ No newline at end of file +3cdc74655a14f57ae21036886ccf31e32aaadce4 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/platform/ios/CCLuaObjcBridge.mm b/cocos/scripting/lua/bindings/platform/ios/CCLuaObjcBridge.mm index 421b85c5b7..74487cee44 100644 --- a/cocos/scripting/lua/bindings/platform/ios/CCLuaObjcBridge.mm +++ b/cocos/scripting/lua/bindings/platform/ios/CCLuaObjcBridge.mm @@ -10,7 +10,7 @@ void LuaObjcBridge::luaopen_luaoc(lua_State *L) lua_pushstring(L, "callStaticMethod"); lua_pushcfunction(L, LuaObjcBridge::callObjcStaticMethod); lua_rawset(L, -3); - lua_setglobal(L, "CCLuaObjcBridge"); + lua_setglobal(L, "LuaObjcBridge"); } /** diff --git a/cocos/scripting/lua/script/luaoc.lua b/cocos/scripting/lua/script/luaoc.lua new file mode 100644 index 0000000000..ff6d157c3b --- /dev/null +++ b/cocos/scripting/lua/script/luaoc.lua @@ -0,0 +1,28 @@ + +local luaoc = {} + +local callStaticMethod = LuaObjcBridge.callStaticMethod + +function luaoc.callStaticMethod(className, methodName, args) + local ok, ret = callStaticMethod(className, methodName, args) + if not ok then + local msg = string.format("luaoc.callStaticMethod(\"%s\", \"%s\", \"%s\") - error: [%s] ", + className, methodName, tostring(args), tostring(ret)) + if ret == -1 then + print(msg .. "INVALID PARAMETERS") + elseif ret == -2 then + print(msg .. "CLASS NOT FOUND") + elseif ret == -3 then + print(msg .. "METHOD NOT FOUND") + elseif ret == -4 then + print(msg .. "EXCEPTION OCCURRED") + elseif ret == -5 then + print(msg .. "INVALID METHOD SIGNATURE") + else + print(msg .. "UNKNOWN") + end + end + return ok, ret +end + +return luaoc diff --git a/samples/Lua/TestLua/Resources/luaScript/LuaBridgeTest/LuaBridgeTest.lua b/samples/Lua/TestLua/Resources/luaScript/LuaBridgeTest/LuaBridgeTest.lua index 2cc9b17568..dd149a00d5 100644 --- a/samples/Lua/TestLua/Resources/luaScript/LuaBridgeTest/LuaBridgeTest.lua +++ b/samples/Lua/TestLua/Resources/luaScript/LuaBridgeTest/LuaBridgeTest.lua @@ -66,7 +66,7 @@ local function LuaBridgeLayer() if not ok then print("luaj error:", ret) else - print("luaj ret:", ret) + print("The ret is:", ret) end local function callbackLua(param) @@ -86,6 +86,34 @@ local function LuaBridgeLayer() local function newLuaObjectCBridge() local newScene = cc.Scene:create() + local titleLabel = cc.LabelTTF:create("", "Arial", 28) + newScene:addChild(titleLabel, 1) + titleLabel:setPosition(s.width / 2, s.height - 50) + titleLabel:setString("LuaObjectCBridge Test") + + subtitleLabel = cc.LabelTTF:create("", "Thonburi", 16) + newScene:addChild(subtitleLabel, 1) + subtitleLabel:setPosition(s.width / 2, s.height - 80) + subtitleLabel:setString("See the console.") + if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or (cc.PLATFORM_OS_MAC == targetPlatform) then + local args = { num1 = 2 , num2 = 3 } + local luaoc = require "luaoc" + local className = "LuaObjectCBridgeTest" + local ok,ret = luaoc.callStaticMethod(className,"addTwoNumbers",args) + if not ok then + Director:getInstance():resume() + else + print("The ret is:", ret) + end + + local function callback(param) + if "success" == param then + print("object c call back success") + end + end + luaoc.callStaticMethod(className,"registerScriptHandler", {scriptHandler = callback } ) + luaoc.callStaticMethod(className,"callbackScriptHandler") + end return newScene end diff --git a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua index 73d79855d6..c1c5088530 100644 --- a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua +++ b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua @@ -75,6 +75,7 @@ local _allTests = { { isSupported = true, name = "KeypadTest" , create_func= KeypadTestMain }, { isSupported = true, name = "LabelTest" , create_func = LabelTest }, { isSupported = true, name = "LayerTest" , create_func = LayerTestMain }, + { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest }, { isSupported = true, name = "MenuTest" , create_func = MenuTestMain }, { isSupported = true, name = "MotionStreakTest" , create_func = MotionStreakTest }, { isSupported = false, name = "MutiTouchTest" , create_func= MutiTouchTestMain }, @@ -96,8 +97,7 @@ local _allTests = { { isSupported = true, name = "TouchesTest" , create_func = TouchesTest }, { isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest }, { isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain }, - { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain }, - { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest } + { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain } } local TESTS_COUNT = table.getn(_allTests) diff --git a/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.h b/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.h new file mode 100644 index 0000000000..882dab3ed7 --- /dev/null +++ b/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.h @@ -0,0 +1,20 @@ +#ifndef COCOS2DX_SAMPLES_TESTLUA_PROJ_IOS_LUAOBJECTCBRIDGETEST_H +#define COCOS2DX_SAMPLES_TESTLUA_PROJ_IOS_LUAOBJECTCBRIDGETEST_H +#import + +@interface LuaObjectCBridgeTest : NSObject { + int _scriptHandler; +} ++ (LuaObjectCBridgeTest*) getInstance; ++ (void) destroyInstance; + ++ (void) registerScriptHandler:(NSDictionary *)dict; ++ (void) unregisterScriptHandler; + ++ (int) addTwoNumbers:(NSDictionary *)dict; ++ (void) callbackScriptHandler; + +- (void) init; +@end + +#endif // COCOS2DX_SAMPLES_TESTLUA_PROJ_IOS_LUAOBJECTCBRIDGETEST_H diff --git a/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm b/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm new file mode 100644 index 0000000000..efed273add --- /dev/null +++ b/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm @@ -0,0 +1,81 @@ +#import "LuaObjectCBridgeTest.h" + +#include "cocos2d.h" +#include "CCLuaEngine.h" +#include "CCLuaBridge.h" + +using namespace cocos2d; + +@implementation LuaObjectCBridgeTest + +static LuaObjectCBridgeTest* s_instance = nil; + ++ (LuaObjectCBridgeTest*) getInstance +{ + if (!s_instance) + { + s_instance = [LuaObjectCBridgeTest alloc]; + [s_instance init]; + } + + return s_instance; +} + ++ (void) destroyInstance +{ + [s_instance release]; +} + +- (void) setScriptHandler:(int)scriptHandler +{ + if (_scriptHandler) + { + LuaBridge::releaseLuaFunctionById(_scriptHandler); + _scriptHandler = 0; + } + _scriptHandler = scriptHandler; +} + +- (int) getScriptHandler +{ + return _scriptHandler; +} + + ++(void) registerScriptHandler:(NSDictionary *)dict +{ + [[LuaObjectCBridgeTest getInstance] setScriptHandler:[[dict objectForKey:@"scriptHandler"] intValue]]; +} + + ++ (void) unregisterScriptHandler +{ + [[LuaObjectCBridgeTest getInstance] setScriptHandler:0]; +} + ++ (int) addTwoNumbers:(NSDictionary *)dict +{ + int num1 = [[dict objectForKey:@"num1"] intValue]; + int num2 = [[dict objectForKey:@"num2"] intValue]; + + return num1 + num2; +} + ++ (void) callbackScriptHandler +{ + int scriptHandler = [[LuaObjectCBridgeTest getInstance] getScriptHandler]; + if (scriptHandler) + { + LuaBridge::pushLuaFunctionById(scriptHandler); + LuaStack *stack = LuaBridge::getStack(); + stack->pushString("success"); + stack->executeFunction(1); + } +} + +- (void)init +{ + _scriptHandler = 0; +} + +@end \ No newline at end of file diff --git a/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.h b/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.h new file mode 100644 index 0000000000..882dab3ed7 --- /dev/null +++ b/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.h @@ -0,0 +1,20 @@ +#ifndef COCOS2DX_SAMPLES_TESTLUA_PROJ_IOS_LUAOBJECTCBRIDGETEST_H +#define COCOS2DX_SAMPLES_TESTLUA_PROJ_IOS_LUAOBJECTCBRIDGETEST_H +#import + +@interface LuaObjectCBridgeTest : NSObject { + int _scriptHandler; +} ++ (LuaObjectCBridgeTest*) getInstance; ++ (void) destroyInstance; + ++ (void) registerScriptHandler:(NSDictionary *)dict; ++ (void) unregisterScriptHandler; + ++ (int) addTwoNumbers:(NSDictionary *)dict; ++ (void) callbackScriptHandler; + +- (void) init; +@end + +#endif // COCOS2DX_SAMPLES_TESTLUA_PROJ_IOS_LUAOBJECTCBRIDGETEST_H diff --git a/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm b/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm new file mode 100644 index 0000000000..efed273add --- /dev/null +++ b/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm @@ -0,0 +1,81 @@ +#import "LuaObjectCBridgeTest.h" + +#include "cocos2d.h" +#include "CCLuaEngine.h" +#include "CCLuaBridge.h" + +using namespace cocos2d; + +@implementation LuaObjectCBridgeTest + +static LuaObjectCBridgeTest* s_instance = nil; + ++ (LuaObjectCBridgeTest*) getInstance +{ + if (!s_instance) + { + s_instance = [LuaObjectCBridgeTest alloc]; + [s_instance init]; + } + + return s_instance; +} + ++ (void) destroyInstance +{ + [s_instance release]; +} + +- (void) setScriptHandler:(int)scriptHandler +{ + if (_scriptHandler) + { + LuaBridge::releaseLuaFunctionById(_scriptHandler); + _scriptHandler = 0; + } + _scriptHandler = scriptHandler; +} + +- (int) getScriptHandler +{ + return _scriptHandler; +} + + ++(void) registerScriptHandler:(NSDictionary *)dict +{ + [[LuaObjectCBridgeTest getInstance] setScriptHandler:[[dict objectForKey:@"scriptHandler"] intValue]]; +} + + ++ (void) unregisterScriptHandler +{ + [[LuaObjectCBridgeTest getInstance] setScriptHandler:0]; +} + ++ (int) addTwoNumbers:(NSDictionary *)dict +{ + int num1 = [[dict objectForKey:@"num1"] intValue]; + int num2 = [[dict objectForKey:@"num2"] intValue]; + + return num1 + num2; +} + ++ (void) callbackScriptHandler +{ + int scriptHandler = [[LuaObjectCBridgeTest getInstance] getScriptHandler]; + if (scriptHandler) + { + LuaBridge::pushLuaFunctionById(scriptHandler); + LuaStack *stack = LuaBridge::getStack(); + stack->pushString("success"); + stack->executeFunction(1); + } +} + +- (void)init +{ + _scriptHandler = 0; +} + +@end \ No newline at end of file From 705da20ee729dc7b8a8d4ea061ad7380522e56c8 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 15:26:38 +0800 Subject: [PATCH 096/144] issue #2794:Add LuaObjectCBridge and related test sample --- samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm | 2 +- samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm b/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm index efed273add..624e338206 100644 --- a/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm +++ b/samples/Lua/TestLua/proj.ios/LuaObjectCBridgeTest.mm @@ -78,4 +78,4 @@ static LuaObjectCBridgeTest* s_instance = nil; _scriptHandler = 0; } -@end \ No newline at end of file +@end diff --git a/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm b/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm index efed273add..624e338206 100644 --- a/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm +++ b/samples/Lua/TestLua/proj.mac/LuaObjectCBridgeTest.mm @@ -78,4 +78,4 @@ static LuaObjectCBridgeTest* s_instance = nil; _scriptHandler = 0; } -@end \ No newline at end of file +@end From 771844fc58420fbfbed09a2ad6c7cb9c6b3b6265 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 31 Oct 2013 00:40:38 -0700 Subject: [PATCH 097/144] Fix android build after adding MouseEvent and MouseTest --- cocos/2d/Android.mk | 2 ++ samples/Cpp/TestCpp/Android.mk | 1 + 2 files changed, 3 insertions(+) diff --git a/cocos/2d/Android.mk b/cocos/2d/Android.mk index 6a25764f44..75ff000786 100644 --- a/cocos/2d/Android.mk +++ b/cocos/2d/Android.mk @@ -39,6 +39,8 @@ CCEventAcceleration.cpp \ CCEventCustom.cpp \ CCEventDispatcher.cpp \ CCEventKeyboard.cpp \ +CCEventMouse.cpp \ +CCEventListenerMouse.cpp \ CCEventListener.cpp \ CCEventListenerAcceleration.cpp \ CCEventListenerCustom.cpp \ diff --git a/samples/Cpp/TestCpp/Android.mk b/samples/Cpp/TestCpp/Android.mk index c848586fbb..4fd63763d1 100644 --- a/samples/Cpp/TestCpp/Android.mk +++ b/samples/Cpp/TestCpp/Android.mk @@ -99,6 +99,7 @@ Classes/ExtensionsTest/TableViewTest/TableViewTestScene.cpp \ Classes/FileUtilsTest/FileUtilsTest.cpp \ Classes/FontTest/FontTest.cpp \ Classes/IntervalTest/IntervalTest.cpp \ +Classes/InputTest/MouseTest.cpp \ Classes/KeyboardTest/KeyboardTest.cpp \ Classes/KeypadTest/KeypadTest.cpp \ Classes/LabelTest/LabelTest.cpp \ From 4b2429186c73969d61e3de731160e8fb693e11fe Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 16:25:06 +0800 Subject: [PATCH 098/144] closed #3093: The last test of OpenglTest crashes on Windows. --- .../javascript/bindings/jsb_opengl_manual.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cocos/scripting/javascript/bindings/jsb_opengl_manual.cpp b/cocos/scripting/javascript/bindings/jsb_opengl_manual.cpp index e7aac467ee..38a168b935 100644 --- a/cocos/scripting/javascript/bindings/jsb_opengl_manual.cpp +++ b/cocos/scripting/javascript/bindings/jsb_opengl_manual.cpp @@ -437,8 +437,8 @@ JSBool JSB_glGetUniformfv(JSContext *cx, uint32_t argc, jsval *vp) JSB_PRECONDITION2(ok, cx, JS_FALSE, "JSB_glGetUniformfv: Error processing arguments"); GLsizei length; - glGetProgramiv(arg0, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length); - GLchar* namebuffer = new GLchar[length]; + glGetProgramiv(arg0, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length); + GLchar* namebuffer = new GLchar[length+1]; GLint size = -1; GLenum type = -1; @@ -503,7 +503,10 @@ JSBool JSB_glGetUniformfv(JSContext *cx, uint32_t argc, jsval *vp) JSObject *typedArray = NULL; if( utype == GL_FLOAT) { - GLfloat* param = new GLfloat[usize]; + // FIXME: glew on windows will cause array overflow after invoking glGetUniformfv. + // It seems that glGetUniformfv re-assign the memeroy with a wrong size which is 4x than we pass in. + // For temporary solution, we allocate 4x array. + GLfloat* param = new GLfloat[usize*4]; glGetUniformfv(arg0, arg1, param); typedArray = JS_NewFloat32Array(cx, usize); @@ -511,7 +514,10 @@ JSBool JSB_glGetUniformfv(JSContext *cx, uint32_t argc, jsval *vp) memcpy( buffer, param, sizeof(float) * usize); CC_SAFE_DELETE_ARRAY(param); } else if( utype == GL_INT ) { - GLint* param = new GLint[usize]; + // FIXME: glew on windows will cause array overflow after invoking glGetUniformfv. + // It seems that glGetUniformfv re-assign the memeroy with a wrong size which is 4x than we pass in. + // For temporary solution, we allocate 4x array. + GLint* param = new GLint[usize*4]; glGetUniformiv(arg0, arg1, param); typedArray = JS_NewInt32Array(cx, usize); From 15cf5197573b852e07c0a64bc8f3446b8401309b Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 16:59:55 +0800 Subject: [PATCH 099/144] issue #2970:crash for CCLabelTTF when setting dimension width less than the font height --- cocos/2d/platform/android/CCImage.cpp | 10 +- .../src/org/cocos2dx/lib/Cocos2dxBitmap.java | 210 ++++++++++-------- 2 files changed, 123 insertions(+), 97 deletions(-) diff --git a/cocos/2d/platform/android/CCImage.cpp b/cocos/2d/platform/android/CCImage.cpp index 0fdfe6445e..ba722d7fad 100644 --- a/cocos/2d/platform/android/CCImage.cpp +++ b/cocos/2d/platform/android/CCImage.cpp @@ -81,7 +81,7 @@ public: { JniMethodInfo methodInfo; if (! JniHelper::getStaticMethodInfo(methodInfo, "org/cocos2dx/lib/Cocos2dxBitmap", "createTextBitmapShadowStroke", - "(Ljava/lang/String;Ljava/lang/String;IFFFIIIZFFFFZFFFF)V")) + "(Ljava/lang/String;Ljava/lang/String;IFFFIIIZFFFFZFFFF)Z")) { CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__); return false; @@ -109,8 +109,12 @@ public: jstring jstrText = methodInfo.env->NewStringUTF(text); jstring jstrFont = methodInfo.env->NewStringUTF(fullPathOrFontName.c_str()); - methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrText, - jstrFont, (int)fontSize, textTintR, textTintG, textTintB, eAlignMask, nWidth, nHeight, shadow, shadowDeltaX, -shadowDeltaY, shadowBlur, shadowOpacity, stroke, strokeColorR, strokeColorG, strokeColorB, strokeSize); + if(!methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstrText, + jstrFont, (int)fontSize, textTintR, textTintG, textTintB, eAlignMask, nWidth, nHeight, shadow, shadowDeltaX, -shadowDeltaY, shadowBlur, shadowOpacity, stroke, strokeColorR, strokeColorG, strokeColorB, strokeSize)) + { + return false; + } + methodInfo.env->DeleteLocalRef(jstrText); methodInfo.env->DeleteLocalRef(jstrFont); diff --git a/cocos/2d/platform/android/java/src/org/cocos2dx/lib/Cocos2dxBitmap.java b/cocos/2d/platform/android/java/src/org/cocos2dx/lib/Cocos2dxBitmap.java index 2660097a45..ef0ba4074e 100644 --- a/cocos/2d/platform/android/java/src/org/cocos2dx/lib/Cocos2dxBitmap.java +++ b/cocos/2d/platform/android/java/src/org/cocos2dx/lib/Cocos2dxBitmap.java @@ -58,7 +58,7 @@ public class Cocos2dxBitmap { // Fields // =========================================================== - private static Context sContext; + private static Context _context; // =========================================================== // Constructors @@ -68,8 +68,8 @@ public class Cocos2dxBitmap { // Getter & Setter // =========================================================== - public static void setContext(final Context pContext) { - Cocos2dxBitmap.sContext = pContext; + public static void setContext(final Context context) { + Cocos2dxBitmap._context = context; } // =========================================================== @@ -80,8 +80,8 @@ public class Cocos2dxBitmap { // Methods // =========================================================== - private static native void nativeInitBitmapDC(final int pWidth, - final int pHeight, final byte[] pPixels); + private static native void nativeInitBitmapDC(final int width, + final int height, final byte[] pixels); /** * @param pWidth @@ -89,36 +89,49 @@ public class Cocos2dxBitmap { * @param pHeight * the height to draw, it can be 0 */ - public static void createTextBitmap(String pString, final String pFontName, - final int pFontSize, final int pAlignment, final int pWidth, - final int pHeight) { + public static void createTextBitmap(String string, final String fontName, + final int fontSize, final int alignment, final int width, + final int height) { // - createTextBitmapShadowStroke( pString, pFontName, pFontSize, 1.0f, 1.0f, 1.0f, // text font and color - pAlignment, pWidth, pHeight, // alignment and size + createTextBitmapShadowStroke( string, fontName, fontSize, 1.0f, 1.0f, 1.0f, // text font and color + alignment, width, height, // alignment and size false, 0.0f, 0.0f, 0.0f, 0.0f, // no shadow false, 1.0f, 1.0f, 1.0f, 1.0f); // no stroke } - public static void createTextBitmapShadowStroke(String pString, final String pFontName, final int pFontSize, + public static boolean createTextBitmapShadowStroke(String string, final String fontName, final int fontSize, final float fontTintR, final float fontTintG, final float fontTintB, - final int pAlignment, final int pWidth, final int pHeight, final boolean shadow, + final int alignment, final int width, final int height, final boolean shadow, final float shadowDX, final float shadowDY, final float shadowBlur, final float shadowOpacity, final boolean stroke, final float strokeR, final float strokeG, final float strokeB, final float strokeSize) { - final int horizontalAlignment = pAlignment & 0x0F; - final int verticalAlignment = (pAlignment >> 4) & 0x0F; + final int horizontalAlignment = alignment & 0x0F; + final int verticalAlignment = (alignment >> 4) & 0x0F; + + string = Cocos2dxBitmap.refactorString(string); + final Paint paint = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment); + /** + * if the first word width less than designed width,It means no words to show + */ + if(0 != width) + { + final int firstWordWidth = (int) FloatMath.ceil(paint.measureText(string, 0,1)); + if ( firstWordWidth > width) + { + Log.w("createTextBitmapShadowStroke warning:","the input width is less than the width of the pString's first word\n"); + return false; + } + } - pString = Cocos2dxBitmap.refactorString(pString); - final Paint paint = Cocos2dxBitmap.newPaint(pFontName, pFontSize, horizontalAlignment); // set the paint color paint.setARGB(255, (int)(255.0 * fontTintR), (int)(255.0 * fontTintG), (int)(255.0 * fontTintB)); - final TextProperty textProperty = Cocos2dxBitmap.computeTextProperty(pString, pWidth, pHeight, paint); - final int bitmapTotalHeight = (pHeight == 0 ? textProperty.mTotalHeight: pHeight); + final TextProperty textProperty = Cocos2dxBitmap.computeTextProperty(string, width, height, paint); + final int bitmapTotalHeight = (height == 0 ? textProperty.mTotalHeight: height); // padding needed when using shadows (not used otherwise) float bitmapPaddingX = 0.0f; @@ -144,6 +157,13 @@ public class Cocos2dxBitmap { renderTextDeltaY = bitmapPaddingY; } } + + if (0 == textProperty.mMaxWidth || 0 == bitmapTotalHeight) + { + Log.w("createTextBitmapShadowStroke warning:","textProperty MaxWidth is 0 or bitMapTotalHeight is 0\n"); + return false; + } + final Bitmap bitmap = Bitmap.createBitmap(textProperty.mMaxWidth + (int)bitmapPaddingX, bitmapTotalHeight + (int)bitmapPaddingY, Bitmap.Config.ARGB_8888); @@ -154,7 +174,7 @@ public class Cocos2dxBitmap { final FontMetricsInt fontMetricsInt = paint.getFontMetricsInt(); int x = 0; - int y = Cocos2dxBitmap.computeY(fontMetricsInt, pHeight, textProperty.mTotalHeight, verticalAlignment); + int y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment); final String[] lines = textProperty.mLines; @@ -169,13 +189,13 @@ public class Cocos2dxBitmap { // draw again with stroke on if needed if ( stroke ) { - final Paint paintStroke = Cocos2dxBitmap.newPaint(pFontName, pFontSize, horizontalAlignment); + final Paint paintStroke = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment); paintStroke.setStyle(Paint.Style.STROKE); paintStroke.setStrokeWidth(strokeSize * 0.5f); paintStroke.setARGB(255, (int) (strokeR * 255), (int) (strokeG * 255), (int) (strokeB * 255)); x = 0; - y = Cocos2dxBitmap.computeY(fontMetricsInt, pHeight, textProperty.mTotalHeight, verticalAlignment); + y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment); final String[] lines2 = textProperty.mLines; for (final String line : lines2) { @@ -189,33 +209,35 @@ public class Cocos2dxBitmap { } Cocos2dxBitmap.initNativeObject(bitmap); + + return true; } - private static Paint newPaint(final String pFontName, final int pFontSize, - final int pHorizontalAlignment) { + private static Paint newPaint(final String fontName, final int fontSize, + final int horizontalAlignment) { final Paint paint = new Paint(); paint.setColor(Color.WHITE); - paint.setTextSize(pFontSize); + paint.setTextSize(fontSize); paint.setAntiAlias(true); /* Set type face for paint, now it support .ttf file. */ - if (pFontName.endsWith(".ttf")) { + if (fontName.endsWith(".ttf")) { try { final Typeface typeFace = Cocos2dxTypefaces.get( - Cocos2dxBitmap.sContext, pFontName); + Cocos2dxBitmap._context, fontName); paint.setTypeface(typeFace); } catch (final Exception e) { Log.e("Cocos2dxBitmap", "error to create ttf type face: " - + pFontName); + + fontName); /* The file may not find, use system font. */ - paint.setTypeface(Typeface.create(pFontName, Typeface.NORMAL)); + paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL)); } } else { - paint.setTypeface(Typeface.create(pFontName, Typeface.NORMAL)); + paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL)); } - switch (pHorizontalAlignment) { + switch (horizontalAlignment) { case HORIZONTALALIGN_CENTER: paint.setTextAlign(Align.CENTER); break; @@ -231,22 +253,22 @@ public class Cocos2dxBitmap { return paint; } - private static TextProperty computeTextProperty(final String pString, - final int pWidth, final int pHeight, final Paint pPaint) { - final FontMetricsInt fm = pPaint.getFontMetricsInt(); + private static TextProperty computeTextProperty(final String string, + final int width, final int height, final Paint paint) { + final FontMetricsInt fm = paint.getFontMetricsInt(); final int h = (int) Math.ceil(fm.bottom - fm.top); int maxContentWidth = 0; - final String[] lines = Cocos2dxBitmap.splitString(pString, pWidth, - pHeight, pPaint); + final String[] lines = Cocos2dxBitmap.splitString(string, width, + height, paint); - if (pWidth != 0) { - maxContentWidth = pWidth; + if (width != 0) { + maxContentWidth = width; } else { /* Compute the max width. */ int temp = 0; for (final String line : lines) { - temp = (int) FloatMath.ceil(pPaint.measureText(line, 0, + temp = (int) FloatMath.ceil(paint.measureText(line, 0, line.length())); if (temp > maxContentWidth) { maxContentWidth = temp; @@ -257,16 +279,16 @@ public class Cocos2dxBitmap { return new TextProperty(maxContentWidth, h, lines); } - private static int computeX(final String pText, final int pMaxWidth, - final int pHorizontalAlignment) { + private static int computeX(final String text, final int maxWidth, + final int horizontalAlignment) { int ret = 0; - switch (pHorizontalAlignment) { + switch (horizontalAlignment) { case HORIZONTALALIGN_CENTER: - ret = pMaxWidth / 2; + ret = maxWidth / 2; break; case HORIZONTALALIGN_RIGHT: - ret = pMaxWidth; + ret = maxWidth; break; case HORIZONTALALIGN_LEFT: default: @@ -276,22 +298,22 @@ public class Cocos2dxBitmap { return ret; } - private static int computeY(final FontMetricsInt pFontMetricsInt, - final int pConstrainHeight, final int pTotalHeight, - final int pVerticalAlignment) { - int y = -pFontMetricsInt.top; + private static int computeY(final FontMetricsInt fontMetricsInt, + final int constrainHeight, final int totalHeight, + final int verticalAlignment) { + int y = -fontMetricsInt.top; - if (pConstrainHeight > pTotalHeight) { - switch (pVerticalAlignment) { + if (constrainHeight > totalHeight) { + switch (verticalAlignment) { case VERTICALALIGN_TOP: - y = -pFontMetricsInt.top; + y = -fontMetricsInt.top; break; case VERTICALALIGN_CENTER: - y = -pFontMetricsInt.top + (pConstrainHeight - pTotalHeight) + y = -fontMetricsInt.top + (constrainHeight - totalHeight) / 2; break; case VERTICALALIGN_BOTTOM: - y = -pFontMetricsInt.top + (pConstrainHeight - pTotalHeight); + y = -fontMetricsInt.top + (constrainHeight - totalHeight); break; default: break; @@ -305,26 +327,26 @@ public class Cocos2dxBitmap { * If maxWidth or maxHeight is not 0, split the string to fix the maxWidth * and maxHeight. */ - private static String[] splitString(final String pString, - final int pMaxWidth, final int pMaxHeight, final Paint pPaint) { - final String[] lines = pString.split("\\n"); + private static String[] splitString(final String string, + final int maxWidth, final int maxHeight, final Paint paint) { + final String[] lines = string.split("\\n"); String[] ret = null; - final FontMetricsInt fm = pPaint.getFontMetricsInt(); + final FontMetricsInt fm = paint.getFontMetricsInt(); final int heightPerLine = (int) Math.ceil(fm.bottom - fm.top); - final int maxLines = pMaxHeight / heightPerLine; + final int maxLines = maxHeight / heightPerLine; - if (pMaxWidth != 0) { + if (maxWidth != 0) { final LinkedList strList = new LinkedList(); for (final String line : lines) { /* * The width of line is exceed maxWidth, should divide it into * two or more lines. */ - final int lineWidth = (int) FloatMath.ceil(pPaint + final int lineWidth = (int) FloatMath.ceil(paint .measureText(line)); - if (lineWidth > pMaxWidth) { + if (lineWidth > maxWidth) { strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidth( - line, pMaxWidth, pPaint)); + line, maxWidth, paint)); } else { strList.add(line); } @@ -344,7 +366,7 @@ public class Cocos2dxBitmap { ret = new String[strList.size()]; strList.toArray(ret); - } else if (pMaxHeight != 0 && lines.length > maxLines) { + } else if (maxHeight != 0 && lines.length > maxLines) { /* Remove exceeding lines. */ final LinkedList strList = new LinkedList(); for (int i = 0; i < maxLines; i++) { @@ -360,37 +382,37 @@ public class Cocos2dxBitmap { } private static LinkedList divideStringWithMaxWidth( - final String pString, final int pMaxWidth, final Paint pPaint) { - final int charLength = pString.length(); + final String string, final int maxWidth, final Paint paint) { + final int charLength = string.length(); int start = 0; int tempWidth = 0; final LinkedList strList = new LinkedList(); /* Break a String into String[] by the width & should wrap the word. */ for (int i = 1; i <= charLength; ++i) { - tempWidth = (int) FloatMath.ceil(pPaint.measureText(pString, start, + tempWidth = (int) FloatMath.ceil(paint.measureText(string, start, i)); - if (tempWidth >= pMaxWidth) { - final int lastIndexOfSpace = pString.substring(0, i) + if (tempWidth >= maxWidth) { + final int lastIndexOfSpace = string.substring(0, i) .lastIndexOf(" "); if (lastIndexOfSpace != -1 && lastIndexOfSpace > start) { /* Should wrap the word. */ - strList.add(pString.substring(start, lastIndexOfSpace)); + strList.add(string.substring(start, lastIndexOfSpace)); i = lastIndexOfSpace + 1; // skip space } else { /* Should not exceed the width. */ - if (tempWidth > pMaxWidth) { - strList.add(pString.substring(start, i - 1)); + if (tempWidth > maxWidth) { + strList.add(string.substring(start, i - 1)); /* Compute from previous char. */ --i; } else { - strList.add(pString.substring(start, i)); + strList.add(string.substring(start, i)); } } /* Remove spaces at the beginning of a new line. */ - while (i < charLength && pString.charAt(i) == ' ') { + while (i < charLength && string.charAt(i) == ' ') { ++i; } @@ -400,15 +422,15 @@ public class Cocos2dxBitmap { /* Add the last chars. */ if (start < charLength) { - strList.add(pString.substring(start)); + strList.add(string.substring(start)); } return strList; } - private static String refactorString(final String pString) { + private static String refactorString(final String string) { /* Avoid error when content is "". */ - if (pString.compareTo("") == 0) { + if (string.compareTo("") == 0) { return " "; } @@ -416,7 +438,7 @@ public class Cocos2dxBitmap { * If the font of "\n" is "" or "\n", insert " " in front of it. For * example: "\nabc" -> " \nabc" "\nabc\n\n" -> " \nabc\n \n". */ - final StringBuilder strBuilder = new StringBuilder(pString); + final StringBuilder strBuilder = new StringBuilder(string); int start = 0; int index = strBuilder.indexOf("\n"); while (index != -1) { @@ -437,23 +459,23 @@ public class Cocos2dxBitmap { return strBuilder.toString(); } - private static void initNativeObject(final Bitmap pBitmap) { - final byte[] pixels = Cocos2dxBitmap.getPixels(pBitmap); + private static void initNativeObject(final Bitmap bitmap) { + final byte[] pixels = Cocos2dxBitmap.getPixels(bitmap); if (pixels == null) { return; } - Cocos2dxBitmap.nativeInitBitmapDC(pBitmap.getWidth(), - pBitmap.getHeight(), pixels); + Cocos2dxBitmap.nativeInitBitmapDC(bitmap.getWidth(), + bitmap.getHeight(), pixels); } - private static byte[] getPixels(final Bitmap pBitmap) { - if (pBitmap != null) { - final byte[] pixels = new byte[pBitmap.getWidth() - * pBitmap.getHeight() * 4]; + private static byte[] getPixels(final Bitmap bitmap) { + if (bitmap != null) { + final byte[] pixels = new byte[bitmap.getWidth() + * bitmap.getHeight() * 4]; final ByteBuffer buf = ByteBuffer.wrap(pixels); buf.order(ByteOrder.nativeOrder()); - pBitmap.copyPixelsToBuffer(buf); + bitmap.copyPixelsToBuffer(buf); return pixels; } @@ -484,9 +506,9 @@ public class Cocos2dxBitmap { return incr_text_size; } - private static String getStringWithEllipsis(String pString, float width, + private static String getStringWithEllipsis(String string, float width, float fontSize) { - if (TextUtils.isEmpty(pString)) { + if (TextUtils.isEmpty(string)) { return ""; } @@ -494,7 +516,7 @@ public class Cocos2dxBitmap { paint.setTypeface(Typeface.DEFAULT); paint.setTextSize(fontSize); - return TextUtils.ellipsize(pString, paint, width, + return TextUtils.ellipsize(string, paint, width, TextUtils.TruncateAt.END).toString(); } @@ -510,12 +532,12 @@ public class Cocos2dxBitmap { private final int mHeightPerLine; private final String[] mLines; - TextProperty(final int pMaxWidth, final int pHeightPerLine, - final String[] pLines) { - this.mMaxWidth = pMaxWidth; - this.mHeightPerLine = pHeightPerLine; - this.mTotalHeight = pHeightPerLine * pLines.length; - this.mLines = pLines; + TextProperty(final int maxWidth, final int heightPerLine, + final String[] lines) { + this.mMaxWidth = maxWidth; + this.mHeightPerLine = heightPerLine; + this.mTotalHeight = heightPerLine * lines.length; + this.mLines = lines; } } } From b8faaeba59c1e89a42fbab17dd985a8240c565fe Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Thu, 31 Oct 2013 17:52:22 +0800 Subject: [PATCH 100/144] issus #2893:improve new label --- cocos/2d/CCFontAtlas.cpp | 25 ++++++------- cocos/2d/CCFontAtlas.h | 4 +-- cocos/2d/CCFontAtlasFactory.cpp | 2 ++ cocos/2d/CCFontDefinition.cpp | 1 + cocos/2d/CCFontFNT.cpp | 6 +--- cocos/2d/CCFontFreeType.cpp | 8 ++--- cocos/2d/CCFontFreeType.h | 7 ++-- cocos/2d/CCLabel.cpp | 58 +++++++++++++------------------ cocos/2d/CCLabel.h | 6 ++-- cocos/2d/CCLabelTextFormatter.cpp | 2 -- 10 files changed, 52 insertions(+), 67 deletions(-) diff --git a/cocos/2d/CCFontAtlas.cpp b/cocos/2d/CCFontAtlas.cpp index 2879ac72de..24b56bd448 100644 --- a/cocos/2d/CCFontAtlas.cpp +++ b/cocos/2d/CCFontAtlas.cpp @@ -14,15 +14,15 @@ NS_CC_BEGIN FontAtlas::FontAtlas(Font &theFont) : -_font(theFont), +_font(&theFont), _currentPageData(nullptr) { - _font.retain(); + _font->retain(); - FontFreeType* fontTTf = dynamic_cast(&_font); + FontFreeType* fontTTf = dynamic_cast(_font); if (fontTTf && fontTTf->isDynamicGlyphCollection()) { - _currentPageLineHeight = _font.getFontMaxHeight(); + _currentPageLineHeight = _font->getFontMaxHeight(); _commonLineHeight = _currentPageLineHeight * 0.8f; Texture2D * tex = new Texture2D; _currentPage = 0; @@ -34,16 +34,16 @@ _currentPageData(nullptr) _currentPageData = new unsigned char[_currentPageDataSize]; memset(_currentPageData, 0, _currentPageDataSize); addTexture(*tex,0); + tex->release(); } } FontAtlas::~FontAtlas() { - _font.release(); + _font->release(); relaseTextures(); - if(_currentPageData) - delete []_currentPageData; + delete []_currentPageData; } void FontAtlas::relaseTextures() @@ -79,7 +79,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) if(_currentPageData == nullptr) return false; - FontFreeType* fontTTf = (FontFreeType*)&_font; + FontFreeType* fontTTf = (FontFreeType*)_font; std::vector fontDefs; int length = cc_wcslen(utf16String); @@ -100,7 +100,6 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect)) { - //log("Warning: Cannot find definition for glyph: %c in font:%s", utf16String[i], _fontName.c_str()); tempDef.validDefinition = false; tempDef.letteCharUTF16 = utf16String[i]; tempDef.commonLineHeight = 0; @@ -150,7 +149,9 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) return false; memset(_currentPageData, 0, _currentPageDataSize); _currentPage++; - addTexture(*(new Texture2D),_currentPage); + Texture2D* tex = new Texture2D; + addTexture(*tex,_currentPage); + tex->release(); } } renderCharAt(fontDefs[i].letteCharUTF16,_currentPageOrigX,_currentPageOrigY,_currentPageData,1024); @@ -182,7 +183,7 @@ bool FontAtlas::renderCharAt(unsigned short int charToRender, int posX, int posY int sourceHeight = 0; // get the glyph's bitmap - sourceBitmap = _font.getGlyphBitmap(charToRender, sourceWidth, sourceHeight); + sourceBitmap = _font->getGlyphBitmap(charToRender, sourceWidth, sourceHeight); if (!sourceBitmap) return false; @@ -234,7 +235,7 @@ void FontAtlas::setCommonLineHeight(float newHeight) _commonLineHeight = newHeight; } -Font & FontAtlas::getFont() const +const Font * FontAtlas::getFont() const { return _font; } diff --git a/cocos/2d/CCFontAtlas.h b/cocos/2d/CCFontAtlas.h index b1b6eaa9b4..a388a5b987 100644 --- a/cocos/2d/CCFontAtlas.h +++ b/cocos/2d/CCFontAtlas.h @@ -70,7 +70,7 @@ public: void setCommonLineHeight(float newHeight); Texture2D & getTexture(int slot); - Font & getFont() const; + const Font * getFont() const; private: bool renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize); @@ -79,7 +79,7 @@ private: std::map _atlasTextures; std::map _fontLetterDefinitions; float _commonLineHeight; - Font & _font; + Font * _font; // Dynamic GlyphCollection related stuff int _currentPage; diff --git a/cocos/2d/CCFontAtlasFactory.cpp b/cocos/2d/CCFontAtlasFactory.cpp index 2b8e0b4ca4..aeb0b6154e 100644 --- a/cocos/2d/CCFontAtlasFactory.cpp +++ b/cocos/2d/CCFontAtlasFactory.cpp @@ -35,7 +35,9 @@ FontAtlas * FontAtlasFactory::createAtlasFromFNT(const char* fntFilePath) return atlas; } else + { return nullptr; + } } NS_CC_END diff --git a/cocos/2d/CCFontDefinition.cpp b/cocos/2d/CCFontDefinition.cpp index 7852d56d84..938204f3b0 100644 --- a/cocos/2d/CCFontDefinition.cpp +++ b/cocos/2d/CCFontDefinition.cpp @@ -49,6 +49,7 @@ FontDefinitionTTF* FontDefinitionTTF::create(Font *font, int textureSize) if (ret->initDefinition(font, glyph, textureSize)) { + ret->autorelease(); return ret; } else diff --git a/cocos/2d/CCFontFNT.cpp b/cocos/2d/CCFontFNT.cpp index cd1e586e62..7a1ca6f200 100644 --- a/cocos/2d/CCFontFNT.cpp +++ b/cocos/2d/CCFontFNT.cpp @@ -38,11 +38,7 @@ FontFNT * FontFNT::create(const char* fntFilePath) FontFNT::~FontFNT() { - //_configuration release when execute LabelBMFont::purgeCachedData(); - /*if (_configuration) - { - _configuration->release(); - }*/ + } Size * FontFNT::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const diff --git a/cocos/2d/CCFontFreeType.cpp b/cocos/2d/CCFontFreeType.cpp index 3fbac58b5b..0e4e49d96f 100644 --- a/cocos/2d/CCFontFreeType.cpp +++ b/cocos/2d/CCFontFreeType.cpp @@ -88,8 +88,8 @@ FT_Library FontFreeType::getFTLibrary() } FontFreeType::FontFreeType(bool dynamicGlyphCollection) - : _letterPadding(5) - ,_ttfData(nullptr), + : _letterPadding(5), + _ttfData(nullptr), _dynamicGlyphCollection(dynamicGlyphCollection), _fontRef(nullptr) { @@ -130,8 +130,6 @@ bool FontFreeType::createFontObject(const std::string &fontName, int fontSize) FontFreeType::~FontFreeType() { - // release the font - // TO DO if (_fontRef) { FT_Done_Face(_fontRef); @@ -160,8 +158,6 @@ FontAtlas * FontFreeType::createFontAtlas() FontAtlas *atlas = def->createFontAtlas(); - // release the font definition, we don't need it anymore - def->release(); return atlas; } } diff --git a/cocos/2d/CCFontFreeType.h b/cocos/2d/CCFontFreeType.h index cdf3d1a1ac..a305b2253e 100644 --- a/cocos/2d/CCFontFreeType.h +++ b/cocos/2d/CCFontFreeType.h @@ -39,7 +39,9 @@ class CC_DLL FontFreeType : public Font public: static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs); - + + static void shutdownFreeType(); + virtual FontAtlas * createFontAtlas() override; virtual Size * getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const override; virtual GlyphDef * getGlyphDefintionsForText(const char *text, int &outNumGlyphs, bool UTF16text = false) const override; @@ -49,8 +51,7 @@ public: bool getBBOXFotChar(unsigned short theChar, Rect &outRect) const; - inline bool isDynamicGlyphCollection() { return _dynamicGlyphCollection;} - static void shutdownFreeType(); + inline bool isDynamicGlyphCollection() { return _dynamicGlyphCollection;} protected: diff --git a/cocos/2d/CCLabel.cpp b/cocos/2d/CCLabel.cpp index a7ed8e2978..ce928825bc 100644 --- a/cocos/2d/CCLabel.cpp +++ b/cocos/2d/CCLabel.cpp @@ -112,12 +112,9 @@ Label::Label(FontAtlas *atlas, TextHAlignment alignment) Label::~Label() { - if (_currentUTF16String) - delete [] _currentUTF16String; - if (_originalUTF16String) - delete [] _originalUTF16String; - if (_advances) - delete [] _advances; + delete [] _currentUTF16String; + delete [] _originalUTF16String; + delete [] _advances; if (_fontAtlas) FontAtlasCache::releaseFontAtlas(_fontAtlas); @@ -254,8 +251,7 @@ void Label::alignText() int strLen = cc_wcslen(_currentUTF16String); if (_children && _children->count() != 0) { - Object* child; - CCARRAY_FOREACH(_children, child) + for (auto child: *_children) { Node* pNode = static_cast( child ); if (pNode) @@ -275,7 +271,7 @@ void Label::alignText() { if (_lettersInfo[ctr].def.validDefinition) { - child = (Sprite*)this->getChildByTag(ctr); + child = static_cast( this->getChildByTag(ctr) ); if (child) { uvRect.size.height = _lettersInfo[ctr].def.height; @@ -302,10 +298,8 @@ bool Label::computeAdvancesForString(unsigned short int *stringToRender) _advances = 0; } - Font &theFont = _fontAtlas->getFont(); - int letterCount = 0; - _advances = theFont.getAdvancesForTextUTF16(stringToRender, letterCount); + _advances = _fontAtlas->getFont()->getAdvancesForTextUTF16(stringToRender, letterCount); if(!_advances) return false; @@ -519,7 +513,7 @@ int Label::getAdvanceForChar(unsigned short c, int hintPositionInString) const Rect Label::getRectForChar(unsigned short c) const { - return _fontAtlas->getFont().getRectForChar(c); + return _fontAtlas->getFont()->getRectForChar(c); } // string related stuff @@ -649,31 +643,27 @@ void Label::updateDisplayedOpacity(GLubyte parentOpacity) { _displayedOpacity = _realOpacity * parentOpacity/255.0; - Object* pObj; - CCARRAY_FOREACH(_children, pObj) + for (auto child: *_children) { - Sprite *item = static_cast( pObj ); + Sprite *item = static_cast( child ); item->updateDisplayedOpacity(_displayedOpacity); } - //if (_cascadeOpacityEnabled) + V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads(); + int count = _textureAtlas->getTotalQuads(); + Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); + if (_isOpacityModifyRGB) { - V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads(); - int count = _textureAtlas->getTotalQuads(); - Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); - if (_isOpacityModifyRGB) - { - color4.r *= _displayedOpacity/255.0f; - color4.g *= _displayedOpacity/255.0f; - color4.b *= _displayedOpacity/255.0f; - } - for (int index=0; indexupdateQuad(&quads[index], index); - } + color4.r *= _displayedOpacity/255.0f; + color4.g *= _displayedOpacity/255.0f; + color4.b *= _displayedOpacity/255.0f; + } + for (int index = 0; index < count; ++index) + { + quads[index].bl.colors = color4; + quads[index].br.colors = color4; + quads[index].tl.colors = color4; + quads[index].tr.colors = color4; + _textureAtlas->updateQuad(&quads[index], index); } } diff --git a/cocos/2d/CCLabel.h b/cocos/2d/CCLabel.h index e9e56e31ca..b59850632b 100644 --- a/cocos/2d/CCLabel.h +++ b/cocos/2d/CCLabel.h @@ -82,9 +82,9 @@ public: virtual unsigned char getDisplayedOpacity() const override; // CCLabelTextFormat protocol implementation - virtual std::vector *getLettersInfo(){ return &_lettersInfo; }; - virtual bool recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex); - virtual bool recordPlaceholderInfo(int spriteIndex); + virtual std::vector *getLettersInfo() override { return &_lettersInfo; }; + virtual bool recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex) override; + virtual bool recordPlaceholderInfo(int spriteIndex) override; virtual float getLetterPosXLeft( int index ) const override; virtual float getLetterPosXRight( int index ) const override; diff --git a/cocos/2d/CCLabelTextFormatter.cpp b/cocos/2d/CCLabelTextFormatter.cpp index dc3bc82020..87dd3cf7cd 100644 --- a/cocos/2d/CCLabelTextFormatter.cpp +++ b/cocos/2d/CCLabelTextFormatter.cpp @@ -71,8 +71,6 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel) } skip += justSkipped; tIndex = j + skip; - //if (!info->visible) - // continue; if (i >= stringLength) break; From 150f1aeaab06902d711b98a874f624c57aad051a Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Thu, 31 Oct 2013 20:17:30 +0800 Subject: [PATCH 101/144] issue #2893:improve new label --- cocos/2d/CCFontAtlasFactory.cpp | 1 - cocos/2d/CCFontFNT.cpp | 2 +- cocos/2d/CCLabel.cpp | 10 ++++------ cocos/2d/CCLabel.h | 2 +- cocos/2d/CCLabelTextFormatProtocol.h | 2 +- samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp | 8 ++++---- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/cocos/2d/CCFontAtlasFactory.cpp b/cocos/2d/CCFontAtlasFactory.cpp index aeb0b6154e..f5e4f60802 100644 --- a/cocos/2d/CCFontAtlasFactory.cpp +++ b/cocos/2d/CCFontAtlasFactory.cpp @@ -31,7 +31,6 @@ FontAtlas * FontAtlasFactory::createAtlasFromFNT(const char* fntFilePath) if(font) { FontAtlas * atlas = font->createFontAtlas(); - font->release(); return atlas; } else diff --git a/cocos/2d/CCFontFNT.cpp b/cocos/2d/CCFontFNT.cpp index 7a1ca6f200..e655236a1b 100644 --- a/cocos/2d/CCFontFNT.cpp +++ b/cocos/2d/CCFontFNT.cpp @@ -32,7 +32,7 @@ FontFNT * FontFNT::create(const char* fntFilePath) delete newConf; return nullptr; } - + tempFont->autorelease(); return tempFont; } diff --git a/cocos/2d/CCLabel.cpp b/cocos/2d/CCLabel.cpp index ce928825bc..09192c0e89 100644 --- a/cocos/2d/CCLabel.cpp +++ b/cocos/2d/CCLabel.cpp @@ -420,7 +420,7 @@ void Label::addChild(Node * child, int zOrder/* =0 */, int tag/* =0 */) ///// PROTOCOL STUFF -Sprite * Label::getLetterAt(int ID) +Sprite * Label::getLetter(int ID) { if (ID < getStringLenght()) { @@ -598,8 +598,7 @@ void Label::setOpacityModifyRGB(bool isOpacityModifyRGB) _isOpacityModifyRGB = isOpacityModifyRGB; if (_children && _children->count() != 0) { - Object* child; - CCARRAY_FOREACH(_children, child) + for (auto child: *_children) { Node* pNode = static_cast( child ); if (pNode) @@ -709,10 +708,9 @@ void Label::updateDisplayedColor(const Color3B& parentColor) _displayedColor.g = _realColor.g * parentColor.g/255.0; _displayedColor.b = _realColor.b * parentColor.b/255.0; - Object* pObj; - CCARRAY_FOREACH(_children, pObj) + for (auto child: *_children) { - Sprite *item = static_cast( pObj ); + Sprite *item = static_cast( child ); item->updateDisplayedColor(_displayedColor); } diff --git a/cocos/2d/CCLabel.h b/cocos/2d/CCLabel.h index b59850632b..0d668256f2 100644 --- a/cocos/2d/CCLabel.h +++ b/cocos/2d/CCLabel.h @@ -88,7 +88,7 @@ public: virtual float getLetterPosXLeft( int index ) const override; virtual float getLetterPosXRight( int index ) const override; - virtual Sprite * getLetterAt(int ID) override; + virtual Sprite * getLetter(int ID) override; // font related stuff virtual int getCommonLineHeight() const override; diff --git a/cocos/2d/CCLabelTextFormatProtocol.h b/cocos/2d/CCLabelTextFormatProtocol.h index c2027350fc..8e1530fb3e 100644 --- a/cocos/2d/CCLabelTextFormatProtocol.h +++ b/cocos/2d/CCLabelTextFormatProtocol.h @@ -48,7 +48,7 @@ public: virtual float getLetterPosXLeft(int index) const = 0; virtual float getLetterPosXRight(int index) const = 0; // sprite related stuff - virtual cocos2d::Sprite *getLetterAt(int ID) = 0; + virtual cocos2d::Sprite *getLetter(int ID) = 0; // font related stuff virtual int getCommonLineHeight() const = 0; diff --git a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp index 9aa5d20947..e329dafcbe 100644 --- a/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp +++ b/samples/Cpp/TestCpp/Classes/LabelTest/LabelTestNew.cpp @@ -264,9 +264,9 @@ LabelFNTSpriteActions::LabelFNTSpriteActions() label->setAnchorPoint( Point(0.5f, 0.5f) ); - auto BChar = (Sprite*) label->getLetterAt(0); - auto FChar = (Sprite*) label->getLetterAt(7); - auto AChar = (Sprite*) label->getLetterAt(12); + auto BChar = (Sprite*) label->getLetter(0); + auto FChar = (Sprite*) label->getLetter(7); + auto AChar = (Sprite*) label->getLetter(12); auto rotate = RotateBy::create(2, 360); @@ -296,7 +296,7 @@ LabelFNTSpriteActions::LabelFNTSpriteActions() addChild(label2, 0, kTagBitmapAtlas2); label2->setPosition( Point(s.width/2.0f, 80) ); - auto lastChar = (Sprite*) label2->getLetterAt(3); + auto lastChar = (Sprite*) label2->getLetter(3); lastChar->runAction( rot_4ever->clone() ); schedule( schedule_selector(LabelFNTSpriteActions::step), 0.1f); From 8884c58ac1a5de5352e9d6a82326dae1f30cc519 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 31 Oct 2013 21:03:06 +0800 Subject: [PATCH 102/144] issue #2826: Updating ScriptingCore.cpp. runScript small fix. --- cocos/scripting/javascript/bindings/ScriptingCore.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index 59fe928dde..65c136da87 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -493,7 +493,7 @@ void ScriptingCore::createGlobalContext() { //JS_SetGCZeal(this->_cx, 2, JS_DEFAULT_ZEAL_FREQ); #endif this->_global = NewGlobalObject(_cx); - JS_AddObjectRoot(_cx, &_global); + JSAutoCompartment ac(_cx, _global); js::SetDefaultObjectForContext(_cx, _global); @@ -521,7 +521,7 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c cocos2d::FileUtils *futil = cocos2d::FileUtils::getInstance(); - std::string fullPath = futil->fullPathForFilename(path); + if (global == NULL) { global = _global; } @@ -534,9 +534,6 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c js::RootedScript script(cx); js::RootedObject obj(cx, global); - JS::CompileOptions options(cx); - options.setUTF8(true).setFileAndLine(fullPath.c_str(), 1); - // a) check jsc file first std::string byteCodePath = RemoveFileExt(std::string(path)) + BYTE_CODE_FILE_EXT; unsigned long length = 0; @@ -554,6 +551,10 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c /* Clear any pending exception from previous failed decoding. */ ReportException(cx); + std::string fullPath = futil->fullPathForFilename(path); + JS::CompileOptions options(cx); + options.setUTF8(true).setFileAndLine(fullPath.c_str(), 1); + #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) String* content = String::createWithContentsOfFile(path); if (content) { From 5891f009672bc0b81a4e7eaea38e641f9e0be11d Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 21:52:28 +0800 Subject: [PATCH 103/144] issue #3037:Add assetsmananger lua binding and a releated test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- external/lua/luajit/build_mac.sh | 4 ++-- .../TestLua/Classes}/lua_assetsmanager_test_sample.cpp | 0 .../Lua/TestLua/Classes}/lua_assetsmanager_test_sample.h | 0 samples/Lua/TestLua/proj.android/jni/Android.mk | 8 ++++++-- 5 files changed, 9 insertions(+), 5 deletions(-) rename {cocos/scripting/lua/bindings => samples/Lua/TestLua/Classes}/lua_assetsmanager_test_sample.cpp (100%) rename {cocos/scripting/lua/bindings => samples/Lua/TestLua/Classes}/lua_assetsmanager_test_sample.h (100%) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 3a1978b2ff..da0402247e 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3cdc74655a14f57ae21036886ccf31e32aaadce4 \ No newline at end of file +8d8d7ea290e8626153fe3dd955b85757a7bb6e05 \ No newline at end of file diff --git a/external/lua/luajit/build_mac.sh b/external/lua/luajit/build_mac.sh index d3b43e2d4b..35e88665f8 100755 --- a/external/lua/luajit/build_mac.sh +++ b/external/lua/luajit/build_mac.sh @@ -1,7 +1,7 @@ #!/bin/sh DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -SRCDIR=$DIR/LuaJit-2.0.1 -DESTDIR=$DIR/mac +SRCDIR=$DIR/src +DESTDIR=$DIR/prebuilt/mac MACOSX_DEPLOYMENT_TARGET="10.6" rm "$DESTDIR"/*.a diff --git a/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.cpp b/samples/Lua/TestLua/Classes/lua_assetsmanager_test_sample.cpp similarity index 100% rename from cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.cpp rename to samples/Lua/TestLua/Classes/lua_assetsmanager_test_sample.cpp diff --git a/cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.h b/samples/Lua/TestLua/Classes/lua_assetsmanager_test_sample.h similarity index 100% rename from cocos/scripting/lua/bindings/lua_assetsmanager_test_sample.h rename to samples/Lua/TestLua/Classes/lua_assetsmanager_test_sample.h diff --git a/samples/Lua/TestLua/proj.android/jni/Android.mk b/samples/Lua/TestLua/proj.android/jni/Android.mk index daadaf2a3a..5dc5404354 100644 --- a/samples/Lua/TestLua/proj.android/jni/Android.mk +++ b/samples/Lua/TestLua/proj.android/jni/Android.mk @@ -7,10 +7,14 @@ LOCAL_MODULE := testlua_shared LOCAL_MODULE_FILENAME := libtestlua LOCAL_SRC_FILES := testlua/main.cpp \ - ../../Classes/AppDelegate.cpp + ../../Classes/AppDelegate.cpp \ + ../../Classes/lua_assetsmanager_test_sample.cpp -LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \ + $(LOCAL_PATH)/../../../../external/lua/tolua \ + $(LOCAL_PATH)/../../../../cocos/scripting/lua/bindings + LOCAL_STATIC_LIBRARIES := curl_static_prebuilt From de4aaeda2d232f72f3d02695456898a29e456bcd Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 22:06:34 +0800 Subject: [PATCH 104/144] issue #3049:Add XMLHttpRequest lua binding and corresponding test sample --- build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- samples/Lua/TestLua/Resources/luaScript/mainMenu.lua | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 3a1978b2ff..9bd7c96932 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3cdc74655a14f57ae21036886ccf31e32aaadce4 \ No newline at end of file +99dcbba48124bf51788735fe775650f659d7302c \ No newline at end of file diff --git a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua index c1c5088530..9c4640be8e 100644 --- a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua +++ b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua @@ -44,6 +44,7 @@ require "luaScript/TransitionsTest/TransitionsTest" require "luaScript/UserDefaultTest/UserDefaultTest" require "luaScript/ZwoptexTest/ZwoptexTest" require "luaScript/LuaBridgeTest/LuaBridgeTest" +require "luaScript/XMLHttpRequestTest/XMLHttpRequestTest" local LINE_SPACE = 40 @@ -97,6 +98,7 @@ local _allTests = { { isSupported = true, name = "TouchesTest" , create_func = TouchesTest }, { isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest }, { isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain }, + { isSupported = true, name = "XMLHttpRequestTest" , create_func = XMLHttpRequestTestMain }, { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain } } From 17af5b6850dda462c2eb85d9102e8a185078f512 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Thu, 31 Oct 2013 17:56:15 -0700 Subject: [PATCH 105/144] Adds flags in GLProgram to prevent sending uneeded uniforms --- cocos/2d/CCGLProgram.cpp | 61 ++++++++++++++++++++++------------------ cocos/2d/CCGLProgram.h | 11 +++++++- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/cocos/2d/CCGLProgram.cpp b/cocos/2d/CCGLProgram.cpp index 83da8f9bdc..61fd7aaa66 100644 --- a/cocos/2d/CCGLProgram.cpp +++ b/cocos/2d/CCGLProgram.cpp @@ -75,7 +75,7 @@ GLProgram::GLProgram() , _vertShader(0) , _fragShader(0) , _hashForUniforms(NULL) -, _usesTime(false) +, _flags() { memset(_uniforms, 0, sizeof(_uniforms)); } @@ -223,27 +223,30 @@ void GLProgram::addAttribute(const char* attributeName, GLuint index) void GLProgram::updateUniforms() { _uniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX); - _uniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_MV_MATRIX); - _uniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_MVP_MATRIX); + _uniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX); + _uniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MVP_MATRIX); - _uniforms[GLProgram::UNIFORM_TIME] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_TIME); - _uniforms[GLProgram::UNIFORM_SIN_TIME] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_SIN_TIME); - _uniforms[GLProgram::UNIFORM_COS_TIME] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_COS_TIME); - - _usesTime = ( - _uniforms[GLProgram::UNIFORM_TIME] != -1 || - _uniforms[GLProgram::UNIFORM_SIN_TIME] != -1 || - _uniforms[GLProgram::UNIFORM_COS_TIME] != -1 - ); - - _uniforms[UNIFORM_RANDOM01] = glGetUniformLocation(_program, UNIFORM_NAME_RANDOM01); + _uniforms[UNIFORM_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_TIME); + _uniforms[UNIFORM_SIN_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_SIN_TIME); + _uniforms[UNIFORM_COS_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_COS_TIME); + + _uniforms[UNIFORM_RANDOM01] = glGetUniformLocation(_program, UNIFORM_NAME_RANDOM01); _uniforms[UNIFORM_SAMPLER] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER); + _flags.usesMVP = _uniforms[UNIFORM_MVP_MATRIX] != -1; + _flags.usesMV = (_uniforms[UNIFORM_MV_MATRIX] != -1 && _uniforms[UNIFORM_P_MATRIX] != -1 ); + _flags.usesTime = ( + _uniforms[UNIFORM_TIME] != -1 || + _uniforms[UNIFORM_SIN_TIME] != -1 || + _uniforms[UNIFORM_COS_TIME] != -1 + ); + _flags.usesRandom = _uniforms[UNIFORM_RANDOM01] != -1; + this->use(); // Since sample most probably won't change, set it to 0 now. - this->setUniformLocationWith1i(_uniforms[GLProgram::UNIFORM_SAMPLER], 0); + this->setUniformLocationWith1i(_uniforms[UNIFORM_SAMPLER], 0); } bool GLProgram::link() @@ -527,19 +530,23 @@ void GLProgram::setUniformsForBuiltins() { kmMat4 matrixP; kmMat4 matrixMV; - kmMat4 matrixMVP; - + kmGLGetMatrix(KM_GL_PROJECTION, &matrixP); kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV); - kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); - - setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.mat, 1); - setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.mat, 1); - setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.mat, 1); - - if(_usesTime) - { + + if(_flags.usesMVP) { + kmMat4 matrixMVP; + kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); + setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.mat, 1); + } + + if(_flags.usesMV) { + setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.mat, 1); + setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.mat, 1); + } + + if(_flags.usesTime) { Director *director = Director::getInstance(); // This doesn't give the most accurate global time value. // Cocos2D doesn't store a high precision time value, so this will have to do. @@ -551,10 +558,8 @@ void GLProgram::setUniformsForBuiltins() setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_COS_TIME], time/8.0, time/4.0, time/2.0, cosf(time)); } - if (_uniforms[GLProgram::UNIFORM_RANDOM01] != -1) - { + if(_flags.usesRandom) setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_RANDOM01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1()); - } } void GLProgram::reset() diff --git a/cocos/2d/CCGLProgram.h b/cocos/2d/CCGLProgram.h index cea1add0b2..f218f7181e 100644 --- a/cocos/2d/CCGLProgram.h +++ b/cocos/2d/CCGLProgram.h @@ -244,7 +244,16 @@ private: GLuint _fragShader; GLint _uniforms[UNIFORM_MAX]; struct _hashUniformEntry* _hashForUniforms; - bool _usesTime; + + struct flag_struct { + unsigned int usesTime:1; + unsigned int usesMVP:1; + unsigned int usesMV:1; + unsigned int usesRandom:1; + + // handy way to initialize the bitfield + flag_struct() { memset(this, 0, sizeof(*this)); } + } _flags; }; // end of shaders group From 0c6748b5777c836ac4629a49d1ab110d91bc70b5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 10:44:15 +0800 Subject: [PATCH 106/144] issue #2826: Bug fix of 'js::IsInRequest' --- external/spidermonkey/include/android/js/RootingAPI.h | 5 +++-- external/spidermonkey/include/ios/js/RootingAPI.h | 5 +++-- external/spidermonkey/include/mac/js/RootingAPI.h | 5 +++-- external/spidermonkey/include/win32/js/RootingAPI.h | 5 +++-- .../android/armeabi-v7a/libjs_static.a.REMOVED.git-id | 2 +- .../prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id | 2 +- .../prebuilt/android/x86/libjs_static.a.REMOVED.git-id | 2 +- .../spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id | 2 +- .../spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id | 2 +- .../prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id | 2 +- .../prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id | 2 +- 11 files changed, 19 insertions(+), 15 deletions(-) diff --git a/external/spidermonkey/include/android/js/RootingAPI.h b/external/spidermonkey/include/android/js/RootingAPI.h index 99295f1238..c4a5925ae7 100644 --- a/external/spidermonkey/include/android/js/RootingAPI.h +++ b/external/spidermonkey/include/android/js/RootingAPI.h @@ -628,11 +628,12 @@ struct GCMethods #endif }; -#if defined(DEBUG) +// XXX: Needed for cocos2d JS Bindings +//#if defined(DEBUG) /* This helper allows us to assert that Rooted is scoped within a request. */ extern JS_PUBLIC_API(bool) IsInRequest(JSContext *cx); -#endif +//#endif } /* namespace js */ diff --git a/external/spidermonkey/include/ios/js/RootingAPI.h b/external/spidermonkey/include/ios/js/RootingAPI.h index 99295f1238..c4a5925ae7 100644 --- a/external/spidermonkey/include/ios/js/RootingAPI.h +++ b/external/spidermonkey/include/ios/js/RootingAPI.h @@ -628,11 +628,12 @@ struct GCMethods #endif }; -#if defined(DEBUG) +// XXX: Needed for cocos2d JS Bindings +//#if defined(DEBUG) /* This helper allows us to assert that Rooted is scoped within a request. */ extern JS_PUBLIC_API(bool) IsInRequest(JSContext *cx); -#endif +//#endif } /* namespace js */ diff --git a/external/spidermonkey/include/mac/js/RootingAPI.h b/external/spidermonkey/include/mac/js/RootingAPI.h index 99295f1238..c4a5925ae7 100644 --- a/external/spidermonkey/include/mac/js/RootingAPI.h +++ b/external/spidermonkey/include/mac/js/RootingAPI.h @@ -628,11 +628,12 @@ struct GCMethods #endif }; -#if defined(DEBUG) +// XXX: Needed for cocos2d JS Bindings +//#if defined(DEBUG) /* This helper allows us to assert that Rooted is scoped within a request. */ extern JS_PUBLIC_API(bool) IsInRequest(JSContext *cx); -#endif +//#endif } /* namespace js */ diff --git a/external/spidermonkey/include/win32/js/RootingAPI.h b/external/spidermonkey/include/win32/js/RootingAPI.h index 99295f1238..c4a5925ae7 100644 --- a/external/spidermonkey/include/win32/js/RootingAPI.h +++ b/external/spidermonkey/include/win32/js/RootingAPI.h @@ -628,11 +628,12 @@ struct GCMethods #endif }; -#if defined(DEBUG) +// XXX: Needed for cocos2d JS Bindings +//#if defined(DEBUG) /* This helper allows us to assert that Rooted is scoped within a request. */ extern JS_PUBLIC_API(bool) IsInRequest(JSContext *cx); -#endif +//#endif } /* namespace js */ diff --git a/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id index 8362daf11f..66d2ff3161 100644 --- a/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -faf19f806c33a8c42138cd4ada1c76d04f9510f4 \ No newline at end of file +0e1091b9f67b4d348d01b69e998be70c9e0b2dad \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id index 8da98b5613..8a8f30faca 100644 --- a/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -9c5b123f113fb3b0b6846b4f1123ec5a40004944 \ No newline at end of file +23bfd06f14371832fa99b4efb76133ade10887ec \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id index 74e8973064..fbdaca36eb 100644 --- a/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -3e18fa7933f481d605147b1d46dd7afee105fa2c \ No newline at end of file +1eb9de4a5ab182f329be479e736c06ac8ab83a00 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id index a263aa1a15..3aa7da9b21 100644 --- a/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/ios/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -62ff11f15f6f4dae163513e336bc3e4671b91a90 \ No newline at end of file +1267f1437ae315da4c23e0fc5e7e3f70b4b3c8e2 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id index 609f8680c6..e3f35605ac 100644 --- a/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/mac/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -591cdbb9304d6f7b5682542b7a50e0b5ae4d6a4d \ No newline at end of file +2385a209e3aa59896599e079658d761fd2985c9a \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id b/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id index 7e9dc81732..e9a69561f8 100644 --- a/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/win32/mozjs-25.0.dll.REMOVED.git-id @@ -1 +1 @@ -c1212ee7de1da38ee10b27e327120205ab2cac7c \ No newline at end of file +66328744e55deaa5397a58a7e0a49b34a602697b \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id b/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id index ae3f274acc..729e48a68d 100644 --- a/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/win32/mozjs-25.0.lib.REMOVED.git-id @@ -1 +1 @@ -5991d26d951ae7b8398cd037bb22422ec33ab949 \ No newline at end of file +746eb762bc48a27219221c08bd8ada90727f3921 \ No newline at end of file From baccf828f32de6a628facc0a248bcf1388bea36c Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 10:45:01 +0800 Subject: [PATCH 107/144] closed #2826: Removing js::IsInRequest in ScriptingCore.cpp for win32. --- cocos/scripting/javascript/bindings/ScriptingCore.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index 65c136da87..5d902c1c23 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -79,15 +79,6 @@ static std::map ports_sockets; // name ~> globals static std::map globals; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) -namespace js { -bool IsInRequest(JSContext* cx) -{ - return true; -} -} -#endif - static void ReportException(JSContext *cx) { if (JS_IsExceptionPending(cx)) { From 0298c338a6198de180bb287ead1d496a7675ccf5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 10:46:06 +0800 Subject: [PATCH 108/144] issue #2826: Updating cocos2d-console submodule. --- tools/cocos2d-console | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cocos2d-console b/tools/cocos2d-console index 37a695d46c..3556d41429 160000 --- a/tools/cocos2d-console +++ b/tools/cocos2d-console @@ -1 +1 @@ -Subproject commit 37a695d46c0a7386a261733f9f76583895681702 +Subproject commit 3556d41429e487e88fbbd5222df95fdd4c2ddf7b From f3ff7955a8fc94a9033efd4b89f056e6c25fa57d Mon Sep 17 00:00:00 2001 From: samuelhu Date: Fri, 1 Nov 2013 11:18:02 +0800 Subject: [PATCH 109/144] issue #3037:Modify platform build config --- .../project.pbxproj.REMOVED.git-id | 2 +- samples/Lua/TestLua/Classes/AppDelegate.cpp | 2 +- .../luaScript/AssetsManagerTest/AssetsManagerTest.lua | 7 ++++--- samples/Lua/TestLua/proj.android/jni/Android.mk | 9 +++++---- samples/Lua/TestLua/proj.linux/Makefile | 7 +++++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index da0402247e..56fa5cef1e 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -8d8d7ea290e8626153fe3dd955b85757a7bb6e05 \ No newline at end of file +ec80e8e2bcdb07b161a4ba7fcdee13bfec8cf347 \ No newline at end of file diff --git a/samples/Lua/TestLua/Classes/AppDelegate.cpp b/samples/Lua/TestLua/Classes/AppDelegate.cpp index 025f938b6b..deefa14f40 100644 --- a/samples/Lua/TestLua/Classes/AppDelegate.cpp +++ b/samples/Lua/TestLua/Classes/AppDelegate.cpp @@ -51,7 +51,7 @@ bool AppDelegate::applicationDidFinishLaunching() LuaEngine* pEngine = LuaEngine::getInstance(); ScriptEngineManager::getInstance()->setScriptEngine(pEngine); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID ||CC_TARGET_PLATFORM == CC_PLATFORM_IOS) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID ||CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC) LuaStack* stack = pEngine->getLuaStack(); register_assetsmanager_test_sample(stack->getLuaState()); #endif diff --git a/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua index 853342a706..67be1499eb 100644 --- a/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua +++ b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua @@ -12,23 +12,24 @@ local menuItemNames = local winSize = cc.Director:getInstance():getWinSize() local function updateLayer() + local layer = cc.Layer:create() local support = false if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or (cc.PLATFORM_OS_WINDOWS == targetPlatform) or (cc.PLATFORM_OS_ANDROID == targetPlatform) - or (cc.PLATFORM_OS_IPHONE == targetPlatform) then + or (cc.PLATFORM_OS_MAC == targetPlatform) then support = true end if not support then - return nil + print("Platform is not supported!") + return layer end local isUpdateItemClicked = false local assetsManager = nil local pathToSave = "" - local layer = cc.Layer:create() local menu = cc.Menu:create() menu:setPosition(cc.p(0, 0)) cc.MenuItemFont:setFontName("Arial") diff --git a/samples/Lua/TestLua/proj.android/jni/Android.mk b/samples/Lua/TestLua/proj.android/jni/Android.mk index 5dc5404354..4bc4ceafb3 100644 --- a/samples/Lua/TestLua/proj.android/jni/Android.mk +++ b/samples/Lua/TestLua/proj.android/jni/Android.mk @@ -6,14 +6,15 @@ LOCAL_MODULE := testlua_shared LOCAL_MODULE_FILENAME := libtestlua -LOCAL_SRC_FILES := testlua/main.cpp \ +LOCAL_SRC_FILES += testlua/main.cpp \ ../../Classes/AppDelegate.cpp \ ../../Classes/lua_assetsmanager_test_sample.cpp -LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \ - $(LOCAL_PATH)/../../../../external/lua/tolua \ - $(LOCAL_PATH)/../../../../cocos/scripting/lua/bindings +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../Classes \ + $(LOCAL_PATH)/../../../../../external/lua/tolua \ + $(LOCAL_PATH)/../../../../../extensions \ + $(LOCAL_PATH)/../../../../../cocos/scripting/lua/bindings LOCAL_STATIC_LIBRARIES := curl_static_prebuilt diff --git a/samples/Lua/TestLua/proj.linux/Makefile b/samples/Lua/TestLua/proj.linux/Makefile index 5151716394..8e9246c6ee 100644 --- a/samples/Lua/TestLua/proj.linux/Makefile +++ b/samples/Lua/TestLua/proj.linux/Makefile @@ -4,10 +4,13 @@ COCOS_ROOT = ../../../.. INCLUDES = -I../Classes \ -I$(COCOS_ROOT)/audio/include \ -I$(COCOS_ROOT)/cocos/scripting/lua/bindings \ - -I$(COCOS_ROOT)/external/lua/lua + -I$(COCOS_ROOT)/external/lua/lua \ + -I$(COCOS_ROOT)/external/lua/tolua \ + -I$(COCOS_ROOT)/extensions SOURCES = main.cpp \ -../Classes/AppDelegate.cpp +../Classes/AppDelegate.cpp \ +../Classes/lua_assetsmanager_test_sample.cpp SHAREDLIBS += -lcocos2d -lcocosdenshion -llua From 5010779e39242f9b0ff40cbee5b1fcb247ad2e86 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Fri, 1 Nov 2013 11:36:06 +0800 Subject: [PATCH 110/144] issue #3049:Reset .project file in pro.android. --- samples/Lua/TestLua/proj.android/.project | 52 +++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/samples/Lua/TestLua/proj.android/.project b/samples/Lua/TestLua/proj.android/.project index 8703060095..3c1261c623 100644 --- a/samples/Lua/TestLua/proj.android/.project +++ b/samples/Lua/TestLua/proj.android/.project @@ -6,12 +6,56 @@ - org.eclipse.ui.externaltools.ExternalToolBuilder - full,incremental, + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, - LaunchConfigHandle - <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.buildArguments + ${ProjDirPath}/build_native.sh + + + org.eclipse.cdt.make.core.buildCommand + bash + + + org.eclipse.cdt.make.core.buildLocation + ${ProjDirPath} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false From 1d932ae95f5a04df83895934ed63f40dd8016f0d Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 11:46:02 +0800 Subject: [PATCH 111/144] Updating travic-ci scripts. --- tools/travis-scripts/before-install.sh | 4 +-- tools/travis-scripts/generate-jsbindings.sh | 8 ++--- tools/travis-scripts/run-script.sh | 39 ++++++--------------- 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/tools/travis-scripts/before-install.sh b/tools/travis-scripts/before-install.sh index 4353b026a8..93cdb195fe 100755 --- a/tools/travis-scripts/before-install.sh +++ b/tools/travis-scripts/before-install.sh @@ -102,8 +102,8 @@ elif [ "$PLATFORM"x = "linux"x ]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 90 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7 g++ --version - bash $COCOS2DX_ROOT/install-deps-linux.sh - bash $DIR/install_glfw.sh + bash $COCOS2DX_ROOT/build/install-deps-linux.sh + bash $COCOS2DX_ROOT/build/install_glfw.sh install_android_ndk install_llvm elif [ "$PLATFORM"x = "nacl"x ]; then diff --git a/tools/travis-scripts/generate-jsbindings.sh b/tools/travis-scripts/generate-jsbindings.sh index 2a1dd3b69a..dcb2b9bd0f 100755 --- a/tools/travis-scripts/generate-jsbindings.sh +++ b/tools/travis-scripts/generate-jsbindings.sh @@ -20,7 +20,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" COCOS2DX_ROOT="$DIR"/../.. TOJS_ROOT=$COCOS2DX_ROOT/tools/tojs TOLUA_ROOT=$COCOS2DX_ROOT/tools/tolua -GENERATED_WORKTREE="$COCOS2DX_ROOT"/scripting/auto-generated +GENERATED_WORKTREE="$COCOS2DX_ROOT"/cocos/scripting/auto-generated COMMITTAG="[AUTO]" # Exit on error @@ -75,10 +75,10 @@ echo "Set git user for the submodule of ${GENERATED_WORKTREE}" git config user.email ${GH_EMAIL} git config user.name ${GH_USER} #Set remotes -git remote add upstream https://${GH_USER}:${GH_PASSWORD}@github.com/folecr/cocos2dx-autogen-bindings.git 2> /dev/null > /dev/null +git remote add upstream https://${GH_USER}:${GH_PASSWORD}@github.com/cocos2d-x/bindings-auto-generated.git 2> /dev/null > /dev/null -echo "Delete all directories and files except '.git' and 'README'." -ls -a | grep -E -v ^\[.\]\{1,2\}$ | grep -E -v ^\.git$ | grep -E -v ^README$ | xargs -I{} rm -rf {} +echo "Delete all directories and files except '.git' and 'README.md'." +ls -a | grep -E -v ^\[.\]\{1,2\}$ | grep -E -v ^\.git$ | grep -E -v ^README.md$ | xargs -I{} rm -rf {} echo "Show files in ${GENERATED_WORKTREE} folder." ls -a popd diff --git a/tools/travis-scripts/run-script.sh b/tools/travis-scripts/run-script.sh index 79c063dc0e..7e86b00319 100755 --- a/tools/travis-scripts/run-script.sh +++ b/tools/travis-scripts/run-script.sh @@ -5,15 +5,6 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" COCOS2DX_ROOT="$DIR"/../.. -build_android() -{ - echo "Current dir: `pwd`" - pushd $1/proj.android - ln -s $COCOS2DX_ROOT/android_build_objs obj - ./build_native.sh - popd -} - if [ "$GEN_JSB"x = "YES"x ]; then # Re-generation of the javascript bindings can perform push of the new # version back to github. We don't do this for pull requests, or if @@ -51,23 +42,15 @@ elif [ "$PLATFORM"x = "android"x ]; then # Create a directory for temporary objects mkdir android_build_objs - # Build samples - echo "Building samples ..." - cd $COCOS2DX_ROOT/samples/Cpp - build_android HelloCpp - build_android TestCpp - build_android AssetsManagerTest + PROJECTS=("Cpp/HelloCpp" "Cpp/TestCpp" "Cpp/AssetsManagerTest" "Javascript/TestJavascript" "Javascript/CocosDragonJS" "Javascript/CrystalCraze" "Javascript/MoonWarriors" "Javascript/WatermelonWithMe" "Lua/HelloLua" "Lua/TestLua") + for i in ${PROJECTS[*]}; do + ln -s $COCOS2DX_ROOT/android_build_objs $COCOS2DX_ROOT/samples/$i/proj.android/obj + done - cd $COCOS2DX_ROOT/samples/Javascript - build_android TestJavascript - build_android CocosDragonJS - build_android CrystalCraze - build_android MoonWarriors - build_android WatermelonWithMe - - cd $COCOS2DX_ROOT/samples/Lua - build_android HelloLua - build_android TestLua + # Build all samples + echo "Building all samples ..." + cd $COCOS2DX_ROOT/build + ./android-build.py all # Build template # echo "Building template ..." @@ -80,7 +63,7 @@ elif [ "$PLATFORM"x = "nacl"x ]; then export NACL_SDK_ROOT=$HOME/bin/nacl_sdk/pepper_canary export PATH=$PATH:$NACL_SDK_ROOT/toolchain/linux_x86_newlib/bin export PATH=$PATH:$NACL_SDK_ROOT/toolchain/linux_arm_newlib/bin - cd $COCOS2DX_ROOT + cd $COCOS2DX_ROOT/build make -j4 elif [ "$PLATFORM"x = "linux"x ]; then # Generate binding glue codes @@ -88,7 +71,7 @@ elif [ "$PLATFORM"x = "linux"x ]; then cd $COCOS2DX_ROOT/tools/travis-scripts ./generate-jsbindings.sh - cd $COCOS2DX_ROOT + cd $COCOS2DX_ROOT/build make -j4 elif [ "$PLATFORM"x = "emscripten"x ]; then # Generate binding glue codes @@ -96,7 +79,7 @@ elif [ "$PLATFORM"x = "emscripten"x ]; then cd $COCOS2DX_ROOT/tools/travis-scripts ./generate-jsbindings.sh - cd $COCOS2DX_ROOT + cd $COCOS2DX_ROOT/build export PYTHON=/usr/bin/python export LLVM=$HOME/bin/clang+llvm-3.2/bin export LLVM_ROOT=$LLVM From 72d6f8650b3d06ae67332cdfb6f933ec54c50978 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 11:50:43 +0800 Subject: [PATCH 112/144] Regular expression fix for generate-jsbindings.sh. --- tools/travis-scripts/generate-jsbindings.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/travis-scripts/generate-jsbindings.sh b/tools/travis-scripts/generate-jsbindings.sh index dcb2b9bd0f..cd7f897e20 100755 --- a/tools/travis-scripts/generate-jsbindings.sh +++ b/tools/travis-scripts/generate-jsbindings.sh @@ -78,7 +78,7 @@ git config user.name ${GH_USER} git remote add upstream https://${GH_USER}:${GH_PASSWORD}@github.com/cocos2d-x/bindings-auto-generated.git 2> /dev/null > /dev/null echo "Delete all directories and files except '.git' and 'README.md'." -ls -a | grep -E -v ^\[.\]\{1,2\}$ | grep -E -v ^\.git$ | grep -E -v ^README.md$ | xargs -I{} rm -rf {} +ls -a | grep -E -v ^\[.\]\{1,2\}$ | grep -E -v ^\.git$ | grep -E -v ^README\.md$ | xargs -I{} rm -rf {} echo "Show files in ${GENERATED_WORKTREE} folder." ls -a popd From d98c6f8de60a1e5449ca7ba9ae817d07b01792ea Mon Sep 17 00:00:00 2001 From: minggo Date: Fri, 1 Nov 2013 14:27:29 +0800 Subject: [PATCH 113/144] can run build-android.python in any path --- build/android-build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/android-build.py b/build/android-build.py index 62bc226e77..e59ee61bf1 100755 --- a/build/android-build.py +++ b/build/android-build.py @@ -164,7 +164,7 @@ def build_samples(target,ndk_build_param): select_toolchain_version() build_targets = caculate_built_samples(target) - current_dir = os.getcwd() + current_dir = os.path.dirname(os.path.realpath(__file__)) cocos_root = os.path.join(current_dir, "..") app_android_root = '' From b0fdb66d2d8d17ea84c3b107a38fb66c3eebee45 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Fri, 1 Nov 2013 14:38:14 +0800 Subject: [PATCH 114/144] Modify the all luajit build scripts and let libluajit.a of mac only support 64bit --- .../project.pbxproj.REMOVED.git-id | 2 +- external/lua/luajit/build_android.sh | 8 +++--- external/lua/luajit/build_ios.sh | 4 +-- external/lua/luajit/build_mac.sh | 25 +++---------------- .../prebuilt/mac/libluajit.a.REMOVED.git-id | 2 +- tools/tolua/cocos2dx.ini | 3 ++- 6 files changed, 13 insertions(+), 31 deletions(-) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 9bd7c96932..626de951df 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -99dcbba48124bf51788735fe775650f659d7302c \ No newline at end of file +167357a8d59c47386aaae51aafe1c47e34de0202 \ No newline at end of file diff --git a/external/lua/luajit/build_android.sh b/external/lua/luajit/build_android.sh index be17f6157f..c0551cb92a 100755 --- a/external/lua/luajit/build_android.sh +++ b/external/lua/luajit/build_android.sh @@ -2,7 +2,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" host_os=`uname -s | tr "[:upper:]" "[:lower:]"` -SRCDIR=$DIR/LuaJit-2.0.1 +SRCDIR=$DIR/src cd "$SRCDIR" NDK=$NDK_ROOT @@ -12,7 +12,7 @@ NDKP=$NDKVER/prebuilt/${host_os}-x86/bin/arm-linux-androideabi- NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm" # Android/ARM, armeabi (ARMv5TE soft-float), Android 2.2+ (Froyo) -DESTDIR=$DIR/android/armeabi +DESTDIR=$DIR/prebuilt/android/armeabi rm "$DESTDIR"/*.a make clean make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF" @@ -23,7 +23,7 @@ fi; # Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS) NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8" -DESTDIR=$DIR/android/armeabi-v7a +DESTDIR=$DIR/prebuilt/android/armeabi-v7a rm "$DESTDIR"/*.a make clean make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF $NDKARCH" @@ -34,7 +34,7 @@ fi; # Android/x86, x86 (i686 SSE3), Android 4.0+ (ICS) NDKABI=14 -DESTDIR=$DIR/android/x86 +DESTDIR=$DIR/prebuilt/android/x86 NDKVER=$NDK/toolchains/x86-4.6 NDKP=$NDKVER/prebuilt/${host_os}-x86/bin/i686-linux-android- NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86" diff --git a/external/lua/luajit/build_ios.sh b/external/lua/luajit/build_ios.sh index 79a8d4a5d4..52ea997371 100755 --- a/external/lua/luajit/build_ios.sh +++ b/external/lua/luajit/build_ios.sh @@ -3,8 +3,8 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" LIPO="xcrun -sdk iphoneos lipo" STRIP="xcrun -sdk iphoneos strip" -SRCDIR=$DIR/LuaJit-2.0.1 -DESTDIR=$DIR/ios +SRCDIR=$DIR/src +DESTDIR=$DIR/prebuilt/ios IXCODE=`xcode-select -print-path` ISDK=$IXCODE/Platforms/iPhoneOS.platform/Developer ISDKVER=iPhoneOS6.1.sdk diff --git a/external/lua/luajit/build_mac.sh b/external/lua/luajit/build_mac.sh index d3b43e2d4b..f5f93d3d56 100755 --- a/external/lua/luajit/build_mac.sh +++ b/external/lua/luajit/build_mac.sh @@ -1,36 +1,17 @@ #!/bin/sh DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -SRCDIR=$DIR/LuaJit-2.0.1 -DESTDIR=$DIR/mac +SRCDIR=$DIR/src +DESTDIR=$DIR/prebuilt/mac MACOSX_DEPLOYMENT_TARGET="10.6" rm "$DESTDIR"/*.a cd $SRCDIR -make clean -make CC="gcc -m32 -arch i386" clean all - -if [ -f $SRCDIR/src/libluajit.a ]; then - mv $SRCDIR/src/libluajit.a $DESTDIR/libluajit_32.a -fi; - make clean make CC="gcc -m64 -arch x86_64" clean all if [ -f $SRCDIR/src/libluajit.a ]; then - mv $SRCDIR/src/libluajit.a $DESTDIR/libluajit_64.a + mv $SRCDIR/src/libluajit.a $DESTDIR/libluajit.a fi; make clean - -# create lipo library -lipo -create -output $DESTDIR/libluajit.a $DESTDIR/libluajit_32.a $DESTDIR/libluajit_64.a - -rm $DESTDIR/libluajit_32.a $DESTDIR/libluajit_64.a - -# strip -strip -S $DESTDIR/libluajit.a - -# info -lipo -info $DESTDIR/libluajit.a - diff --git a/external/lua/luajit/prebuilt/mac/libluajit.a.REMOVED.git-id b/external/lua/luajit/prebuilt/mac/libluajit.a.REMOVED.git-id index df8d16ea2b..2b297152c9 100644 --- a/external/lua/luajit/prebuilt/mac/libluajit.a.REMOVED.git-id +++ b/external/lua/luajit/prebuilt/mac/libluajit.a.REMOVED.git-id @@ -1 +1 @@ -51a333ce3c98512e50967762ab907be96d6d14e5 \ No newline at end of file +c319cbee7c1d56c5e7add0ba9dcd272ccb36366d \ No newline at end of file diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index 8721cdba4f..2411628c85 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -103,7 +103,8 @@ skip = Node::[setGLServerState description getUserObject .*UserData getGLServerS Camera::[getEyeXYZ getCenterXYZ getUpXYZ], ccFontDefinition::[*], Object::[autorelease isEqual acceptVisitor update], - UserDefault::[getInstance (s|g)etDataForKey] + UserDefault::[getInstance (s|g)etDataForKey], + Label::[getLettersInfo] rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames getSpriteFrameByName=getSpriteFrame], ProgressTimer::[setReverseProgress=setReverseDirection], From 8580b166380041166bad7c60bc6366442e3bc53d Mon Sep 17 00:00:00 2001 From: samuelhu Date: Fri, 1 Nov 2013 14:40:35 +0800 Subject: [PATCH 115/144] Modify let the libluajit.a of mac only support 64bit --- build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 626de951df..e3805fe0de 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -167357a8d59c47386aaae51aafe1c47e34de0202 \ No newline at end of file +e2d62e7c366bf3a2c2bbd08ce9b482dab2aa38c4 \ No newline at end of file From 6eb6809b2c524a005f9236d39bd1355a599d7ca0 Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Fri, 1 Nov 2013 06:52:31 +0000 Subject: [PATCH 116/144] [AUTO] : updating submodule reference to latest autogenerated bindings --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index c1da46eabb..3366eebe56 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit c1da46eabb46727a66daa4d64d9841b09fa6d63c +Subproject commit 3366eebe56e09c3d32201654f5a29813c8b5defc From ed10b92a607098865eea82338c0c42e93c415ef9 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 15:19:10 +0800 Subject: [PATCH 117/144] Fix of including wrong include files. --- build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/platform/mac/CCDirectorCaller.mm | 2 +- .../mac/{CCEventDispatcher.h => CCEventDispatcherMac.h} | 0 .../mac/{CCEventDispatcher.mm => CCEventDispatcherMac.mm} | 3 +-- cocos/2d/platform/mac/EAGLView.mm | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) rename cocos/2d/platform/mac/{CCEventDispatcher.h => CCEventDispatcherMac.h} (100%) rename cocos/2d/platform/mac/{CCEventDispatcher.mm => CCEventDispatcherMac.mm} (99%) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index f82767e410..d13b25c773 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -f918efd122d7a0cfabddf411f64d954d4fcd8579 \ No newline at end of file +245681d0a739a5432c0e588df5627789e03d902f \ No newline at end of file diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 9bd7c96932..f27b44e3fa 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -99dcbba48124bf51788735fe775650f659d7302c \ No newline at end of file +92d0a8b3ee96411da3d9d2d3422dee5e9e0b40fb \ No newline at end of file diff --git a/cocos/2d/platform/mac/CCDirectorCaller.mm b/cocos/2d/platform/mac/CCDirectorCaller.mm index 83d9689470..af4645a7aa 100644 --- a/cocos/2d/platform/mac/CCDirectorCaller.mm +++ b/cocos/2d/platform/mac/CCDirectorCaller.mm @@ -25,7 +25,7 @@ #import "CCDirectorCaller.h" #import "CCDirector.h" #import "EAGLView.h" -#import "CCEventDispatcher.h" +#import "CCEventDispatcherMac.h" #include "CCAutoreleasePool.h" static id s_sharedDirectorCaller; diff --git a/cocos/2d/platform/mac/CCEventDispatcher.h b/cocos/2d/platform/mac/CCEventDispatcherMac.h similarity index 100% rename from cocos/2d/platform/mac/CCEventDispatcher.h rename to cocos/2d/platform/mac/CCEventDispatcherMac.h diff --git a/cocos/2d/platform/mac/CCEventDispatcher.mm b/cocos/2d/platform/mac/CCEventDispatcherMac.mm similarity index 99% rename from cocos/2d/platform/mac/CCEventDispatcher.mm rename to cocos/2d/platform/mac/CCEventDispatcherMac.mm index 6487d877a1..89660ce0f5 100644 --- a/cocos/2d/platform/mac/CCEventDispatcher.mm +++ b/cocos/2d/platform/mac/CCEventDispatcherMac.mm @@ -27,12 +27,11 @@ // But in case they are included, it won't be compiled. #import -#import "CCEventDispatcher.h" +#import "CCEventDispatcherMac.h" #import "ccConfig.h" #include "utlist.h" #include "CCDirector.h" -#include "platform/mac/CCEventDispatcher.h" //NS_CC_BEGIN; static CCEventDispatcher *sharedDispatcher = nil; diff --git a/cocos/2d/platform/mac/EAGLView.mm b/cocos/2d/platform/mac/EAGLView.mm index 2bc17be1f1..ff456d0e6a 100644 --- a/cocos/2d/platform/mac/EAGLView.mm +++ b/cocos/2d/platform/mac/EAGLView.mm @@ -37,7 +37,7 @@ THE SOFTWARE. #import "CCTouch.h" #import "CCIMEDispatcher.h" #import "CCWindow.h" -#import "CCEventDispatcher.h" +#import "CCEventDispatcherMac.h" #import "CCEGLView.h" From a04d1acedeb4448bedcbdc549940fe33ad5441b5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 15:19:51 +0800 Subject: [PATCH 118/144] Fix of compilation errros of SimpleGame. --- samples/Cpp/SimpleGame/Classes/HelloWorldScene.cpp | 7 +++++-- samples/Cpp/SimpleGame/Classes/HelloWorldScene.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/samples/Cpp/SimpleGame/Classes/HelloWorldScene.cpp b/samples/Cpp/SimpleGame/Classes/HelloWorldScene.cpp index d5052e66a0..85d2f97be9 100644 --- a/samples/Cpp/SimpleGame/Classes/HelloWorldScene.cpp +++ b/samples/Cpp/SimpleGame/Classes/HelloWorldScene.cpp @@ -100,8 +100,11 @@ bool HelloWorld::init() this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 ); - this->setTouchEnabled(true); - + auto dispatcher = Director::getInstance()->getEventDispatcher(); + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this); + dispatcher->addEventListenerWithSceneGraphPriority(listener, this); + _targets = new Array(); _targets->init(); diff --git a/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h b/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h index 279f2c4399..ee65eb2f08 100644 --- a/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h +++ b/samples/Cpp/SimpleGame/Classes/HelloWorldScene.h @@ -30,7 +30,7 @@ public: void updateGame(float dt); - void onTouchesEnded(const std::vector& touches, cocos2d::Event* event) override; + void onTouchesEnded(const std::vector& touches, cocos2d::Event* event); protected: From daf4e22819c8d01869524a8afa6564f90dd56b68 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 15:33:57 +0800 Subject: [PATCH 119/144] [Bindings] Skip Label::getLettersInfo --- tools/tojs/cocos2dx.ini | 1 + tools/tolua/cocos2dx.ini | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/tojs/cocos2dx.ini b/tools/tojs/cocos2dx.ini index 510440e508..e49e3dbc0f 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -51,6 +51,7 @@ skip = Node::[^setPosition$ getGrid setGLServerState description getUserObject . Copying::[*], LabelProtocol::[*], LabelTextFormatProtocol::[*], + Label::[getLettersInfo], .*Delegate::[*], PoolManager::[*], Texture2D::[initWithPVRTCData addPVRTCImage releaseData setTexParameters initWithData keepData], diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index 2411628c85..3a1d67655c 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -48,6 +48,7 @@ skip = Node::[setGLServerState description getUserObject .*UserData getGLServerS Layer.*::[didAccelerate (g|s)etBlendFunc keyPressed keyReleased], Menu.*::[.*Target getSubItems create initWithItems alignItemsInRows alignItemsInColumns], MenuItem.*::[create setCallback initWithCallback], + Label::[getLettersInfo], Copying::[*], .*Protocol::[*], .*Delegate::[*], From 8e7ed129c52388670ad7abf79ceb260a57054aef Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 15:39:46 +0800 Subject: [PATCH 120/144] Update before-install.sh --- tools/travis-scripts/before-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/travis-scripts/before-install.sh b/tools/travis-scripts/before-install.sh index 93cdb195fe..79154e4604 100755 --- a/tools/travis-scripts/before-install.sh +++ b/tools/travis-scripts/before-install.sh @@ -103,7 +103,6 @@ elif [ "$PLATFORM"x = "linux"x ]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 90 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7 g++ --version bash $COCOS2DX_ROOT/build/install-deps-linux.sh - bash $COCOS2DX_ROOT/build/install_glfw.sh install_android_ndk install_llvm elif [ "$PLATFORM"x = "nacl"x ]; then From 8aac938531aa640fdb5ba6a752b91baa8f1901f5 Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Fri, 1 Nov 2013 07:42:11 +0000 Subject: [PATCH 121/144] [AUTO] : updating submodule reference to latest autogenerated bindings --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index 3366eebe56..dac276f47b 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit 3366eebe56e09c3d32201654f5a29813c8b5defc +Subproject commit dac276f47b7162898a526b385f076e5712acf12d From 0a59d9eb3e2b591097c1770564c2ac515c654efd Mon Sep 17 00:00:00 2001 From: minggo Date: Fri, 1 Nov 2013 16:44:04 +0800 Subject: [PATCH 122/144] fix assetsmansger path --- build/android-build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/android-build.py b/build/android-build.py index e59ee61bf1..a9791936a5 100755 --- a/build/android-build.py +++ b/build/android-build.py @@ -176,7 +176,7 @@ def build_samples(target,ndk_build_param): elif target == 'simplegame': app_android_root = os.path.join(cocos_root, 'samples/Cpp/SimpleGame/proj.android') elif target == 'assetsmanager': - app_android_root = os.path.join(cocos_root, 'samples/Cpp/AssetsManager/proj.android') + app_android_root = os.path.join(cocos_root, 'samples/Cpp/AssetsManagerTest/proj.android') elif target == 'hellolua': app_android_root = os.path.join(cocos_root, 'samples/Lua/HelloLua/proj.android') elif target == 'testlua': From 915d75ea7c6bdb9afd65c509fad8ca09e785b915 Mon Sep 17 00:00:00 2001 From: minggo Date: Fri, 1 Nov 2013 16:44:35 +0800 Subject: [PATCH 123/144] build release version of android samples --- tools/travis-scripts/run-script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/travis-scripts/run-script.sh b/tools/travis-scripts/run-script.sh index 7e86b00319..f9e5e0ff6b 100755 --- a/tools/travis-scripts/run-script.sh +++ b/tools/travis-scripts/run-script.sh @@ -50,7 +50,7 @@ elif [ "$PLATFORM"x = "android"x ]; then # Build all samples echo "Building all samples ..." cd $COCOS2DX_ROOT/build - ./android-build.py all + ./android-build.py -n NDK_DEBUG=0 all # Build template # echo "Building template ..." From 9fad8bfc8dcc9c7ef8503fdaed4088ecf5e85f74 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 17:02:35 +0800 Subject: [PATCH 124/144] Don't set debug flag in AndroidManifest.xml. --- samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml | 3 +-- samples/Cpp/TestCpp/proj.android/AndroidManifest.xml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml b/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml index 840bcce203..0937a1e991 100644 --- a/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml +++ b/samples/Cpp/SimpleGame/proj.android/AndroidManifest.xml @@ -8,8 +8,7 @@ + android:icon="@drawable/icon"> + android:icon="@drawable/icon"> Date: Fri, 1 Nov 2013 17:03:15 +0800 Subject: [PATCH 125/144] fix a bug when building AssetsManagerTest --- build/android-build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/android-build.py b/build/android-build.py index a9791936a5..4212076c28 100755 --- a/build/android-build.py +++ b/build/android-build.py @@ -127,7 +127,7 @@ def copy_resources(target, app_android_root): copy_files(resources_dir, assets_dir) # jsb samples should copy javascript files and resources(shared with cocos2d-html5) - if target in JSB_SAMPLES or target == "assetsmanager": + if target in JSB_SAMPLES: resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/javascript/script") copy_files(resources_dir, assets_dir) From 463ed08ffe9d0eea3119212a5c857b5d2049a659 Mon Sep 17 00:00:00 2001 From: samuele3 Date: Fri, 1 Nov 2013 17:29:09 +0800 Subject: [PATCH 126/144] issue #3037:Modify AssetsManagerTest.lua --- .../luaScript/AssetsManagerTest/AssetsManagerTest.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua index 67be1499eb..bd09f69e8a 100644 --- a/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua +++ b/samples/Lua/TestLua/Resources/luaScript/AssetsManagerTest/AssetsManagerTest.lua @@ -74,13 +74,9 @@ local function updateLayer() end local function update(sender) - progressLable:setString("") getAssetsManager():update() - - --isUpdateItemClicked = true - end local function reset(sender) From 8cf1337777be0e70bfc5fc2068c7304f105f5cda Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 17:48:10 +0800 Subject: [PATCH 127/144] Update AUTHORS [ci skip] --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index 469f299f7c..7260f3e164 100644 --- a/AUTHORS +++ b/AUTHORS @@ -634,6 +634,9 @@ Developers: superrad Clear NoSuchMethodError Exception when JniHelper fails to find methodID + Nite Luo (darkdukey) + Added Mouse Support For Desktop Platforms. + Retired Core Developers: WenSheng Yang Author of windows port, CCTextField, From eabb611093e919e89e43083be84ca2ef798c6d0d Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 17:49:01 +0800 Subject: [PATCH 128/144] Update CHANGELOG [ci skip] --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 158e288955..778f136096 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] create_project.py does not rename/replace template projects completely. [FIX] Could not set next animation in CCBAnimationCompleted callback. [FIX] The Node's anchor point was changed after being added to ScrollView. + [NEW] Added Mouse Support For Desktop Platforms. [Android] [FIX] Added EGL_RENDERABLE_TYPE to OpenGL attributes [NEW] Added Cocos2dxHelper.runOnGLThread(Runnable) again From a272bcd6ea4e2a7cd22489c13d0eea8039d887b3 Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Fri, 1 Nov 2013 10:02:54 +0000 Subject: [PATCH 129/144] [AUTO] : updating submodule reference to latest autogenerated bindings --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index dac276f47b..c2828315e5 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit dac276f47b7162898a526b385f076e5712acf12d +Subproject commit c2828315e53a4dedcdbc9e64fee388e20e49b9b4 From 32c575586916d928e60946bb2f48134d0182cbea Mon Sep 17 00:00:00 2001 From: minggo Date: Fri, 1 Nov 2013 18:24:34 +0800 Subject: [PATCH 130/144] better log --- build/android-build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/android-build.py b/build/android-build.py index 4212076c28..be4800453a 100755 --- a/build/android-build.py +++ b/build/android-build.py @@ -192,7 +192,7 @@ def build_samples(target,ndk_build_param): elif target == 'watermelonwithme': app_android_root = os.path.join(cocos_root, 'samples/JavaScript/WatermelonWithMe/proj.android') else: - print 'unknown target %s, pass it', target + print 'unknown target: %s' % target continue copy_resources(target, app_android_root) From e893ae56972550de17a4b7edb56cbecb167fd99f Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 18:27:09 +0800 Subject: [PATCH 131/144] Using namespace std; for AssetsManagerTest. --- samples/Cpp/AssetsManagerTest/Classes/AppDelegate.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/Cpp/AssetsManagerTest/Classes/AppDelegate.cpp b/samples/Cpp/AssetsManagerTest/Classes/AppDelegate.cpp index 31808c17b0..3e9381a865 100644 --- a/samples/Cpp/AssetsManagerTest/Classes/AppDelegate.cpp +++ b/samples/Cpp/AssetsManagerTest/Classes/AppDelegate.cpp @@ -18,6 +18,7 @@ USING_NS_CC; USING_NS_CC_EXT; +using namespace std; using namespace CocosDenshion; AppDelegate::AppDelegate() From b751c41498c32e279870a827b428b6207bbf4ece Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 18:27:47 +0800 Subject: [PATCH 132/144] [Android] Updating Android.mk for JSB projects. --- .../AssetsManagerTest/proj.android/jni/Android.mk | 10 ++++++++++ .../CocosDragonJS/proj.android/jni/Android.mk | 11 +++++++++++ .../CrystalCraze/proj.android/jni/Android.mk | 10 ++++++++++ .../MoonWarriors/proj.android/jni/Android.mk | 12 +++++++++++- .../WatermelonWithMe/proj.android/jni/Android.mk | 12 +++++++++++- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/samples/Cpp/AssetsManagerTest/proj.android/jni/Android.mk b/samples/Cpp/AssetsManagerTest/proj.android/jni/Android.mk index 78d938432f..28588e400a 100644 --- a/samples/Cpp/AssetsManagerTest/proj.android/jni/Android.mk +++ b/samples/Cpp/AssetsManagerTest/proj.android/jni/Android.mk @@ -12,9 +12,19 @@ LOCAL_SRC_FILES := hellocpp/main.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_chipmunk_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_localstorage_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_builder_static LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT include $(BUILD_SHARED_LIBRARY) $(call import-module,scripting/javascript/bindings) +$(call import-module,scripting/javascript/bindings/chipmunk) +$(call import-module,scripting/javascript/bindings/extension) +$(call import-module,scripting/javascript/bindings/localstorage) +$(call import-module,scripting/javascript/bindings/network) +$(call import-module,scripting/javascript/bindings/cocosbuilder) diff --git a/samples/Javascript/CocosDragonJS/proj.android/jni/Android.mk b/samples/Javascript/CocosDragonJS/proj.android/jni/Android.mk index e06290f84b..1e65b8e7a5 100644 --- a/samples/Javascript/CocosDragonJS/proj.android/jni/Android.mk +++ b/samples/Javascript/CocosDragonJS/proj.android/jni/Android.mk @@ -12,9 +12,20 @@ LOCAL_SRC_FILES := cocosdragonjs/main.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_chipmunk_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_localstorage_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_builder_static LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT include $(BUILD_SHARED_LIBRARY) $(call import-module,scripting/javascript/bindings) +$(call import-module,scripting/javascript/bindings/chipmunk) +$(call import-module,scripting/javascript/bindings/extension) +$(call import-module,scripting/javascript/bindings/localstorage) +$(call import-module,scripting/javascript/bindings/network) +$(call import-module,scripting/javascript/bindings/cocosbuilder) + diff --git a/samples/Javascript/CrystalCraze/proj.android/jni/Android.mk b/samples/Javascript/CrystalCraze/proj.android/jni/Android.mk index 3258f123af..9c8854568c 100644 --- a/samples/Javascript/CrystalCraze/proj.android/jni/Android.mk +++ b/samples/Javascript/CrystalCraze/proj.android/jni/Android.mk @@ -12,9 +12,19 @@ LOCAL_SRC_FILES := crystalcraze/main.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_chipmunk_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_localstorage_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_builder_static LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT include $(BUILD_SHARED_LIBRARY) $(call import-module,scripting/javascript/bindings) +$(call import-module,scripting/javascript/bindings/chipmunk) +$(call import-module,scripting/javascript/bindings/extension) +$(call import-module,scripting/javascript/bindings/localstorage) +$(call import-module,scripting/javascript/bindings/network) +$(call import-module,scripting/javascript/bindings/cocosbuilder) diff --git a/samples/Javascript/MoonWarriors/proj.android/jni/Android.mk b/samples/Javascript/MoonWarriors/proj.android/jni/Android.mk index c409b4790b..93726f5b70 100644 --- a/samples/Javascript/MoonWarriors/proj.android/jni/Android.mk +++ b/samples/Javascript/MoonWarriors/proj.android/jni/Android.mk @@ -12,9 +12,19 @@ LOCAL_SRC_FILES := moonwarriors/main.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_chipmunk_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_localstorage_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_builder_static LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT include $(BUILD_SHARED_LIBRARY) -$(call import-module,scripting/javascript/bindings +$(call import-module,scripting/javascript/bindings) +$(call import-module,scripting/javascript/bindings/chipmunk) +$(call import-module,scripting/javascript/bindings/extension) +$(call import-module,scripting/javascript/bindings/localstorage) +$(call import-module,scripting/javascript/bindings/network) +$(call import-module,scripting/javascript/bindings/cocosbuilder) diff --git a/samples/Javascript/WatermelonWithMe/proj.android/jni/Android.mk b/samples/Javascript/WatermelonWithMe/proj.android/jni/Android.mk index b666e13723..2d7b4097ab 100644 --- a/samples/Javascript/WatermelonWithMe/proj.android/jni/Android.mk +++ b/samples/Javascript/WatermelonWithMe/proj.android/jni/Android.mk @@ -12,9 +12,19 @@ LOCAL_SRC_FILES := watermelonwithme/main.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jsb_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_chipmunk_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_extension_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_localstorage_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_network_static +LOCAL_WHOLE_STATIC_LIBRARIES += jsb_builder_static LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT include $(BUILD_SHARED_LIBRARY) -$(call import-module,scripting/javascript/bindings +$(call import-module,scripting/javascript/bindings) +$(call import-module,scripting/javascript/bindings/chipmunk) +$(call import-module,scripting/javascript/bindings/extension) +$(call import-module,scripting/javascript/bindings/localstorage) +$(call import-module,scripting/javascript/bindings/network) +$(call import-module,scripting/javascript/bindings/cocosbuilder) From 50c426109264fc5f8f331e2965a01c79325154e0 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 20:53:51 +0800 Subject: [PATCH 133/144] closed #3104: Touch listener should be registered in Menu::initXXX and Control::init rather than onEnter. --- cocos/2d/CCMenu.cpp | 22 +++++++-------- .../GUI/CCControlExtension/CCControl.cpp | 28 ++++++------------- extensions/GUI/CCControlExtension/CCControl.h | 11 -------- 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/cocos/2d/CCMenu.cpp b/cocos/2d/CCMenu.cpp index 3b0cefbec3..6fef9d78a6 100644 --- a/cocos/2d/CCMenu.cpp +++ b/cocos/2d/CCMenu.cpp @@ -149,7 +149,6 @@ bool Menu::initWithArray(Array* pArrayOfItems) } } - // [self alignItemsVertically]; _selectedItem = NULL; _state = Menu::State::WAITING; @@ -157,6 +156,17 @@ bool Menu::initWithArray(Array* pArrayOfItems) setCascadeColorEnabled(true); setCascadeOpacityEnabled(true); + + auto touchListener = EventListenerTouchOneByOne::create(); + touchListener->setSwallowTouches(true); + + touchListener->onTouchBegan = CC_CALLBACK_2(Menu::onTouchBegan, this); + touchListener->onTouchMoved = CC_CALLBACK_2(Menu::onTouchMoved, this); + touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this); + touchListener->onTouchCancelled = CC_CALLBACK_2(Menu::onTouchCancelled, this); + + _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); + return true; } return false; @@ -184,16 +194,6 @@ void Menu::addChild(Node * child, int zOrder, int tag) void Menu::onEnter() { Layer::onEnter(); - - auto touchListener = EventListenerTouchOneByOne::create(); - touchListener->setSwallowTouches(true); - - touchListener->onTouchBegan = CC_CALLBACK_2(Menu::onTouchBegan, this); - touchListener->onTouchMoved = CC_CALLBACK_2(Menu::onTouchMoved, this); - touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this); - touchListener->onTouchCancelled = CC_CALLBACK_2(Menu::onTouchCancelled, this); - - _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); } void Menu::onExit() diff --git a/extensions/GUI/CCControlExtension/CCControl.cpp b/extensions/GUI/CCControlExtension/CCControl.cpp index 2b97094acc..13d86e629c 100644 --- a/extensions/GUI/CCControlExtension/CCControl.cpp +++ b/extensions/GUI/CCControlExtension/CCControl.cpp @@ -80,6 +80,15 @@ bool Control::init() _dispatchTable = new Dictionary(); _dispatchTable->init(); + auto dispatcher = Director::getInstance()->getEventDispatcher(); + auto touchListener = EventListenerTouchOneByOne::create(); + touchListener->onTouchBegan = CC_CALLBACK_2(Control::onTouchBegan, this); + touchListener->onTouchMoved = CC_CALLBACK_2(Control::onTouchMoved, this); + touchListener->onTouchEnded = CC_CALLBACK_2(Control::onTouchEnded, this); + touchListener->onTouchCancelled = CC_CALLBACK_2(Control::onTouchCancelled, this); + + dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); + return true; } else @@ -93,25 +102,6 @@ Control::~Control() CC_SAFE_RELEASE(_dispatchTable); } -void Control::onEnter() -{ - Layer::onEnter(); - - auto dispatcher = Director::getInstance()->getEventDispatcher(); - auto touchListener = EventListenerTouchOneByOne::create(); - touchListener->onTouchBegan = CC_CALLBACK_2(Control::onTouchBegan, this); - touchListener->onTouchMoved = CC_CALLBACK_2(Control::onTouchMoved, this); - touchListener->onTouchEnded = CC_CALLBACK_2(Control::onTouchEnded, this); - touchListener->onTouchCancelled = CC_CALLBACK_2(Control::onTouchCancelled, this); - - dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); -} - -void Control::onExit() -{ - Layer::onExit(); -} - void Control::sendActionsForControlEvents(EventType controlEvents) { // For each control events diff --git a/extensions/GUI/CCControlExtension/CCControl.h b/extensions/GUI/CCControlExtension/CCControl.h index 0a9952803b..d8644a516f 100644 --- a/extensions/GUI/CCControlExtension/CCControl.h +++ b/extensions/GUI/CCControlExtension/CCControl.h @@ -182,17 +182,6 @@ public: // Overrides virtual bool isOpacityModifyRGB() const override; virtual void setOpacityModifyRGB(bool bOpacityModifyRGB) override; - /** - * @js NA - * @lua NA - */ - virtual void onEnter() override; - /** - * @js NA - * @lua NA - */ - virtual void onExit() override; -// virtual void registerWithTouchDispatcher() override; protected: /** From 01b6e972a0ed681f2e723ce2de8f3f362e5b8bc0 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 1 Nov 2013 20:58:25 +0800 Subject: [PATCH 134/144] Update CHANGELOG [ci skip] --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 778f136096..4d46f23c70 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] create_project.py does not rename/replace template projects completely. [FIX] Could not set next animation in CCBAnimationCompleted callback. [FIX] The Node's anchor point was changed after being added to ScrollView. + [FIX] Refactored and improved EventDispatcher. [NEW] Added Mouse Support For Desktop Platforms. [Android] [FIX] Added EGL_RENDERABLE_TYPE to OpenGL attributes From 6360c407250eb60b5d6751f7a08ed8776de51ab7 Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Fri, 1 Nov 2013 13:03:20 +0000 Subject: [PATCH 135/144] [AUTO] : updating submodule reference to latest autogenerated bindings --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index c2828315e5..f399ed2207 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit c2828315e53a4dedcdbc9e64fee388e20e49b9b4 +Subproject commit f399ed22077b04a757a1b5613acf20bfdf7796b7 From ffad18a1eddb16d84bf94ebda48ffe7a2e2c1982 Mon Sep 17 00:00:00 2001 From: Michael Contento Date: Sat, 2 Nov 2013 06:15:08 +0100 Subject: [PATCH 136/144] Trigger onKeyReleased only after the key has been released --- cocos/2d/platform/linux/CCEGLView.cpp | 2 +- cocos/2d/platform/mac/CCEGLView.mm | 2 +- cocos/2d/platform/win32/CCEGLView.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/2d/platform/linux/CCEGLView.cpp b/cocos/2d/platform/linux/CCEGLView.cpp index ed1b2b6ddb..33b8796959 100644 --- a/cocos/2d/platform/linux/CCEGLView.cpp +++ b/cocos/2d/platform/linux/CCEGLView.cpp @@ -256,7 +256,7 @@ void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { - EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); + EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action || GLFW_REPEAT == action); auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->dispatchEvent(&event); } diff --git a/cocos/2d/platform/mac/CCEGLView.mm b/cocos/2d/platform/mac/CCEGLView.mm index 63bc94a43d..af3863476d 100644 --- a/cocos/2d/platform/mac/CCEGLView.mm +++ b/cocos/2d/platform/mac/CCEGLView.mm @@ -274,7 +274,7 @@ void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { - EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); + EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action || GLFW_REPEAT == action); auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->dispatchEvent(&event); } diff --git a/cocos/2d/platform/win32/CCEGLView.cpp b/cocos/2d/platform/win32/CCEGLView.cpp index b84d87c554..6b19ec5bb5 100644 --- a/cocos/2d/platform/win32/CCEGLView.cpp +++ b/cocos/2d/platform/win32/CCEGLView.cpp @@ -373,7 +373,7 @@ void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { - EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); + EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action || GLFW_REPEAT == action); auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->dispatchEvent(&event); } From 06f166f613efb7611b6d06c94925f982724d072c Mon Sep 17 00:00:00 2001 From: psi Date: Sat, 2 Nov 2013 16:03:54 +0900 Subject: [PATCH 137/144] why not search _toAddedListeners?? --- cocos/2d/CCEventDispatcher.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 14be190f68..1159bba86e 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -212,9 +212,16 @@ void EventDispatcher::removeEventListener(EventListener* listener) break; } - if (isFound) - { + if (isFound) { CC_SAFE_RELEASE(listener); + } else { + for(auto iter=_toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter) { + if ((*iter)->listener == listener) + { + _toAddedListeners.erase(iter); + break; + } + } } } From 7dc6513687c4f6992087060f7ca532a0bd4f5be6 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 21:47:00 +0800 Subject: [PATCH 138/144] Adding more tests for EventDispatcherTest. --- .../NewEventDispatcherTest.cpp | 87 ++++++++++++++++++- .../NewEventDispatcherTest.h | 9 ++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index bbc041c70b..5f06e0c9ed 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -19,7 +19,8 @@ std::function createFunctions[] = CL(CustomEventTest), CL(LabelKeyboardEventTest), CL(SpriteAccelerationEventTest), - CL(RemoveAndRetainNodeTest) + CL(RemoveAndRetainNodeTest), + CL(RemoveListenerAfterAddingTest) }; unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); @@ -665,4 +666,86 @@ std::string RemoveAndRetainNodeTest::title() std::string RemoveAndRetainNodeTest::subtitle() { return "Sprite should be removed after 5s, add to scene again after 5s"; -} \ No newline at end of file +} + +//RemoveListenerAfterAddingTest +void RemoveListenerAfterAddingTest::onEnter() +{ + EventDispatcherTestDemo::onEnter(); + + auto item1 = MenuItemFont::create("Click Me 1", [this](Object* sender){ + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{ + CCASSERT(false, "Should not come here!"); + return true; + }; + + _eventDispatcher->addEventListenerWithFixedPriority(listener, -1); + _eventDispatcher->removeEventListener(listener); + }); + + item1->setPosition(VisibleRect::center() + Point(0, 80)); + + auto addNextButton = [this](){ + auto next = MenuItemFont::create("Please Click Me To Reset!"); + next->setPosition(VisibleRect::center() + Point(0, -40)); + + auto menu = Menu::create(next, nullptr); + menu->setPosition(VisibleRect::leftBottom()); + menu->setAnchorPoint(Point::ZERO); + this->addChild(menu); + }; + + auto item2 = MenuItemFont::create("Click Me 2", [=](Object* sender){ + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{ + CCASSERT(false, "Should not come here!"); + return true; + }; + + _eventDispatcher->addEventListenerWithFixedPriority(listener, -1); + _eventDispatcher->removeEventListeners(EventListener::Type::TOUCH_ONE_BY_ONE); + + addNextButton(); + }); + + item2->setPosition(VisibleRect::center() + Point(0, 40)); + + auto item3 = MenuItemFont::create("Click Me 3", [=](Object* sender){ + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{ + CCASSERT(false, "Should not come here!"); + return true; + }; + + _eventDispatcher->addEventListenerWithFixedPriority(listener, -1); + _eventDispatcher->removeAllEventListeners(); + + addNextButton(); + }); + + item3->setPosition(VisibleRect::center()); + + auto menu = Menu::create(item1, item2, item3, nullptr); + menu->setPosition(VisibleRect::leftBottom()); + menu->setAnchorPoint(Point::ZERO); + + addChild(menu); +} + +void RemoveListenerAfterAddingTest::onExit() +{ + EventDispatcherTestDemo::onExit(); +} + +std::string RemoveListenerAfterAddingTest::title() +{ + return "RemoveListenerAfterAddingTest"; +} + +std::string RemoveListenerAfterAddingTest::subtitle() +{ + return "Should not crash!"; +} + + diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index 080e623008..529813e7b8 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -96,4 +96,13 @@ private: bool _spriteSaved; }; +class RemoveListenerAfterAddingTest : public EventDispatcherTestDemo +{ +public: + virtual void onEnter() override; + virtual void onExit() override; + virtual std::string title() override; + virtual std::string subtitle() override; +}; + #endif /* defined(__samples__NewEventDispatcherTest__) */ From 8f213420ebee44f6a871d70c042da3af7068f293 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:05:04 +0800 Subject: [PATCH 139/144] closed #3106: Update NewEventDispatcherTest.cpp. --- .../Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 5f06e0c9ed..1828dbb03d 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -687,7 +687,9 @@ void RemoveListenerAfterAddingTest::onEnter() item1->setPosition(VisibleRect::center() + Point(0, 80)); auto addNextButton = [this](){ - auto next = MenuItemFont::create("Please Click Me To Reset!"); + auto next = MenuItemFont::create("Please Click Me To Reset!", [this](Object* sender){ + this->restartCallback(nullptr); + }); next->setPosition(VisibleRect::center() + Point(0, -40)); auto menu = Menu::create(next, nullptr); From fd21e3ea38682352cb274bff902b9128b2c948ad Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:08:08 +0800 Subject: [PATCH 140/144] closed #3106: fixed: EventListeners can't be removed sometimes. --- cocos/2d/CCEventDispatcher.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index e4be089f7d..0b9f4d042d 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -442,11 +442,15 @@ void EventDispatcher::removeEventListener(EventListener* listener) break; } - if (isFound) { + if (isFound) + { CC_SAFE_RELEASE(listener); - } else { - for(auto iter=_toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter) { - if ((*iter)->listener == listener) + } + else + { + for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter) + { + if (*iter == listener) { _toAddedListeners.erase(iter); break; @@ -1048,6 +1052,18 @@ void EventDispatcher::removeEventListenersForListenerID(EventListener::ListenerI _priorityDirtyFlagMap.erase(listenerID); } } + + for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end();) + { + if ((*iter)->getListenerID() == listenerID) + { + iter = _toAddedListeners.erase(iter); + } + else + { + ++iter; + } + } } void EventDispatcher::removeEventListeners(EventListener::Type listenerType) From 2cd957a6fe24433a147a765ed0db339587fc5255 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:10:59 +0800 Subject: [PATCH 141/144] Update AUTHORS [ci skip] --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index 7260f3e164..b5e30d6e89 100644 --- a/AUTHORS +++ b/AUTHORS @@ -637,6 +637,9 @@ Developers: Nite Luo (darkdukey) Added Mouse Support For Desktop Platforms. + ledyba + Fixed a bug that EventListeners can't be removed sometimes. + Retired Core Developers: WenSheng Yang Author of windows port, CCTextField, From c0683410b36f69ba6a7a06e9a25c62019bd84b77 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:13:01 +0800 Subject: [PATCH 142/144] update CHANGELOG [ci skip] --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 4d46f23c70..69e6d443fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] The Node's anchor point was changed after being added to ScrollView. [FIX] Refactored and improved EventDispatcher. [NEW] Added Mouse Support For Desktop Platforms. + [FIX] EventListeners can't be removed sometimes. [Android] [FIX] Added EGL_RENDERABLE_TYPE to OpenGL attributes [NEW] Added Cocos2dxHelper.runOnGLThread(Runnable) again From 23faae22eec8566dfc39df364381bd83121b99f5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:16:07 +0800 Subject: [PATCH 143/144] UPDATE CHANGELOG[ci skip] --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 69e6d443fb..c8e6b9d403 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,8 @@ cocos2d-x-3.0alpha1 @??? 2013 [FIX] Removed unused CCLOG() from GL initialization [iOS] [FIX] Can't click the area that outside of keyboard to close keyboard when using EditBox. +[Desktop] + [FIX] Trigger onKeyReleased only after the key has been released. [Javascript binding] [FIX] Fixed a memory leak in ScriptingCore::runScript() [FIX] sys.localStorage.getItem() does not support non-ascii string. From f3be8ac6a68d42d4e429459a3dc3c727807a8ced Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:16:39 +0800 Subject: [PATCH 144/144] Update AUTHORS [ci skip] --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b5e30d6e89..41e87fa132 100644 --- a/AUTHORS +++ b/AUTHORS @@ -593,6 +593,7 @@ Developers: [Android] re-introduce Cocos2dxHelper.runOnGLThread(Runnable) [Android] added EGL_RENDERABLE_TYPE to OpenGL attributes Android: add xlargeScreens="true" to supports-screens + Trigger onKeyReleased only after the key has been released. bmanGH Use gl caching functions in TexturePVR::createGLTexture()