mirror of https://github.com/axmolengine/axmol.git
Merge remote branch 'upstream/gles20' into gles20
This commit is contained in:
commit
a1155f52e6
3
AUTHORS
3
AUTHORS
|
@ -169,6 +169,9 @@ Developers:
|
|||
Igor Zavorotkin (ivzave)
|
||||
Adding lua support for linux platform.
|
||||
|
||||
Jozef Prídavok (jpridavok)
|
||||
Adding CCEditBox implementation for Mac OSX.
|
||||
|
||||
Retired Core Developers:
|
||||
WenSheng Yang
|
||||
Author of windows port, CCTextField,
|
||||
|
|
|
@ -55,7 +55,7 @@ CCRenderTexture::CCRenderTexture()
|
|||
, m_ePixelFormat(kCCTexture2DPixelFormat_RGBA8888)
|
||||
, m_uClearFlags(0)
|
||||
, m_sClearColor(ccc4f(0,0,0,0))
|
||||
, m_fDlearDepth(0.0f)
|
||||
, m_fClearDepth(0.0f)
|
||||
, m_nClearStencil(0)
|
||||
, m_bAutoDraw(false)
|
||||
{
|
||||
|
@ -175,12 +175,12 @@ void CCRenderTexture::setClearColor(const ccColor4F &clearColor)
|
|||
|
||||
float CCRenderTexture::getClearDepth() const
|
||||
{
|
||||
return m_fDlearDepth;
|
||||
return m_fClearDepth;
|
||||
}
|
||||
|
||||
void CCRenderTexture::setClearDepth(float fClearDepth)
|
||||
{
|
||||
m_fDlearDepth = fClearDepth;
|
||||
m_fClearDepth = fClearDepth;
|
||||
}
|
||||
|
||||
int CCRenderTexture::getClearStencil() const
|
||||
|
@ -563,7 +563,7 @@ void CCRenderTexture::draw()
|
|||
if (m_uClearFlags & GL_DEPTH_BUFFER_BIT)
|
||||
{
|
||||
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &oldDepthClearValue);
|
||||
glClearDepth(m_fDlearDepth);
|
||||
glClearDepth(m_fClearDepth);
|
||||
}
|
||||
|
||||
if (m_uClearFlags & GL_STENCIL_BUFFER_BIT)
|
||||
|
|
|
@ -172,7 +172,7 @@ protected:
|
|||
// code for "auto" update
|
||||
GLbitfield m_uClearFlags;
|
||||
ccColor4F m_sClearColor;
|
||||
GLclampf m_fDlearDepth;
|
||||
GLclampf m_fClearDepth;
|
||||
GLint m_nClearStencil;
|
||||
bool m_bAutoDraw;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2011 cocos2d-x.org
|
||||
Copyright (c) 2010-2013 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
@ -26,6 +26,7 @@ package org.cocos2dx.lib;
|
|||
import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -44,6 +45,11 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
|
||||
private Cocos2dxGLSurfaceView mGLSurfaceView;
|
||||
private Cocos2dxHandler mHandler;
|
||||
private static Context sContext = null;
|
||||
|
||||
public static Context getContext() {
|
||||
return sContext;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Constructors
|
||||
|
@ -52,7 +58,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
sContext = this;
|
||||
this.mHandler = new Cocos2dxHandler(this);
|
||||
|
||||
this.init();
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
package org.cocos2dx.lib;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
public class Cocos2dxLocalStorage {
|
||||
|
||||
private static final String TAG = "Cocos2dxLocalStorage";
|
||||
|
||||
private static String DATABASE_NAME = "jsb.sqlite";
|
||||
private static String TABLE_NAME = "data";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
private static DBOpenHelper mDatabaseOpenHelper = null;
|
||||
private static SQLiteDatabase mDatabase = null;
|
||||
/**
|
||||
* Constructor
|
||||
* @param context The Context within which to work, used to create the DB
|
||||
* @return
|
||||
*/
|
||||
public static boolean init(String dbName, String tableName) {
|
||||
if (Cocos2dxActivity.getContext() != null) {
|
||||
DATABASE_NAME = dbName;
|
||||
TABLE_NAME = tableName;
|
||||
mDatabaseOpenHelper = new DBOpenHelper(Cocos2dxActivity.getContext());
|
||||
mDatabase = mDatabaseOpenHelper.getWritableDatabase();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void destory() {
|
||||
if (mDatabase != null) {
|
||||
mDatabase.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setItem(String key, String value) {
|
||||
try {
|
||||
String sql = "replace into "+TABLE_NAME+"(key,value)values(?,?)";
|
||||
mDatabase.execSQL(sql, new Object[] { key, value });
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getItem(String key) {
|
||||
String ret = null;
|
||||
try {
|
||||
String sql = "select value from "+TABLE_NAME+" where key=?";
|
||||
Cursor c = mDatabase.rawQuery(sql, new String[]{key});
|
||||
while (c.moveToNext()) {
|
||||
// only return the first value
|
||||
if (ret != null)
|
||||
{
|
||||
Log.e(TAG, "The key contains more than one value.");
|
||||
break;
|
||||
}
|
||||
ret = c.getString(c.getColumnIndex("value"));
|
||||
}
|
||||
c.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret == null ? "" : ret;
|
||||
}
|
||||
|
||||
public static void removeItem(String key) {
|
||||
try {
|
||||
String sql = "delete from "+TABLE_NAME+" where key=?";
|
||||
mDatabase.execSQL(sql, new Object[] {key});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This creates/opens the database.
|
||||
*/
|
||||
private static class DBOpenHelper extends SQLiteOpenHelper {
|
||||
|
||||
DBOpenHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE IF NOT EXISTS "+TABLE_NAME+"(key TEXT PRIMARY KEY,value TEXT);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion + ", which will destroy all old data");
|
||||
//db.execSQL("DROP TABLE IF EXISTS " + VIRTUAL_TABLE);
|
||||
//onCreate(db);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,8 @@ GUI/CCEditBox/CCEditBox.cpp \
|
|||
GUI/CCEditBox/CCEditBoxImplAndroid.cpp \
|
||||
network/HttpClient.cpp \
|
||||
physics_nodes/CCPhysicsDebugNode.cpp \
|
||||
physics_nodes/CCPhysicsSprite.cpp
|
||||
physics_nodes/CCPhysicsSprite.cpp \
|
||||
LocalStorage/LocalStorageAndroid.cpp
|
||||
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_curl_static
|
||||
|
@ -60,7 +61,8 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
|
|||
$(LOCAL_PATH)/CCBReader \
|
||||
$(LOCAL_PATH)/GUI/CCControlExtension \
|
||||
$(LOCAL_PATH)/GUI/CCScrollView \
|
||||
$(LOCAL_PATH)/network
|
||||
$(LOCAL_PATH)/network \
|
||||
$(LOCAL_PATH)/LocalStorage
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2012 Jozef Pridavok
|
||||
|
||||
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 __CCEditBoxIMPLMAC_H__
|
||||
#define __CCEditBoxIMPLMAC_H__
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "cocos2d.h"
|
||||
#include "ExtensionMacros.h"
|
||||
#include "CCEditBoxImpl.h"
|
||||
|
||||
@interface CustomNSTextField : NSTextField
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface EditBoxImplMac : NSObject <NSTextFieldDelegate>
|
||||
{
|
||||
CustomNSTextField* textField_;
|
||||
void* editBox_;
|
||||
BOOL editState_;
|
||||
}
|
||||
|
||||
@property(nonatomic, retain) NSTextField* textField;
|
||||
@property(nonatomic, readonly, getter = isEditState) BOOL editState;
|
||||
@property(nonatomic, assign) void* editBox;
|
||||
|
||||
-(id) initWithFrame: (NSRect) frameRect editBox: (void*) editBox;
|
||||
-(void) doAnimationWhenKeyboardMoveWithDuration:(float)duration distance:(float)distance;
|
||||
-(void) setPosition:(NSPoint) pos;
|
||||
-(void) setContentSize:(NSSize) size;
|
||||
-(void) visit;
|
||||
-(void) openKeyboard;
|
||||
-(void) closeKeyboard;
|
||||
|
||||
@end
|
||||
|
||||
NS_CC_EXT_BEGIN
|
||||
|
||||
class CCEditBox;
|
||||
|
||||
class CCEditBoxImplMac : public CCEditBoxImpl
|
||||
{
|
||||
public:
|
||||
CCEditBoxImplMac(CCEditBox* pEditText);
|
||||
virtual ~CCEditBoxImplMac();
|
||||
|
||||
virtual bool initWithSize(const CCSize& size);
|
||||
virtual void setFontColor(const ccColor3B& color);
|
||||
virtual void setPlaceholderFontColor(const ccColor3B& color);
|
||||
virtual void setInputMode(EditBoxInputMode inputMode);
|
||||
virtual void setInputFlag(EditBoxInputFlag inputFlag);
|
||||
virtual void setMaxLength(int maxLength);
|
||||
virtual int getMaxLength();
|
||||
virtual void setReturnType(KeyboardReturnType returnType);
|
||||
virtual bool isEditing();
|
||||
|
||||
virtual void setText(const char* pText);
|
||||
virtual const char* getText(void);
|
||||
virtual void setPlaceHolder(const char* pText);
|
||||
virtual void setPosition(const CCPoint& pos);
|
||||
virtual void setContentSize(const CCSize& size);
|
||||
virtual void visit(void);
|
||||
virtual void doAnimationWhenKeyboardMove(float duration, float distance);
|
||||
virtual void openKeyboard();
|
||||
virtual void closeKeyboard();
|
||||
|
||||
private:
|
||||
CCSize m_tContentSize;
|
||||
void* m_pSysEdit;
|
||||
int m_nMaxTextLength;
|
||||
bool m_bInRetinaMode;
|
||||
};
|
||||
|
||||
|
||||
NS_CC_EXT_END
|
||||
|
||||
#endif /* __CCEditBoxIMPLMAC_H__ */
|
||||
|
|
@ -0,0 +1,354 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2012 Jozef Pridavok
|
||||
|
||||
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 "CCEditBoxImplMac.h"
|
||||
#include "CCEditBox.h"
|
||||
#import "EAGLView.h"
|
||||
|
||||
#define getEditBoxImplMac() ((cocos2d::extension::CCEditBoxImplMac*)editBox_)
|
||||
|
||||
@implementation CustomNSTextField
|
||||
|
||||
- (CGRect)textRectForBounds:(CGRect)bounds {
|
||||
float padding = 5.0f;
|
||||
return CGRectMake(bounds.origin.x + padding, bounds.origin.y + padding,
|
||||
bounds.size.width - padding*2, bounds.size.height - padding*2);
|
||||
}
|
||||
- (CGRect)editingRectForBounds:(CGRect)bounds {
|
||||
return [self textRectForBounds:bounds];
|
||||
}
|
||||
|
||||
- (void)setup {
|
||||
[self setBordered:NO];
|
||||
[self setHidden:NO];
|
||||
[self setWantsLayer:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation EditBoxImplMac
|
||||
|
||||
@synthesize textField = textField_;
|
||||
@synthesize editState = editState_;
|
||||
@synthesize editBox = editBox_;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[textField_ resignFirstResponder];
|
||||
[textField_ removeFromSuperview];
|
||||
self.textField = NULL;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(id) initWithFrame: (NSRect) frameRect editBox: (void*) editBox
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
do
|
||||
{
|
||||
if (self == nil) break;
|
||||
editState_ = NO;
|
||||
self.textField = [[[CustomNSTextField alloc] initWithFrame: frameRect] autorelease];
|
||||
if (!textField_) break;
|
||||
[textField_ setTextColor:[NSColor whiteColor]];
|
||||
textField_.font = [NSFont systemFontOfSize:frameRect.size.height*2/3]; //TODO need to delete hard code here.
|
||||
textField_.backgroundColor = [NSColor clearColor];
|
||||
[textField_ setup];
|
||||
textField_.delegate = self;
|
||||
[textField_ setDelegate:self];
|
||||
self.editBox = editBox;
|
||||
|
||||
[[EAGLView sharedEGLView] addSubview:textField_];
|
||||
|
||||
return self;
|
||||
}while(0);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(void) doAnimationWhenKeyboardMoveWithDuration:(float)duration distance:(float)distance
|
||||
{
|
||||
id eglView = [EAGLView sharedEGLView];
|
||||
[eglView doAnimationWhenKeyboardMoveWithDuration:duration distance:distance];
|
||||
}
|
||||
|
||||
-(void) setPosition:(NSPoint) pos
|
||||
{
|
||||
NSRect frame = [textField_ frame];
|
||||
frame.origin = pos;
|
||||
[textField_ setFrame:frame];
|
||||
}
|
||||
|
||||
-(void) setContentSize:(NSSize) size
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
-(void) visit
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
-(void) openKeyboard
|
||||
{
|
||||
[textField_ becomeFirstResponder];
|
||||
}
|
||||
|
||||
-(void) closeKeyboard
|
||||
{
|
||||
[textField_ resignFirstResponder];
|
||||
[textField_ removeFromSuperview];
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(NSTextField *)sender
|
||||
{
|
||||
if (sender == textField_) {
|
||||
[sender resignFirstResponder];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)animationSelector
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldBeginEditing:(NSTextField *)sender // return NO to disallow editing.
|
||||
{
|
||||
editState_ = YES;
|
||||
cocos2d::extension::CCEditBoxDelegate* pDelegate = getEditBoxImplMac()->getDelegate();
|
||||
if (pDelegate != NULL)
|
||||
{
|
||||
pDelegate->editBoxEditingDidBegin(getEditBoxImplMac()->getCCEditBox());
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldEndEditing:(NSTextField *)sender
|
||||
{
|
||||
editState_ = NO;
|
||||
cocos2d::extension::CCEditBoxDelegate* pDelegate = getEditBoxImplMac()->getDelegate();
|
||||
if (pDelegate != NULL)
|
||||
{
|
||||
pDelegate->editBoxEditingDidEnd(getEditBoxImplMac()->getCCEditBox());
|
||||
pDelegate->editBoxReturn(getEditBoxImplMac()->getCCEditBox());
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate method called before the text has been changed.
|
||||
* @param textField The text field containing the text.
|
||||
* @param range The range of characters to be replaced.
|
||||
* @param string The replacement string.
|
||||
* @return YES if the specified text range should be replaced; otherwise, NO to keep the old text.
|
||||
*/
|
||||
- (BOOL)textField:(NSTextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
||||
{
|
||||
if (getEditBoxImplMac()->getMaxLength() < 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
NSUInteger oldLength = [[textField stringValue] length];
|
||||
NSUInteger replacementLength = [string length];
|
||||
NSUInteger rangeLength = range.length;
|
||||
|
||||
NSUInteger newLength = oldLength - rangeLength + replacementLength;
|
||||
|
||||
return newLength <= getEditBoxImplMac()->getMaxLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called each time when the text field's text has changed.
|
||||
*/
|
||||
- (void)controlTextDidChange:(NSNotification *)notification
|
||||
{
|
||||
cocos2d::extension::CCEditBoxDelegate* pDelegate = getEditBoxImplMac()->getDelegate();
|
||||
if (pDelegate != NULL)
|
||||
{
|
||||
pDelegate->editBoxTextChanged(getEditBoxImplMac()->getCCEditBox(), getEditBoxImplMac()->getText());
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_CC_EXT_BEGIN
|
||||
|
||||
CCEditBoxImpl* __createSystemEditBox(CCEditBox* pEditBox)
|
||||
{
|
||||
return new CCEditBoxImplMac(pEditBox);
|
||||
}
|
||||
|
||||
#define GET_IMPL ((EditBoxImplMac*)m_pSysEdit)
|
||||
|
||||
CCEditBoxImplMac::CCEditBoxImplMac(CCEditBox* pEditText)
|
||||
: CCEditBoxImpl(pEditText), m_pSysEdit(NULL), m_nMaxTextLength(-1)
|
||||
{
|
||||
//! TODO: Retina on Mac
|
||||
//! m_bInRetinaMode = [[EAGLView sharedEGLView] contentScaleFactor] == 2.0f ? true : false;
|
||||
m_bInRetinaMode = false;
|
||||
}
|
||||
|
||||
CCEditBoxImplMac::~CCEditBoxImplMac()
|
||||
{
|
||||
[GET_IMPL release];
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::doAnimationWhenKeyboardMove(float duration, float distance)
|
||||
{
|
||||
if ([GET_IMPL isEditState] || distance < 0.0f)
|
||||
[GET_IMPL doAnimationWhenKeyboardMoveWithDuration:duration distance:distance];
|
||||
}
|
||||
|
||||
bool CCEditBoxImplMac::initWithSize(const CCSize& size)
|
||||
{
|
||||
CCEGLViewProtocol* eglView = CCEGLView::sharedOpenGLView();
|
||||
|
||||
NSRect rect = NSMakeRect(0, 0, size.width * eglView->getScaleX(),size.height * eglView->getScaleY());
|
||||
|
||||
if (m_bInRetinaMode) {
|
||||
rect.size.width /= 2.0f;
|
||||
rect.size.height /= 2.0f;
|
||||
}
|
||||
|
||||
m_pSysEdit = [[EditBoxImplMac alloc] initWithFrame:rect editBox:this];
|
||||
|
||||
if (!m_pSysEdit)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setFontColor(const ccColor3B& color)
|
||||
{
|
||||
GET_IMPL.textField.textColor = [NSColor colorWithCalibratedRed:color.r / 255.0f green:color.g / 255.0f blue:color.b / 255.0f alpha:1.0f];
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setPlaceholderFontColor(const ccColor3B& color)
|
||||
{
|
||||
// TODO need to be implemented.
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setInputMode(EditBoxInputMode inputMode)
|
||||
{
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setMaxLength(int maxLength)
|
||||
{
|
||||
m_nMaxTextLength = maxLength;
|
||||
}
|
||||
|
||||
int CCEditBoxImplMac::getMaxLength()
|
||||
{
|
||||
return m_nMaxTextLength;
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setInputFlag(EditBoxInputFlag inputFlag)
|
||||
{
|
||||
// TODO: NSSecureTextField
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setReturnType(KeyboardReturnType returnType)
|
||||
{
|
||||
}
|
||||
|
||||
bool CCEditBoxImplMac::isEditing()
|
||||
{
|
||||
return [GET_IMPL isEditState] ? true : false;
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setText(const char* pText)
|
||||
{
|
||||
GET_IMPL.textField.stringValue = [NSString stringWithUTF8String:pText];
|
||||
}
|
||||
|
||||
const char* CCEditBoxImplMac::getText(void)
|
||||
{
|
||||
return [GET_IMPL.textField.stringValue UTF8String];
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setPlaceHolder(const char* pText)
|
||||
{
|
||||
[[GET_IMPL.textField cell] setPlaceholderString:[NSString stringWithUTF8String:pText]];
|
||||
}
|
||||
|
||||
static NSPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord, bool bInRetinaMode)
|
||||
{
|
||||
CCEGLViewProtocol* eglView = CCEGLView::sharedOpenGLView();
|
||||
//float viewH = (float)[[EAGLView sharedEGLView] getHeight];
|
||||
|
||||
CCPoint visiblePos = ccp(designCoord.x * eglView->getScaleX(), designCoord.y * eglView->getScaleY());
|
||||
CCPoint screenGLPos = ccpAdd(visiblePos, eglView->getViewPortRect().origin);
|
||||
|
||||
NSPoint screenPos = NSMakePoint(screenGLPos.x, /*viewH -*/ screenGLPos.y);
|
||||
|
||||
if (bInRetinaMode) {
|
||||
screenPos.x = screenPos.x / 2.0f;
|
||||
screenPos.y = screenPos.y / 2.0f;
|
||||
}
|
||||
|
||||
CCLOG("[EditBox] pos x = %f, y = %f", screenGLPos.x, screenGLPos.y);
|
||||
return screenPos;
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setPosition(const CCPoint& newPos)
|
||||
{
|
||||
CCPoint pos = newPos;
|
||||
|
||||
//CCPoint pos = m_pEditBox->convertToWorldSpace(newPos);
|
||||
|
||||
//CCPoint worldPoint = m_pEditBox->convertToWorldSpace(newPos);
|
||||
//CCPoint pos = CCDirector::sharedDirector()->convertToUI(worldPoint);
|
||||
|
||||
//TODO should consider anchor point, the default value is (0.5, 0,5)
|
||||
NSRect frame = [GET_IMPL.textField frame];
|
||||
CGFloat height = frame.size.height;
|
||||
[GET_IMPL setPosition:convertDesignCoordToScreenCoord(ccp(pos.x-m_tContentSize.width/2, pos.y+m_tContentSize.height/2-height), m_bInRetinaMode)];
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::setContentSize(const CCSize& size)
|
||||
{
|
||||
m_tContentSize = size;
|
||||
CCLOG("[Edit text] content size = (%f, %f)", size.width, size.height);
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::visit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::openKeyboard()
|
||||
{
|
||||
[GET_IMPL openKeyboard];
|
||||
}
|
||||
|
||||
void CCEditBoxImplMac::closeKeyboard()
|
||||
{
|
||||
[GET_IMPL closeKeyboard];
|
||||
}
|
||||
|
||||
NS_CC_EXT_END
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2012 - Zynga Inc.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Local Storage support for the JS Bindings for iOS.
|
||||
Works on cocos2d-iphone and cocos2d-x.
|
||||
*/
|
||||
|
||||
#include "cocos2d.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int _initialized = 0;
|
||||
static sqlite3 *_db;
|
||||
static sqlite3_stmt *_stmt_select;
|
||||
static sqlite3_stmt *_stmt_remove;
|
||||
static sqlite3_stmt *_stmt_update;
|
||||
|
||||
|
||||
static void localStorageLazyInit();
|
||||
static void localStorageCreateTable();
|
||||
|
||||
static void localStorageCreateTable()
|
||||
{
|
||||
const char *sql_createtable = "CREATE TABLE IF NOT EXISTS data(key TEXT PRIMARY KEY,value TEXT);";
|
||||
sqlite3_stmt *stmt;
|
||||
int ok=sqlite3_prepare_v2(_db, sql_createtable, -1, &stmt, NULL);
|
||||
ok |= sqlite3_step(stmt);
|
||||
ok |= sqlite3_finalize(stmt);
|
||||
|
||||
if( ok != SQLITE_OK && ok != SQLITE_DONE)
|
||||
printf("Error in CREATE TABLE\n");
|
||||
}
|
||||
|
||||
void localStorageInit( const char *fullpath)
|
||||
{
|
||||
if( ! _initialized ) {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (!fullpath)
|
||||
ret = sqlite3_open(":memory:",&_db);
|
||||
else
|
||||
ret = sqlite3_open(fullpath, &_db);
|
||||
|
||||
localStorageCreateTable();
|
||||
|
||||
// SELECT
|
||||
const char *sql_select = "SELECT value FROM data WHERE key=?;";
|
||||
ret |= sqlite3_prepare_v2(_db, sql_select, -1, &_stmt_select, NULL);
|
||||
|
||||
// REPLACE
|
||||
const char *sql_update = "REPLACE INTO data (key, value) VALUES (?,?);";
|
||||
ret |= sqlite3_prepare_v2(_db, sql_update, -1, &_stmt_update, NULL);
|
||||
|
||||
// DELETE
|
||||
const char *sql_remove = "DELETE FROM data WHERE key=?;";
|
||||
ret |= sqlite3_prepare_v2(_db, sql_remove, -1, &_stmt_remove, NULL);
|
||||
|
||||
if( ret != SQLITE_OK ) {
|
||||
printf("Error initializing DB\n");
|
||||
// report error
|
||||
}
|
||||
|
||||
_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void localStorageFree()
|
||||
{
|
||||
if( _initialized ) {
|
||||
sqlite3_finalize(_stmt_select);
|
||||
sqlite3_finalize(_stmt_remove);
|
||||
sqlite3_finalize(_stmt_update);
|
||||
|
||||
sqlite3_close(_db);
|
||||
|
||||
_initialized = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** sets an item in the LS */
|
||||
void localStorageSetItem( const char *key, const char *value)
|
||||
{
|
||||
assert( _initialized );
|
||||
|
||||
int ok = sqlite3_bind_text(_stmt_update, 1, key, -1, SQLITE_TRANSIENT);
|
||||
ok |= sqlite3_bind_text(_stmt_update, 2, value, -1, SQLITE_TRANSIENT);
|
||||
|
||||
ok |= sqlite3_step(_stmt_update);
|
||||
|
||||
ok |= sqlite3_reset(_stmt_update);
|
||||
|
||||
if( ok != SQLITE_OK && ok != SQLITE_DONE)
|
||||
printf("Error in localStorage.setItem()\n");
|
||||
}
|
||||
|
||||
/** gets an item from the LS */
|
||||
const char* localStorageGetItem( const char *key )
|
||||
{
|
||||
assert( _initialized );
|
||||
|
||||
int ok = sqlite3_reset(_stmt_select);
|
||||
|
||||
ok |= sqlite3_bind_text(_stmt_select, 1, key, -1, SQLITE_TRANSIENT);
|
||||
ok |= sqlite3_step(_stmt_select);
|
||||
const unsigned char *ret = sqlite3_column_text(_stmt_select, 0);
|
||||
|
||||
|
||||
if( ok != SQLITE_OK && ok != SQLITE_DONE && ok != SQLITE_ROW)
|
||||
printf("Error in localStorage.getItem()\n");
|
||||
|
||||
return (const char*)ret;
|
||||
}
|
||||
|
||||
/** removes an item from the LS */
|
||||
void localStorageRemoveItem( const char *key )
|
||||
{
|
||||
assert( _initialized );
|
||||
|
||||
int ok = sqlite3_bind_text(_stmt_remove, 1, key, -1, SQLITE_TRANSIENT);
|
||||
|
||||
ok |= sqlite3_step(_stmt_remove);
|
||||
|
||||
ok |= sqlite3_reset(_stmt_remove);
|
||||
|
||||
if( ok != SQLITE_OK && ok != SQLITE_DONE)
|
||||
printf("Error in localStorage.removeItem()\n");
|
||||
}
|
||||
|
||||
#endif // #if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID)
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2012 - Zynga Inc.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Local Storage support for the JS Bindings for iOS.
|
||||
Works on cocos2d-iphone and cocos2d-x.
|
||||
*/
|
||||
|
||||
#ifndef __JSB_LOCALSTORAGE_H
|
||||
#define __JSB_LOCALSTORAGE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** Initializes the database. If path is null, it will create an in-memory DB */
|
||||
void localStorageInit( const char *fullpath);
|
||||
|
||||
/** Frees the allocated resources */
|
||||
void localStorageFree();
|
||||
|
||||
/** sets an item in the LS */
|
||||
void localStorageSetItem( const char *key, const char *value);
|
||||
|
||||
/** gets an item from the LS */
|
||||
const char* localStorageGetItem( const char *key );
|
||||
|
||||
/** removes an item from the LS */
|
||||
void localStorageRemoveItem( const char *key );
|
||||
|
||||
#endif // __JSB_LOCALSTORAGE_H
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2012 - Zynga Inc.
|
||||
Copyright (c) 2013 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.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Local Storage support for the JS Bindings for iOS.
|
||||
Works on cocos2d-iphone and cocos2d-x.
|
||||
*/
|
||||
|
||||
#include "cocos2d.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include "jni.h"
|
||||
#include "jni/JniHelper.h"
|
||||
|
||||
USING_NS_CC;
|
||||
static int _initialized = 0;
|
||||
|
||||
static void splitFilename (std::string& str)
|
||||
{
|
||||
size_t found = 0;
|
||||
found=str.find_last_of("/\\");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
str = str.substr(found+1);
|
||||
}
|
||||
}
|
||||
|
||||
void localStorageInit( const char *fullpath)
|
||||
{
|
||||
if (fullpath == NULL || strlen(fullpath) == 0) return;
|
||||
|
||||
if( ! _initialized ) {
|
||||
JniMethodInfo t;
|
||||
|
||||
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "init", "(Ljava/lang/String;Ljava/lang/String;)Z")) {
|
||||
std::string strDBFilename = fullpath;
|
||||
splitFilename(strDBFilename);
|
||||
jstring jdbName = t.env->NewStringUTF(strDBFilename.c_str());
|
||||
jstring jtableName = t.env->NewStringUTF("data");
|
||||
jboolean ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID, jdbName, jtableName);
|
||||
t.env->DeleteLocalRef(jdbName);
|
||||
t.env->DeleteLocalRef(jtableName);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
if (ret) {
|
||||
_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void localStorageFree()
|
||||
{
|
||||
if( _initialized ) {
|
||||
|
||||
JniMethodInfo t;
|
||||
|
||||
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "destory", "()V"))
|
||||
{
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
}
|
||||
|
||||
_initialized = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** sets an item in the LS */
|
||||
void localStorageSetItem( const char *key, const char *value)
|
||||
{
|
||||
assert( _initialized );
|
||||
|
||||
JniMethodInfo t;
|
||||
|
||||
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "setItem", "(Ljava/lang/String;Ljava/lang/String;)V")) {
|
||||
jstring jkey = t.env->NewStringUTF(key);
|
||||
jstring jvalue = t.env->NewStringUTF(value);
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID, jkey, jvalue);
|
||||
t.env->DeleteLocalRef(jkey);
|
||||
t.env->DeleteLocalRef(jvalue);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
}
|
||||
}
|
||||
|
||||
/** gets an item from the LS */
|
||||
const char* localStorageGetItem( const char *key )
|
||||
{
|
||||
assert( _initialized );
|
||||
JniMethodInfo t;
|
||||
CCString* pStr = NULL;
|
||||
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "getItem", "(Ljava/lang/String;)Ljava/lang/String;")) {
|
||||
jstring jkey = t.env->NewStringUTF(key);
|
||||
jstring ret = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, jkey);
|
||||
pStr = CCString::create(JniHelper::jstring2string(ret));
|
||||
t.env->DeleteLocalRef(ret);
|
||||
t.env->DeleteLocalRef(jkey);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
}
|
||||
return pStr ? pStr->getCString() : NULL;
|
||||
}
|
||||
|
||||
/** removes an item from the LS */
|
||||
void localStorageRemoveItem( const char *key )
|
||||
{
|
||||
assert( _initialized );
|
||||
JniMethodInfo t;
|
||||
|
||||
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "removeItem", "(Ljava/lang/String;)V")) {
|
||||
jstring jkey = t.env->NewStringUTF(key);
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID, jkey);
|
||||
t.env->DeleteLocalRef(jkey);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
|
@ -52,5 +52,6 @@
|
|||
#include "physics_nodes/CCPhysicsSprite.h"
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __COCOS2D_EXT_H__ */
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external\sqlite3\include;$(ProjectDir)..\..\external;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_LIB;COCOS2D_DEBUG=1;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
|
@ -79,7 +79,7 @@
|
|||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external\sqlite3\include;$(ProjectDir)..\..\external;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_LIB;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
|
@ -131,6 +131,7 @@
|
|||
<ClCompile Include="..\GUI\CCScrollView\CCSorting.cpp" />
|
||||
<ClCompile Include="..\GUI\CCScrollView\CCTableView.cpp" />
|
||||
<ClCompile Include="..\GUI\CCScrollView\CCTableViewCell.cpp" />
|
||||
<ClCompile Include="..\LocalStorage\LocalStorage.cpp" />
|
||||
<ClCompile Include="..\network\HttpClient.cpp" />
|
||||
<ClCompile Include="..\physics_nodes\CCPhysicsDebugNode.cpp" />
|
||||
<ClCompile Include="..\physics_nodes\CCPhysicsSprite.cpp" />
|
||||
|
@ -183,6 +184,7 @@
|
|||
<ClInclude Include="..\GUI\CCScrollView\CCSorting.h" />
|
||||
<ClInclude Include="..\GUI\CCScrollView\CCTableView.h" />
|
||||
<ClInclude Include="..\GUI\CCScrollView\CCTableViewCell.h" />
|
||||
<ClInclude Include="..\LocalStorage\LocalStorage.h" />
|
||||
<ClInclude Include="..\network\HttpClient.h" />
|
||||
<ClInclude Include="..\network\HttpRequest.h" />
|
||||
<ClInclude Include="..\network\HttpResponse.h" />
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
<Filter Include="physics_nodes">
|
||||
<UniqueIdentifier>{d5806151-7ae1-4fef-af5a-2fa1d1c7377b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="LocalStorage">
|
||||
<UniqueIdentifier>{4da8061d-80f3-45fd-aa7e-2c0a96701b79}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\GUI\CCScrollView\CCScrollView.cpp">
|
||||
|
@ -150,6 +153,9 @@
|
|||
<ClCompile Include="..\physics_nodes\CCPhysicsSprite.cpp">
|
||||
<Filter>physics_nodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\LocalStorage\LocalStorage.cpp">
|
||||
<Filter>LocalStorage</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\GUI\CCScrollView\CCScrollView.h">
|
||||
|
@ -304,5 +310,8 @@
|
|||
<ClInclude Include="..\physics_nodes\CCPhysicsSprite.h">
|
||||
<Filter>physics_nodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\LocalStorage\LocalStorage.h">
|
||||
<Filter>LocalStorage</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1 @@
|
|||
d5fbb9a1bda9fdaefc9ff04c2c63ab8b02c93709
|
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
** 2006 June 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the SQLite interface for use by
|
||||
** shared libraries that want to be imported as extensions into
|
||||
** an SQLite instance. Shared libraries that intend to be loaded
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef _SQLITE3EXT_H_
|
||||
#define _SQLITE3EXT_H_
|
||||
#include "sqlite3.h"
|
||||
|
||||
typedef struct sqlite3_api_routines sqlite3_api_routines;
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
**
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each others' shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
void * (*aggregate_context)(sqlite3_context*,int nBytes);
|
||||
int (*aggregate_count)(sqlite3_context*);
|
||||
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
|
||||
int (*bind_double)(sqlite3_stmt*,int,double);
|
||||
int (*bind_int)(sqlite3_stmt*,int,int);
|
||||
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
|
||||
int (*bind_null)(sqlite3_stmt*,int);
|
||||
int (*bind_parameter_count)(sqlite3_stmt*);
|
||||
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
|
||||
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
|
||||
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
|
||||
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
|
||||
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
|
||||
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
|
||||
int (*busy_timeout)(sqlite3*,int ms);
|
||||
int (*changes)(sqlite3*);
|
||||
int (*close)(sqlite3*);
|
||||
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const char*));
|
||||
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const void*));
|
||||
const void * (*column_blob)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_count)(sqlite3_stmt*pStmt);
|
||||
const char * (*column_database_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_database_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_decltype)(sqlite3_stmt*,int i);
|
||||
const void * (*column_decltype16)(sqlite3_stmt*,int);
|
||||
double (*column_double)(sqlite3_stmt*,int iCol);
|
||||
int (*column_int)(sqlite3_stmt*,int iCol);
|
||||
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
|
||||
const char * (*column_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_origin_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_origin_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_table_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_table_name16)(sqlite3_stmt*,int);
|
||||
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
|
||||
const void * (*column_text16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_type)(sqlite3_stmt*,int iCol);
|
||||
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
|
||||
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
|
||||
int (*complete)(const char*sql);
|
||||
int (*complete16)(const void*sql);
|
||||
int (*create_collation)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_collation16)(sqlite3*,const void*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_function16)(sqlite3*,const void*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
|
||||
int (*data_count)(sqlite3_stmt*pStmt);
|
||||
sqlite3 * (*db_handle)(sqlite3_stmt*);
|
||||
int (*declare_vtab)(sqlite3*,const char*);
|
||||
int (*enable_shared_cache)(int);
|
||||
int (*errcode)(sqlite3*db);
|
||||
const char * (*errmsg)(sqlite3*);
|
||||
const void * (*errmsg16)(sqlite3*);
|
||||
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
|
||||
int (*expired)(sqlite3_stmt*);
|
||||
int (*finalize)(sqlite3_stmt*pStmt);
|
||||
void (*free)(void*);
|
||||
void (*free_table)(char**result);
|
||||
int (*get_autocommit)(sqlite3*);
|
||||
void * (*get_auxdata)(sqlite3_context*,int);
|
||||
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
|
||||
int (*global_recover)(void);
|
||||
void (*interruptx)(sqlite3*);
|
||||
sqlite_int64 (*last_insert_rowid)(sqlite3*);
|
||||
const char * (*libversion)(void);
|
||||
int (*libversion_number)(void);
|
||||
void *(*malloc)(int);
|
||||
char * (*mprintf)(const char*,...);
|
||||
int (*open)(const char*,sqlite3**);
|
||||
int (*open16)(const void*,sqlite3**);
|
||||
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
|
||||
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
|
||||
void *(*realloc)(void*,int);
|
||||
int (*reset)(sqlite3_stmt*pStmt);
|
||||
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_double)(sqlite3_context*,double);
|
||||
void (*result_error)(sqlite3_context*,const char*,int);
|
||||
void (*result_error16)(sqlite3_context*,const void*,int);
|
||||
void (*result_int)(sqlite3_context*,int);
|
||||
void (*result_int64)(sqlite3_context*,sqlite_int64);
|
||||
void (*result_null)(sqlite3_context*);
|
||||
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
|
||||
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_value)(sqlite3_context*,sqlite3_value*);
|
||||
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*snprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
void (*thread_cleanup)(void);
|
||||
int (*total_changes)(sqlite3*);
|
||||
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
|
||||
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
|
||||
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
|
||||
sqlite_int64),void*);
|
||||
void * (*user_data)(sqlite3_context*);
|
||||
const void * (*value_blob)(sqlite3_value*);
|
||||
int (*value_bytes)(sqlite3_value*);
|
||||
int (*value_bytes16)(sqlite3_value*);
|
||||
double (*value_double)(sqlite3_value*);
|
||||
int (*value_int)(sqlite3_value*);
|
||||
sqlite_int64 (*value_int64)(sqlite3_value*);
|
||||
int (*value_numeric_type)(sqlite3_value*);
|
||||
const unsigned char * (*value_text)(sqlite3_value*);
|
||||
const void * (*value_text16)(sqlite3_value*);
|
||||
const void * (*value_text16be)(sqlite3_value*);
|
||||
const void * (*value_text16le)(sqlite3_value*);
|
||||
int (*value_type)(sqlite3_value*);
|
||||
char *(*vmprintf)(const char*,va_list);
|
||||
/* Added ??? */
|
||||
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
|
||||
/* Added by 3.3.13 */
|
||||
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
int (*clear_bindings)(sqlite3_stmt*);
|
||||
/* Added by 3.4.1 */
|
||||
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
|
||||
void (*xDestroy)(void *));
|
||||
/* Added by 3.5.0 */
|
||||
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
|
||||
int (*blob_bytes)(sqlite3_blob*);
|
||||
int (*blob_close)(sqlite3_blob*);
|
||||
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
|
||||
int,sqlite3_blob**);
|
||||
int (*blob_read)(sqlite3_blob*,void*,int,int);
|
||||
int (*blob_write)(sqlite3_blob*,const void*,int,int);
|
||||
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void(*)(void*));
|
||||
int (*file_control)(sqlite3*,const char*,int,void*);
|
||||
sqlite3_int64 (*memory_highwater)(int);
|
||||
sqlite3_int64 (*memory_used)(void);
|
||||
sqlite3_mutex *(*mutex_alloc)(int);
|
||||
void (*mutex_enter)(sqlite3_mutex*);
|
||||
void (*mutex_free)(sqlite3_mutex*);
|
||||
void (*mutex_leave)(sqlite3_mutex*);
|
||||
int (*mutex_try)(sqlite3_mutex*);
|
||||
int (*open_v2)(const char*,sqlite3**,int,const char*);
|
||||
int (*release_memory)(int);
|
||||
void (*result_error_nomem)(sqlite3_context*);
|
||||
void (*result_error_toobig)(sqlite3_context*);
|
||||
int (*sleep)(int);
|
||||
void (*soft_heap_limit)(int);
|
||||
sqlite3_vfs *(*vfs_find)(const char*);
|
||||
int (*vfs_register)(sqlite3_vfs*,int);
|
||||
int (*vfs_unregister)(sqlite3_vfs*);
|
||||
int (*xthreadsafe)(void);
|
||||
void (*result_zeroblob)(sqlite3_context*,int);
|
||||
void (*result_error_code)(sqlite3_context*,int);
|
||||
int (*test_control)(int, ...);
|
||||
void (*randomness)(int,void*);
|
||||
sqlite3 *(*context_db_handle)(sqlite3_context*);
|
||||
int (*extended_result_codes)(sqlite3*,int);
|
||||
int (*limit)(sqlite3*,int,int);
|
||||
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
|
||||
const char *(*sql)(sqlite3_stmt*);
|
||||
int (*status)(int,int*,int*,int);
|
||||
int (*backup_finish)(sqlite3_backup*);
|
||||
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
|
||||
int (*backup_pagecount)(sqlite3_backup*);
|
||||
int (*backup_remaining)(sqlite3_backup*);
|
||||
int (*backup_step)(sqlite3_backup*,int);
|
||||
const char *(*compileoption_get)(int);
|
||||
int (*compileoption_used)(const char*);
|
||||
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*));
|
||||
int (*db_config)(sqlite3*,int,...);
|
||||
sqlite3_mutex *(*db_mutex)(sqlite3*);
|
||||
int (*db_status)(sqlite3*,int,int*,int*,int);
|
||||
int (*extended_errcode)(sqlite3*);
|
||||
void (*log)(int,const char*,...);
|
||||
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
|
||||
const char *(*sourceid)(void);
|
||||
int (*stmt_status)(sqlite3_stmt*,int,int);
|
||||
int (*strnicmp)(const char*,const char*,int);
|
||||
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
|
||||
int (*wal_autocheckpoint)(sqlite3*,int);
|
||||
int (*wal_checkpoint)(sqlite3*,const char*);
|
||||
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
|
||||
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
|
||||
int (*vtab_config)(sqlite3*,int op,...);
|
||||
int (*vtab_on_conflict)(sqlite3*);
|
||||
};
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected throught the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
** it can get access to the sqlite3_api_routines structure
|
||||
** definition. But the main library does not want to redefine
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#ifndef SQLITE_CORE
|
||||
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
|
||||
#endif
|
||||
#define sqlite3_bind_blob sqlite3_api->bind_blob
|
||||
#define sqlite3_bind_double sqlite3_api->bind_double
|
||||
#define sqlite3_bind_int sqlite3_api->bind_int
|
||||
#define sqlite3_bind_int64 sqlite3_api->bind_int64
|
||||
#define sqlite3_bind_null sqlite3_api->bind_null
|
||||
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
|
||||
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
|
||||
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
|
||||
#define sqlite3_bind_text sqlite3_api->bind_text
|
||||
#define sqlite3_bind_text16 sqlite3_api->bind_text16
|
||||
#define sqlite3_bind_value sqlite3_api->bind_value
|
||||
#define sqlite3_busy_handler sqlite3_api->busy_handler
|
||||
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
|
||||
#define sqlite3_changes sqlite3_api->changes
|
||||
#define sqlite3_close sqlite3_api->close
|
||||
#define sqlite3_collation_needed sqlite3_api->collation_needed
|
||||
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
|
||||
#define sqlite3_column_blob sqlite3_api->column_blob
|
||||
#define sqlite3_column_bytes sqlite3_api->column_bytes
|
||||
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
|
||||
#define sqlite3_column_count sqlite3_api->column_count
|
||||
#define sqlite3_column_database_name sqlite3_api->column_database_name
|
||||
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
|
||||
#define sqlite3_column_decltype sqlite3_api->column_decltype
|
||||
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
|
||||
#define sqlite3_column_double sqlite3_api->column_double
|
||||
#define sqlite3_column_int sqlite3_api->column_int
|
||||
#define sqlite3_column_int64 sqlite3_api->column_int64
|
||||
#define sqlite3_column_name sqlite3_api->column_name
|
||||
#define sqlite3_column_name16 sqlite3_api->column_name16
|
||||
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
|
||||
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
|
||||
#define sqlite3_column_table_name sqlite3_api->column_table_name
|
||||
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
|
||||
#define sqlite3_column_text sqlite3_api->column_text
|
||||
#define sqlite3_column_text16 sqlite3_api->column_text16
|
||||
#define sqlite3_column_type sqlite3_api->column_type
|
||||
#define sqlite3_column_value sqlite3_api->column_value
|
||||
#define sqlite3_commit_hook sqlite3_api->commit_hook
|
||||
#define sqlite3_complete sqlite3_api->complete
|
||||
#define sqlite3_complete16 sqlite3_api->complete16
|
||||
#define sqlite3_create_collation sqlite3_api->create_collation
|
||||
#define sqlite3_create_collation16 sqlite3_api->create_collation16
|
||||
#define sqlite3_create_function sqlite3_api->create_function
|
||||
#define sqlite3_create_function16 sqlite3_api->create_function16
|
||||
#define sqlite3_create_module sqlite3_api->create_module
|
||||
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
|
||||
#define sqlite3_data_count sqlite3_api->data_count
|
||||
#define sqlite3_db_handle sqlite3_api->db_handle
|
||||
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
|
||||
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
|
||||
#define sqlite3_errcode sqlite3_api->errcode
|
||||
#define sqlite3_errmsg sqlite3_api->errmsg
|
||||
#define sqlite3_errmsg16 sqlite3_api->errmsg16
|
||||
#define sqlite3_exec sqlite3_api->exec
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_expired sqlite3_api->expired
|
||||
#endif
|
||||
#define sqlite3_finalize sqlite3_api->finalize
|
||||
#define sqlite3_free sqlite3_api->free
|
||||
#define sqlite3_free_table sqlite3_api->free_table
|
||||
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
|
||||
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
|
||||
#define sqlite3_get_table sqlite3_api->get_table
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_global_recover sqlite3_api->global_recover
|
||||
#endif
|
||||
#define sqlite3_interrupt sqlite3_api->interruptx
|
||||
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
|
||||
#define sqlite3_libversion sqlite3_api->libversion
|
||||
#define sqlite3_libversion_number sqlite3_api->libversion_number
|
||||
#define sqlite3_malloc sqlite3_api->malloc
|
||||
#define sqlite3_mprintf sqlite3_api->mprintf
|
||||
#define sqlite3_open sqlite3_api->open
|
||||
#define sqlite3_open16 sqlite3_api->open16
|
||||
#define sqlite3_prepare sqlite3_api->prepare
|
||||
#define sqlite3_prepare16 sqlite3_api->prepare16
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_profile sqlite3_api->profile
|
||||
#define sqlite3_progress_handler sqlite3_api->progress_handler
|
||||
#define sqlite3_realloc sqlite3_api->realloc
|
||||
#define sqlite3_reset sqlite3_api->reset
|
||||
#define sqlite3_result_blob sqlite3_api->result_blob
|
||||
#define sqlite3_result_double sqlite3_api->result_double
|
||||
#define sqlite3_result_error sqlite3_api->result_error
|
||||
#define sqlite3_result_error16 sqlite3_api->result_error16
|
||||
#define sqlite3_result_int sqlite3_api->result_int
|
||||
#define sqlite3_result_int64 sqlite3_api->result_int64
|
||||
#define sqlite3_result_null sqlite3_api->result_null
|
||||
#define sqlite3_result_text sqlite3_api->result_text
|
||||
#define sqlite3_result_text16 sqlite3_api->result_text16
|
||||
#define sqlite3_result_text16be sqlite3_api->result_text16be
|
||||
#define sqlite3_result_text16le sqlite3_api->result_text16le
|
||||
#define sqlite3_result_value sqlite3_api->result_value
|
||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||
#define sqlite3_snprintf sqlite3_api->snprintf
|
||||
#define sqlite3_step sqlite3_api->step
|
||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||
#define sqlite3_total_changes sqlite3_api->total_changes
|
||||
#define sqlite3_trace sqlite3_api->trace
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
|
||||
#endif
|
||||
#define sqlite3_update_hook sqlite3_api->update_hook
|
||||
#define sqlite3_user_data sqlite3_api->user_data
|
||||
#define sqlite3_value_blob sqlite3_api->value_blob
|
||||
#define sqlite3_value_bytes sqlite3_api->value_bytes
|
||||
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
|
||||
#define sqlite3_value_double sqlite3_api->value_double
|
||||
#define sqlite3_value_int sqlite3_api->value_int
|
||||
#define sqlite3_value_int64 sqlite3_api->value_int64
|
||||
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
|
||||
#define sqlite3_value_text sqlite3_api->value_text
|
||||
#define sqlite3_value_text16 sqlite3_api->value_text16
|
||||
#define sqlite3_value_text16be sqlite3_api->value_text16be
|
||||
#define sqlite3_value_text16le sqlite3_api->value_text16le
|
||||
#define sqlite3_value_type sqlite3_api->value_type
|
||||
#define sqlite3_vmprintf sqlite3_api->vmprintf
|
||||
#define sqlite3_overload_function sqlite3_api->overload_function
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
|
||||
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
|
||||
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
|
||||
#define sqlite3_blob_close sqlite3_api->blob_close
|
||||
#define sqlite3_blob_open sqlite3_api->blob_open
|
||||
#define sqlite3_blob_read sqlite3_api->blob_read
|
||||
#define sqlite3_blob_write sqlite3_api->blob_write
|
||||
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
|
||||
#define sqlite3_file_control sqlite3_api->file_control
|
||||
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
|
||||
#define sqlite3_memory_used sqlite3_api->memory_used
|
||||
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
|
||||
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
|
||||
#define sqlite3_mutex_free sqlite3_api->mutex_free
|
||||
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
|
||||
#define sqlite3_mutex_try sqlite3_api->mutex_try
|
||||
#define sqlite3_open_v2 sqlite3_api->open_v2
|
||||
#define sqlite3_release_memory sqlite3_api->release_memory
|
||||
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
|
||||
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
|
||||
#define sqlite3_sleep sqlite3_api->sleep
|
||||
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
|
||||
#define sqlite3_vfs_find sqlite3_api->vfs_find
|
||||
#define sqlite3_vfs_register sqlite3_api->vfs_register
|
||||
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
|
||||
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
|
||||
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
|
||||
#define sqlite3_result_error_code sqlite3_api->result_error_code
|
||||
#define sqlite3_test_control sqlite3_api->test_control
|
||||
#define sqlite3_randomness sqlite3_api->randomness
|
||||
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
|
||||
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
|
||||
#define sqlite3_limit sqlite3_api->limit
|
||||
#define sqlite3_next_stmt sqlite3_api->next_stmt
|
||||
#define sqlite3_sql sqlite3_api->sql
|
||||
#define sqlite3_status sqlite3_api->status
|
||||
#define sqlite3_backup_finish sqlite3_api->backup_finish
|
||||
#define sqlite3_backup_init sqlite3_api->backup_init
|
||||
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
|
||||
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
|
||||
#define sqlite3_backup_step sqlite3_api->backup_step
|
||||
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
|
||||
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
|
||||
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
|
||||
#define sqlite3_db_config sqlite3_api->db_config
|
||||
#define sqlite3_db_mutex sqlite3_api->db_mutex
|
||||
#define sqlite3_db_status sqlite3_api->db_status
|
||||
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
|
||||
#define sqlite3_log sqlite3_api->log
|
||||
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
|
||||
#define sqlite3_sourceid sqlite3_api->sourceid
|
||||
#define sqlite3_stmt_status sqlite3_api->stmt_status
|
||||
#define sqlite3_strnicmp sqlite3_api->strnicmp
|
||||
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
|
||||
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
|
||||
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
|
||||
#define sqlite3_wal_hook sqlite3_api->wal_hook
|
||||
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
|
||||
#define sqlite3_vtab_config sqlite3_api->vtab_config
|
||||
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
|
||||
#endif /* SQLITE_CORE */
|
||||
|
||||
#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0;
|
||||
#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v;
|
||||
|
||||
#endif /* _SQLITE3EXT_H_ */
|
|
@ -0,0 +1 @@
|
|||
b5bf8f14c59b82e556d56af620a029dba2d0be3b
|
|
@ -6,7 +6,7 @@
|
|||
#include "NetworkTest/HttpClientTest.h"
|
||||
#include "TableViewTest/TableViewTestScene.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
#include "EditBoxTest/EditBoxTest.h"
|
||||
#endif
|
||||
|
||||
|
@ -22,7 +22,7 @@ enum
|
|||
TEST_CCCONTROLBUTTON,
|
||||
TEST_COCOSBUILDER,
|
||||
TEST_HTTPCLIENT,
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
TEST_EDITBOX,
|
||||
#endif
|
||||
TEST_TABLEVIEW,
|
||||
|
@ -35,7 +35,7 @@ static const std::string testsName[TEST_MAX_COUNT] =
|
|||
"CCControlButtonTest",
|
||||
"CocosBuilderTest",
|
||||
"HttpClientTest",
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
"EditBoxTest",
|
||||
#endif
|
||||
"TableViewTest"
|
||||
|
@ -107,7 +107,7 @@ void ExtensionsMainLayer::menuCallback(CCObject* pSender)
|
|||
}
|
||||
break;
|
||||
#endif
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
case TEST_EDITBOX:
|
||||
{
|
||||
runEditBoxTest();
|
||||
|
|
|
@ -1 +1 @@
|
|||
4e53e096b4a054e3817b30692cff2b40dafce521
|
||||
3d27ac9829ac45f2433d903b6b4f359a8e20636f
|
|
@ -1 +1 @@
|
|||
8c25f4e08196498edb3752dc9672b14525454fd7
|
||||
1f510de34b422f771994acc6642ef828eb42340a
|
|
@ -97,7 +97,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -151,7 +151,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
|
|
@ -1 +1 @@
|
|||
9d5b1248e92a3f45928c60181236b6a3c3e7617f
|
||||
2e242c0171e848d248e90070640ddf579e07ec13
|
|
@ -97,7 +97,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -149,7 +149,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ec1b3ecbbe576d1a13b5a537df6f5c215d1fbaad
|
||||
Subproject commit b075ab99af838f15a524a0506f068ac2dd1574f9
|
|
@ -1 +1 @@
|
|||
55b8526c01c19734df75118031b5655cc1744422
|
||||
71b990c76b9563a422db95317ef07720122f9617
|
|
@ -97,7 +97,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -151,7 +151,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
256ff6e456360f571ae24d610f20eaf087c174b9
|
|
@ -76,7 +76,7 @@
|
|||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\include;$(ProjectDir)..\..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\..\extensions;$(ProjectDir)..\..\..\..\scripting\javascript\bindings;$(ProjectDir)..\..\..\..\cocos2dx;$(ProjectDir)..\..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\..\CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;STRICT;_DEBUG;DEBUG;COCOS2D_DEBUG=1;COCOS2D_JAVASCRIPT=1;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;STRICT;_DEBUG;DEBUG;XP_WIN;JS_HAVE___INTN;JS_INTPTR_TYPE=int;COCOS2D_DEBUG=1;COCOS2D_JAVASCRIPT=1;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
|
@ -97,7 +97,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -151,7 +151,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\scripting\javascript\spidermonkey-win32\li
|
|||
</Command>
|
||||
</PreLinkEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;mozjs.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libcocos2d.lib;libExtensions.lib;opengl32.lib;glew32.lib;libCocosDenshion.lib;libchipmunk.lib;libJSBinding.lib;mozjs.lib;ws2_32.lib;sqlite3.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "ScriptingCore.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "cocos2d.h"
|
||||
#include "LocalStorage.h"
|
||||
#include "cocos2d_specifics.hpp"
|
||||
// for debug socket
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||
|
@ -465,6 +466,7 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c
|
|||
|
||||
ScriptingCore::~ScriptingCore()
|
||||
{
|
||||
localStorageFree();
|
||||
removeAllRoots(cx_);
|
||||
JS_DestroyContext(cx_);
|
||||
JS_DestroyRuntime(rt_);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "js_bindings_config.h"
|
||||
//#ifdef JSB_INCLUDE_SYSTEM
|
||||
|
||||
//#include "LocalStorage.h"
|
||||
#include "LocalStorage.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "js_bindings_config.h"
|
||||
|
@ -27,12 +27,11 @@ JSBool JSB_localStorageGetItem(JSContext *cx, uint32_t argc, jsval *vp) {
|
|||
|
||||
ok &= jsval_to_charptr( cx, *argvp++, &arg0 );
|
||||
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
|
||||
std::string ret_val;
|
||||
const char* ret_val;
|
||||
|
||||
//ret_val = localStorageGetItem((char*)arg0 );
|
||||
ret_val = CCUserDefault::sharedUserDefault()->getStringForKey(arg0);
|
||||
ret_val = localStorageGetItem((char*)arg0 );
|
||||
|
||||
jsval ret_jsval = charptr_to_jsval( cx, ret_val.c_str() );
|
||||
jsval ret_jsval = charptr_to_jsval( cx, ret_val);
|
||||
JS_SET_RVAL(cx, vp, ret_jsval );
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -49,9 +48,7 @@ JSBool JSB_localStorageRemoveItem(JSContext *cx, uint32_t argc, jsval *vp) {
|
|||
ok &= jsval_to_charptr( cx, *argvp++, &arg0 );
|
||||
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
|
||||
|
||||
CCUserDefault::sharedUserDefault()->setStringForKey(arg0, "");
|
||||
|
||||
//localStorageRemoveItem((char*)arg0 );
|
||||
localStorageRemoveItem((char*)arg0 );
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -68,8 +65,7 @@ JSBool JSB_localStorageSetItem(JSContext *cx, uint32_t argc, jsval *vp) {
|
|||
ok &= jsval_to_charptr( cx, *argvp++, &arg1 );
|
||||
JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments");
|
||||
|
||||
//localStorageSetItem((char*)arg0 , (char*)arg1 );
|
||||
CCUserDefault::sharedUserDefault()->setStringForKey(arg0, arg1);
|
||||
localStorageSetItem((char*)arg0 , (char*)arg1 );
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
|
||||
#include "js_bindings_config.h"
|
||||
#include "js_bindings_core.h"
|
||||
//#include "LocalStorage.h"
|
||||
|
||||
#include "LocalStorage.h"
|
||||
#include "cocos2d.h"
|
||||
|
||||
// system
|
||||
#include "js_bindings_system_functions.h"
|
||||
|
@ -50,11 +50,13 @@ void jsb_register_system( JSContext *_cx, JSObject *object)
|
|||
JSObject *system = ls;
|
||||
#include "js_bindings_system_functions_registration.h"
|
||||
|
||||
/*
|
||||
|
||||
// Init DB with full path
|
||||
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
|
||||
NSString *fullpath = [path stringByAppendingPathComponent:@"jsb.sqlite"];
|
||||
localStorageInit([fullpath UTF8String]);
|
||||
*/
|
||||
//NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
|
||||
//NSString *fullpath = [path stringByAppendingPathComponent:@"jsb.sqlite"];
|
||||
std::string strFilePath = cocos2d::CCFileUtils::sharedFileUtils()->getWriteablePath();
|
||||
strFilePath += "/jsb.sqlite";
|
||||
localStorageInit(strFilePath.c_str());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -105,13 +105,17 @@
|
|||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_LIB;DEBUG;COCOS2D_DEBUG=1;XP_WIN;JS_HAVE___INTN;JS_INTPTR_TYPE=int;COCOS2D_JAVASCRIPT=1;CC_ENABLE_CHIPMUNK_INTEGRATION=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\cocos2dx;$(ProjectDir)..\..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\..\CocosDenshion\include;$(ProjectDir)..;$(ProjectDir)..\..\spidermonkey-win32\include;$(ProjectDir)..\..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\..\extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\cocos2dx;$(ProjectDir)..\..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\..\CocosDenshion\include;$(ProjectDir)..;$(ProjectDir)..\..\spidermonkey-win32\include;$(ProjectDir)..\..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\..\extensions;$(ProjectDir)..\..\..\..\extensions\LocalStorage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4068;4101;4800;4251;4996;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>if not exist "$(OutDir)" mkdir "$(OutDir)"
|
||||
xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\sqlite3\libraries\win32\*.*" "$(OutDir)"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -122,7 +126,7 @@
|
|||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_LIB;XP_WIN;JS_HAVE___INTN;JS_INTPTR_TYPE=int;COCOS2D_JAVASCRIPT=1;CC_ENABLE_CHIPMUNK_INTEGRATION=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\cocos2dx;$(ProjectDir)..\..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\..\CocosDenshion\include;$(ProjectDir)..;$(ProjectDir)..\..\spidermonkey-win32\include;$(ProjectDir)..\..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\..\extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\cocos2dx;$(ProjectDir)..\..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\..\CocosDenshion\include;$(ProjectDir)..;$(ProjectDir)..\..\spidermonkey-win32\include;$(ProjectDir)..\..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\..\extensions;$(ProjectDir)..\..\..\..\extensions\LocalStorage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4068;4101;4800;4251;4996;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -131,6 +135,10 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>if not exist "$(OutDir)" mkdir "$(OutDir)"
|
||||
xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\sqlite3\libraries\win32\*.*" "$(OutDir)"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "jsapi.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Root.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
/*
|
||||
|
@ -172,7 +173,7 @@ class EncapsulatedPtr
|
|||
operator T*() const { return value; }
|
||||
|
||||
protected:
|
||||
void pre() { T::writeBarrierPre(value); }
|
||||
void pre();
|
||||
};
|
||||
|
||||
template <class T, class Unioned = uintptr_t>
|
||||
|
@ -217,6 +218,36 @@ class HeapPtr : public EncapsulatedPtr<T, Unioned>
|
|||
HeapPtr<T2> &v2, T2 *val2);
|
||||
};
|
||||
|
||||
/*
|
||||
* FixedHeapPtr is designed for one very narrow case: replacing immutable raw
|
||||
* pointers to GC-managed things, implicitly converting to a handle type for
|
||||
* ease of use. Pointers encapsulated by this type must:
|
||||
*
|
||||
* be immutable (no incremental write barriers),
|
||||
* never point into the nursery (no generational write barriers), and
|
||||
* be traced via MarkRuntime (we use fromMarkedLocation).
|
||||
*
|
||||
* In short: you *really* need to know what you're doing before you use this
|
||||
* class!
|
||||
*/
|
||||
template <class T>
|
||||
class FixedHeapPtr
|
||||
{
|
||||
T *value;
|
||||
|
||||
public:
|
||||
operator T*() const { return value; }
|
||||
T * operator->() const { return value; }
|
||||
|
||||
operator Handle<T*>() const {
|
||||
return Handle<T*>::fromMarkedLocation(&value);
|
||||
}
|
||||
|
||||
void init(T *ptr) {
|
||||
value = ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
{
|
||||
|
|
|
@ -66,7 +66,8 @@ enum AllocKind {
|
|||
FINALIZE_SHORT_STRING,
|
||||
FINALIZE_STRING,
|
||||
FINALIZE_EXTERNAL_STRING,
|
||||
FINALIZE_LAST = FINALIZE_EXTERNAL_STRING
|
||||
FINALIZE_IONCODE,
|
||||
FINALIZE_LAST = FINALIZE_IONCODE
|
||||
};
|
||||
|
||||
static const unsigned FINALIZE_LIMIT = FINALIZE_LAST + 1;
|
||||
|
@ -103,26 +104,32 @@ struct Cell
|
|||
};
|
||||
|
||||
/*
|
||||
* Page size is 4096 by default, except for SPARC, where it is 8192.
|
||||
* 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.
|
||||
* Bug 692267: Move page size definition to gc/Memory.h and include it
|
||||
* directly once jsgc.h is no longer an installed header.
|
||||
*/
|
||||
#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
|
||||
#if (defined(SOLARIS) || defined(__FreeBSD__)) && \
|
||||
(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;
|
||||
|
||||
const size_t ChunkShift = 20;
|
||||
const size_t ChunkSize = size_t(1) << ChunkShift;
|
||||
const size_t ChunkMask = ChunkSize - 1;
|
||||
|
||||
const size_t ArenaShift = PageShift;
|
||||
const size_t ArenaSize = PageSize;
|
||||
const size_t ArenaMask = ArenaSize - 1;
|
||||
|
||||
/*
|
||||
* This is the maximum number of arenas we allow in the FreeCommitted state
|
||||
* before we trigger a GC_SHRINK to release free arenas to the OS.
|
||||
|
|
|
@ -11,13 +11,11 @@
|
|||
#ifdef __cplusplus
|
||||
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
namespace JS {
|
||||
#include "jspubtd.h"
|
||||
|
||||
/*
|
||||
* Moving GC Stack Rooting
|
||||
|
@ -62,11 +60,24 @@ namespace JS {
|
|||
* separate rooting analysis.
|
||||
*/
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
namespace js {
|
||||
|
||||
template <typename T> class Rooted;
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods { };
|
||||
struct RootMethods {};
|
||||
|
||||
template <typename T>
|
||||
class HandleBase {};
|
||||
|
||||
template <typename T>
|
||||
class MutableHandleBase {};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
|
||||
/*
|
||||
* Handle provides an implicit constructor for NullPtr so that, given:
|
||||
|
@ -83,9 +94,6 @@ struct NullPtr
|
|||
template <typename T>
|
||||
class MutableHandle;
|
||||
|
||||
template <typename T>
|
||||
class HandleBase {};
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -95,7 +103,7 @@ class HandleBase {};
|
|||
* specialization, define a HandleBase<T> specialization containing them.
|
||||
*/
|
||||
template <typename T>
|
||||
class Handle : public HandleBase<T>
|
||||
class Handle : public js::HandleBase<T>
|
||||
{
|
||||
public:
|
||||
/* Creates a handle from a handle of a type convertible to T. */
|
||||
|
@ -136,7 +144,7 @@ class Handle : public HandleBase<T>
|
|||
*/
|
||||
template <typename S>
|
||||
inline
|
||||
Handle(Rooted<S> &root,
|
||||
Handle(js::Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
/* Construct a read only handle from a mutable handle. */
|
||||
|
@ -167,9 +175,6 @@ typedef Handle<JSString*> HandleString;
|
|||
typedef Handle<jsid> HandleId;
|
||||
typedef Handle<Value> HandleValue;
|
||||
|
||||
template <typename T>
|
||||
class MutableHandleBase {};
|
||||
|
||||
/*
|
||||
* Similar to a handle, but the underlying storage can be changed. This is
|
||||
* useful for outparams.
|
||||
|
@ -179,7 +184,7 @@ class MutableHandleBase {};
|
|||
* them.
|
||||
*/
|
||||
template <typename T>
|
||||
class MutableHandle : public MutableHandleBase<T>
|
||||
class MutableHandle : public js::MutableHandleBase<T>
|
||||
{
|
||||
public:
|
||||
template <typename S>
|
||||
|
@ -191,12 +196,12 @@ class MutableHandle : public MutableHandleBase<T>
|
|||
|
||||
template <typename S>
|
||||
inline
|
||||
MutableHandle(Rooted<S> *root,
|
||||
MutableHandle(js::Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
void set(T v)
|
||||
{
|
||||
JS_ASSERT(!RootMethods<T>::poisoned(v));
|
||||
JS_ASSERT(!js::RootMethods<T>::poisoned(v));
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
|
@ -228,14 +233,88 @@ class MutableHandle : public MutableHandleBase<T>
|
|||
void operator =(S v) MOZ_DELETE;
|
||||
};
|
||||
|
||||
typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<JSFunction*> MutableHandleFunction;
|
||||
typedef MutableHandle<JSScript*> MutableHandleScript;
|
||||
typedef MutableHandle<JSString*> MutableHandleString;
|
||||
typedef MutableHandle<jsid> MutableHandleId;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
|
||||
/*
|
||||
* Raw pointer used as documentation that a parameter does not need to be
|
||||
* rooted.
|
||||
*/
|
||||
typedef JSObject * RawObject;
|
||||
typedef JSFunction * RawFunction;
|
||||
typedef JSScript * RawScript;
|
||||
typedef JSString * RawString;
|
||||
typedef jsid RawId;
|
||||
typedef Value RawValue;
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* InternalHandle is a handle to an internal pointer into a gcthing. Use
|
||||
* InternalHandle when you have a pointer to a direct field of a gcthing, or
|
||||
* when you need a parameter type for something that *may* be a pointer to a
|
||||
* direct field of a gcthing.
|
||||
*/
|
||||
template <typename T>
|
||||
class InternalHandle { };
|
||||
|
||||
template <typename T>
|
||||
class InternalHandle<T*>
|
||||
{
|
||||
void * const *holder;
|
||||
size_t offset;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Create an InternalHandle using a Handle to the gcthing containing the
|
||||
* field in question, and a pointer to the field.
|
||||
*/
|
||||
template<typename H>
|
||||
InternalHandle(const JS::Handle<H> &handle, T *field)
|
||||
: holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get()))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an InternalHandle to a field within a Rooted<>.
|
||||
*/
|
||||
template<typename R>
|
||||
InternalHandle(const Rooted<R> &root, T *field)
|
||||
: holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
|
||||
{
|
||||
}
|
||||
|
||||
T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
|
||||
|
||||
const T& operator *() const { return *get(); }
|
||||
T* operator ->() const { return get(); }
|
||||
|
||||
static InternalHandle<T*> fromMarkedLocation(T *fieldPtr) {
|
||||
return InternalHandle(fieldPtr);
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* Create an InternalHandle to something that is not a pointer to a
|
||||
* gcthing, and so does not need to be rooted in the first place. Use these
|
||||
* InternalHandles to pass pointers into functions that also need to accept
|
||||
* regular InternalHandles to gcthing fields.
|
||||
*
|
||||
* Make this private to prevent accidental misuse; this is only for
|
||||
* fromMarkedLocation().
|
||||
*/
|
||||
InternalHandle(T *field)
|
||||
: holder(reinterpret_cast<void * const *>(&NullPtr::constNullValue)),
|
||||
offset(uintptr_t(field))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* By default, pointers should use the inheritance hierarchy to find their
|
||||
|
@ -243,7 +322,7 @@ typedef JSObject * RawObject;
|
|||
* Rooted<T> may be used without the class definition being available.
|
||||
*/
|
||||
template <typename T>
|
||||
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); }; };
|
||||
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); } };
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods<T *>
|
||||
|
@ -253,6 +332,12 @@ struct RootMethods<T *>
|
|||
static bool poisoned(T *v) { return IsPoisonedPtr(v); }
|
||||
};
|
||||
|
||||
#if !(defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING))
|
||||
// Defined in vm/String.h.
|
||||
template <>
|
||||
class Rooted<JSStableString *>;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
class RootedBase {};
|
||||
|
||||
|
@ -267,10 +352,10 @@ class RootedBase {};
|
|||
template <typename T>
|
||||
class Rooted : public RootedBase<T>
|
||||
{
|
||||
void init(JSContext *cx_)
|
||||
void init(JSContext *cxArg)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cx_);
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cxArg);
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Rooted<T>**>(&cx->thingGCRooters[kind]);
|
||||
|
@ -281,9 +366,52 @@ class Rooted : public RootedBase<T>
|
|||
#endif
|
||||
}
|
||||
|
||||
void init(JSRuntime *rtArg)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
RuntimeFriendFields *rt = const_cast<RuntimeFriendFields *>(RuntimeFriendFields::get(rtArg));
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Rooted<T>**>(&rt->thingGCRooters[kind]);
|
||||
this->prev = *stack;
|
||||
*stack = this;
|
||||
|
||||
JS_ASSERT(!RootMethods<T>::poisoned(ptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
Rooted(JSContext *cx) : ptr(RootMethods<T>::initial()) { init(cx); }
|
||||
Rooted(JSContext *cx, T initial) : ptr(initial) { init(cx); }
|
||||
Rooted(JSRuntime *rt
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(RootMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(rt);
|
||||
}
|
||||
|
||||
Rooted(JSRuntime *rt, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(rt);
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(RootMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
~Rooted()
|
||||
{
|
||||
|
@ -318,40 +446,15 @@ class Rooted : public RootedBase<T>
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
Rooted<T> **stack, *prev;
|
||||
#endif
|
||||
T ptr;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
Rooted() MOZ_DELETE;
|
||||
Rooted(const Rooted &) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
|
@ -367,7 +470,7 @@ typedef Rooted<Value> RootedValue;
|
|||
*/
|
||||
class SkipRoot
|
||||
{
|
||||
#if defined(DEBUG) && defined(JSGC_ROOT_ANALYSIS)
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
|
||||
SkipRoot **stack, *prev;
|
||||
const uint8_t *start;
|
||||
|
@ -419,64 +522,123 @@ class SkipRoot
|
|||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(js::Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(js::Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void) EnterAssertNoGCScope();
|
||||
JS_FRIEND_API(void) LeaveAssertNoGCScope();
|
||||
JS_FRIEND_API(bool) InNoGCScope();
|
||||
|
||||
/*
|
||||
* This typedef is to annotate parameters that we have manually verified do not
|
||||
* need rooting, as opposed to parameters that have not yet been considered.
|
||||
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
|
||||
* attempted while the guard object is live. If you have a GC-unsafe operation
|
||||
* to perform, use this guard object to protect your operation.
|
||||
*/
|
||||
typedef JSObject *RawObject;
|
||||
class AutoAssertNoGC
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_FRIEND_API(bool) IsRootingUnnecessaryForContext(JSContext *cx);
|
||||
JS_FRIEND_API(void) SetRootingUnnecessaryForContext(JSContext *cx, bool value);
|
||||
JS_FRIEND_API(bool) RelaxRootChecksForContext(JSContext *cx);
|
||||
#endif
|
||||
|
||||
class AssertRootingUnnecessary {
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
#ifdef DEBUG
|
||||
JSContext *cx;
|
||||
bool prev;
|
||||
#endif
|
||||
public:
|
||||
AssertRootingUnnecessary(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
AutoAssertNoGC(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
#ifdef DEBUG
|
||||
this->cx = cx;
|
||||
prev = IsRootingUnnecessaryForContext(cx);
|
||||
SetRootingUnnecessaryForContext(cx, true);
|
||||
EnterAssertNoGCScope();
|
||||
#endif
|
||||
}
|
||||
|
||||
~AssertRootingUnnecessary() {
|
||||
~AutoAssertNoGC() {
|
||||
#ifdef DEBUG
|
||||
SetRootingUnnecessaryForContext(cx, prev);
|
||||
LeaveAssertNoGCScope();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* AssertCanGC will assert if it is called inside of an AutoAssertNoGC region.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
JS_ALWAYS_INLINE void
|
||||
AssertCanGC()
|
||||
{
|
||||
JS_ASSERT(!InNoGCScope());
|
||||
}
|
||||
#else
|
||||
# define AssertCanGC()
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
extern void
|
||||
CheckStackRoots(JSContext *cx);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(bool) NeedRelaxedRootChecks();
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Hook for dynamic root analysis. Checks the native stack and poisons
|
||||
* references to GC things which have not been rooted.
|
||||
*/
|
||||
inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!IsRootingUnnecessaryForContext(cx));
|
||||
# if defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
if (relax && RelaxRootChecksForContext(cx))
|
||||
AssertCanGC();
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
if (relax && NeedRelaxedRootChecks())
|
||||
return;
|
||||
CheckStackRoots(cx);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
namespace gc {
|
||||
struct Cell;
|
||||
} /* namespace gc */
|
||||
|
||||
/* Base class for automatic read-only object rooting during compilation. */
|
||||
class CompilerRootNode
|
||||
{
|
||||
protected:
|
||||
CompilerRootNode(js::gc::Cell *ptr)
|
||||
: next(NULL), ptr(ptr)
|
||||
{ }
|
||||
|
||||
public:
|
||||
void **address() { return (void **)&ptr; }
|
||||
|
||||
public:
|
||||
CompilerRootNode *next;
|
||||
|
||||
protected:
|
||||
js::gc::Cell *ptr;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ enum Phase {
|
|||
PHASE_SWEEP_STRING,
|
||||
PHASE_SWEEP_SCRIPT,
|
||||
PHASE_SWEEP_SHAPE,
|
||||
PHASE_SWEEP_IONCODE,
|
||||
PHASE_SWEEP_DISCARD_CODE,
|
||||
PHASE_DISCARD_ANALYSIS,
|
||||
PHASE_DISCARD_TI,
|
||||
|
|
|
@ -360,3 +360,18 @@ MSG_DEF(JSMSG_PAR_ARRAY_REDUCE_EMPTY, 306, 0, JSEXN_ERR, "cannot reduce empty Pa
|
|||
MSG_DEF(JSMSG_PAR_ARRAY_ALREADY_FLAT, 307, 0, JSEXN_ERR, "cannot flatten 1-dimensional ParallelArray object")
|
||||
MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_CONFLICT, 308, 0, JSEXN_ERR, "no conflict resolution function provided")
|
||||
MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BOUNDS, 309, 0, JSEXN_ERR, "index in scatter vector out of bounds")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE, 310, 0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 311, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_NEW, 312, 0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_INVALID, 313, 0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC, 314, 0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_NEW, 315, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 316, 0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 317, 0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable")
|
||||
MSG_DEF(JSMSG_INVALID_TRAP_RESULT, 318, 2, JSEXN_TYPEERR, "trap {1} for {0} returned an invalid result")
|
||||
MSG_DEF(JSMSG_CANT_SKIP_NC, 319, 0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property")
|
||||
MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 320, 0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property")
|
||||
MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 321, 0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter")
|
||||
MSG_DEF(JSMSG_CANT_SET_NW_NC, 322, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property")
|
||||
MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 323, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter")
|
||||
MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 324, 2, JSEXN_TYPEERR, "{0} does not refer to {1}")
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#ifndef jshashtable_h_
|
||||
#define jshashtable_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "TemplateLib.h"
|
||||
#include "Utility.h"
|
||||
|
||||
|
@ -340,8 +342,7 @@ class HashTable : private AllocPolicy
|
|||
|
||||
MOZ_WARN_UNUSED_RESULT bool init(uint32_t length)
|
||||
{
|
||||
/* Make sure that init isn't called twice. */
|
||||
JS_ASSERT(table == NULL);
|
||||
JS_ASSERT(!initialized());
|
||||
|
||||
/*
|
||||
* Correct for sMaxAlphaFrac such that the table will not resize
|
||||
|
@ -1013,10 +1014,6 @@ class HashMap
|
|||
|
||||
friend class Impl::Enum;
|
||||
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashMap(const HashMap &);
|
||||
HashMap &operator=(const HashMap &);
|
||||
|
||||
Impl impl;
|
||||
|
||||
public:
|
||||
|
@ -1218,6 +1215,11 @@ class HashMap
|
|||
if (Ptr p = lookup(l))
|
||||
remove(p);
|
||||
}
|
||||
|
||||
private:
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashMap(const HashMap &hm) MOZ_DELETE;
|
||||
HashMap &operator=(const HashMap &hm) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1251,10 +1253,6 @@ class HashSet
|
|||
|
||||
friend class Impl::Enum;
|
||||
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashSet(const HashSet &);
|
||||
HashSet &operator=(const HashSet &);
|
||||
|
||||
Impl impl;
|
||||
|
||||
public:
|
||||
|
@ -1418,6 +1416,11 @@ class HashSet
|
|||
if (Ptr p = lookup(l))
|
||||
remove(p);
|
||||
}
|
||||
|
||||
private:
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashSet(const HashSet &hs) MOZ_DELETE;
|
||||
HashSet &operator=(const HashSet &hs) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -8,10 +8,8 @@
|
|||
#ifndef js_MemoryMetrics_h
|
||||
#define js_MemoryMetrics_h
|
||||
|
||||
/*
|
||||
* These declarations are not within jsapi.h because they are highly likely
|
||||
* to change in the future. Depend on them at your own risk.
|
||||
*/
|
||||
// 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 <string.h>
|
||||
|
||||
|
@ -21,11 +19,31 @@
|
|||
#include "js/Utility.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
// In memory reporting, we have concept of "sundries", line items which are too
|
||||
// small to be worth reporting individually. Under some circumstances, a memory
|
||||
// reporter gets tossed into the sundries bucket if it's smaller than
|
||||
// MemoryReportingSundriesThreshold() bytes.
|
||||
//
|
||||
// We need to define this value here, rather than in the code which actually
|
||||
// generates the memory reports, because HugeStringInfo uses this value.
|
||||
JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold();
|
||||
|
||||
} // namespace js
|
||||
|
||||
namespace JS {
|
||||
|
||||
/* Data for tracking analysis/inference memory usage. */
|
||||
// Data for tracking analysis/inference memory usage.
|
||||
struct TypeInferenceSizes
|
||||
{
|
||||
TypeInferenceSizes()
|
||||
: scripts(0)
|
||||
, objects(0)
|
||||
, tables(0)
|
||||
, temporary(0)
|
||||
{}
|
||||
|
||||
size_t scripts;
|
||||
size_t objects;
|
||||
size_t tables;
|
||||
|
@ -39,6 +57,34 @@ struct TypeInferenceSizes
|
|||
}
|
||||
};
|
||||
|
||||
// Holds data about a huge string (one which uses more HugeStringInfo::MinSize
|
||||
// bytes of memory), so we can report it individually.
|
||||
struct HugeStringInfo
|
||||
{
|
||||
HugeStringInfo()
|
||||
: length(0)
|
||||
, size(0)
|
||||
{
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
}
|
||||
|
||||
// A string needs to take up this many bytes of storage before we consider
|
||||
// it to be "huge".
|
||||
static size_t MinSize()
|
||||
{
|
||||
return js::MemoryReportingSundriesThreshold();
|
||||
}
|
||||
|
||||
// A string's size in memory is not necessarily equal to twice its length
|
||||
// because the allocator and the JS engine both may round up.
|
||||
size_t length;
|
||||
size_t size;
|
||||
|
||||
// We record the first 32 chars of the escaped string here. (We escape the
|
||||
// string so we can use a char[] instead of a jschar[] here.
|
||||
char buffer[32];
|
||||
};
|
||||
|
||||
// These measurements relate directly to the JSRuntime, and not to
|
||||
// compartments within it.
|
||||
struct RuntimeSizes
|
||||
|
@ -49,15 +95,15 @@ struct RuntimeSizes
|
|||
, contexts(0)
|
||||
, dtoa(0)
|
||||
, temporary(0)
|
||||
, mjitCode(0)
|
||||
, jaegerCode(0)
|
||||
, ionCode(0)
|
||||
, regexpCode(0)
|
||||
, unusedCodeMemory(0)
|
||||
, stackCommitted(0)
|
||||
, unusedCode(0)
|
||||
, stack(0)
|
||||
, gcMarker(0)
|
||||
, mathCache(0)
|
||||
, scriptFilenames(0)
|
||||
, scriptSources(0)
|
||||
, compartmentObjects(0)
|
||||
{}
|
||||
|
||||
size_t object;
|
||||
|
@ -65,34 +111,102 @@ struct RuntimeSizes
|
|||
size_t contexts;
|
||||
size_t dtoa;
|
||||
size_t temporary;
|
||||
size_t mjitCode;
|
||||
size_t jaegerCode;
|
||||
size_t ionCode;
|
||||
size_t regexpCode;
|
||||
size_t unusedCodeMemory;
|
||||
size_t stackCommitted;
|
||||
size_t unusedCode;
|
||||
size_t stack;
|
||||
size_t gcMarker;
|
||||
size_t mathCache;
|
||||
size_t scriptFilenames;
|
||||
size_t scriptSources;
|
||||
|
||||
// This is the exception to the "RuntimeSizes doesn't measure things within
|
||||
// compartments" rule. We combine the sizes of all the JSCompartment
|
||||
// objects into a single measurement because each one is fairly small, and
|
||||
// they're all the same size.
|
||||
size_t compartmentObjects;
|
||||
};
|
||||
|
||||
struct CompartmentStats
|
||||
{
|
||||
CompartmentStats() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
CompartmentStats()
|
||||
: extra1(0)
|
||||
, extra2(0)
|
||||
, gcHeapArenaAdmin(0)
|
||||
, gcHeapUnusedGcThings(0)
|
||||
, gcHeapObjectsNonFunction(0)
|
||||
, gcHeapObjectsFunction(0)
|
||||
, gcHeapStrings(0)
|
||||
, gcHeapShapesTree(0)
|
||||
, gcHeapShapesDict(0)
|
||||
, gcHeapShapesBase(0)
|
||||
, gcHeapScripts(0)
|
||||
, gcHeapTypeObjects(0)
|
||||
, gcHeapIonCodes(0)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
, gcHeapXML(0)
|
||||
#endif
|
||||
, objectsExtraSlots(0)
|
||||
, objectsExtraElements(0)
|
||||
, objectsExtraArgumentsData(0)
|
||||
, objectsExtraRegExpStatics(0)
|
||||
, objectsExtraPropertyIteratorData(0)
|
||||
, objectsExtraPrivate(0)
|
||||
, nonHugeStringChars(0)
|
||||
, shapesExtraTreeTables(0)
|
||||
, shapesExtraDictTables(0)
|
||||
, shapesExtraTreeShapeKids(0)
|
||||
, shapesCompartmentTables(0)
|
||||
, scriptData(0)
|
||||
, jaegerData(0)
|
||||
, ionData(0)
|
||||
, compartmentObject(0)
|
||||
, crossCompartmentWrappers(0)
|
||||
, regexpCompartment(0)
|
||||
, debuggeesSet(0)
|
||||
{}
|
||||
|
||||
CompartmentStats(const CompartmentStats &other)
|
||||
: extra1(other.extra1)
|
||||
, extra2(other.extra2)
|
||||
, gcHeapArenaAdmin(other.gcHeapArenaAdmin)
|
||||
, gcHeapUnusedGcThings(other.gcHeapUnusedGcThings)
|
||||
, gcHeapObjectsNonFunction(other.gcHeapObjectsNonFunction)
|
||||
, gcHeapObjectsFunction(other.gcHeapObjectsFunction)
|
||||
, gcHeapStrings(other.gcHeapStrings)
|
||||
, gcHeapShapesTree(other.gcHeapShapesTree)
|
||||
, gcHeapShapesDict(other.gcHeapShapesDict)
|
||||
, gcHeapShapesBase(other.gcHeapShapesBase)
|
||||
, gcHeapScripts(other.gcHeapScripts)
|
||||
, gcHeapTypeObjects(other.gcHeapTypeObjects)
|
||||
, gcHeapIonCodes(other.gcHeapIonCodes)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
, gcHeapXML(other.gcHeapXML)
|
||||
#endif
|
||||
, objectsExtraSlots(other.objectsExtraSlots)
|
||||
, objectsExtraElements(other.objectsExtraElements)
|
||||
, objectsExtraArgumentsData(other.objectsExtraArgumentsData)
|
||||
, objectsExtraRegExpStatics(other.objectsExtraRegExpStatics)
|
||||
, objectsExtraPropertyIteratorData(other.objectsExtraPropertyIteratorData)
|
||||
, objectsExtraPrivate(other.objectsExtraPrivate)
|
||||
, nonHugeStringChars(other.nonHugeStringChars)
|
||||
, shapesExtraTreeTables(other.shapesExtraTreeTables)
|
||||
, shapesExtraDictTables(other.shapesExtraDictTables)
|
||||
, shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids)
|
||||
, shapesCompartmentTables(other.shapesCompartmentTables)
|
||||
, scriptData(other.scriptData)
|
||||
, jaegerData(other.jaegerData)
|
||||
, ionData(other.ionData)
|
||||
, compartmentObject(other.compartmentObject)
|
||||
, crossCompartmentWrappers(other.crossCompartmentWrappers)
|
||||
, regexpCompartment(other.regexpCompartment)
|
||||
, debuggeesSet(other.debuggeesSet)
|
||||
, typeInferenceSizes(other.typeInferenceSizes)
|
||||
{
|
||||
hugeStrings.append(other.hugeStrings);
|
||||
}
|
||||
|
||||
// These fields can be used by embedders.
|
||||
void *extra1;
|
||||
void *extra2;
|
||||
|
||||
// If you add a new number, remember to update add() and maybe
|
||||
// gcHeapThingsSize()!
|
||||
// If you add a new number, remember to update the constructors, add(), and
|
||||
// maybe gcHeapThingsSize()!
|
||||
size_t gcHeapArenaAdmin;
|
||||
size_t gcHeapUnusedGcThings;
|
||||
|
||||
|
@ -104,27 +218,36 @@ struct CompartmentStats
|
|||
size_t gcHeapShapesBase;
|
||||
size_t gcHeapScripts;
|
||||
size_t gcHeapTypeObjects;
|
||||
size_t gcHeapIonCodes;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
size_t gcHeapXML;
|
||||
#endif
|
||||
|
||||
size_t objectSlots;
|
||||
size_t objectElements;
|
||||
size_t objectMisc;
|
||||
size_t objectPrivate;
|
||||
size_t stringChars;
|
||||
size_t objectsExtraSlots;
|
||||
size_t objectsExtraElements;
|
||||
size_t objectsExtraArgumentsData;
|
||||
size_t objectsExtraRegExpStatics;
|
||||
size_t objectsExtraPropertyIteratorData;
|
||||
size_t objectsExtraPrivate;
|
||||
size_t nonHugeStringChars;
|
||||
size_t shapesExtraTreeTables;
|
||||
size_t shapesExtraDictTables;
|
||||
size_t shapesExtraTreeShapeKids;
|
||||
size_t shapesCompartmentTables;
|
||||
size_t scriptData;
|
||||
size_t mjitData;
|
||||
size_t jaegerData;
|
||||
size_t ionData;
|
||||
size_t compartmentObject;
|
||||
size_t crossCompartmentWrappers;
|
||||
size_t regexpCompartment;
|
||||
size_t debuggeesSet;
|
||||
|
||||
TypeInferenceSizes typeInferenceSizes;
|
||||
js::Vector<HugeStringInfo, 0, js::SystemAllocPolicy> hugeStrings;
|
||||
|
||||
// Add cStats's numbers to this object's numbers.
|
||||
void add(CompartmentStats &cStats) {
|
||||
void add(CompartmentStats &cStats)
|
||||
{
|
||||
#define ADD(x) this->x += cStats.x
|
||||
|
||||
ADD(gcHeapArenaAdmin);
|
||||
|
@ -138,26 +261,34 @@ struct CompartmentStats
|
|||
ADD(gcHeapShapesBase);
|
||||
ADD(gcHeapScripts);
|
||||
ADD(gcHeapTypeObjects);
|
||||
ADD(gcHeapIonCodes);
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
ADD(gcHeapXML);
|
||||
#endif
|
||||
|
||||
ADD(objectSlots);
|
||||
ADD(objectElements);
|
||||
ADD(objectMisc);
|
||||
ADD(objectPrivate);
|
||||
ADD(stringChars);
|
||||
ADD(objectsExtraSlots);
|
||||
ADD(objectsExtraElements);
|
||||
ADD(objectsExtraArgumentsData);
|
||||
ADD(objectsExtraRegExpStatics);
|
||||
ADD(objectsExtraPropertyIteratorData);
|
||||
ADD(objectsExtraPrivate);
|
||||
ADD(nonHugeStringChars);
|
||||
ADD(shapesExtraTreeTables);
|
||||
ADD(shapesExtraDictTables);
|
||||
ADD(shapesExtraTreeShapeKids);
|
||||
ADD(shapesCompartmentTables);
|
||||
ADD(scriptData);
|
||||
ADD(mjitData);
|
||||
ADD(jaegerData);
|
||||
ADD(ionData);
|
||||
ADD(compartmentObject);
|
||||
ADD(crossCompartmentWrappers);
|
||||
ADD(regexpCompartment);
|
||||
ADD(debuggeesSet);
|
||||
|
||||
#undef ADD
|
||||
|
||||
typeInferenceSizes.add(cStats.typeInferenceSizes);
|
||||
hugeStrings.append(cStats.hugeStrings);
|
||||
}
|
||||
|
||||
// The size of all the live things in the GC heap.
|
||||
|
@ -239,7 +370,7 @@ CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *
|
|||
extern JS_PUBLIC_API(int64_t)
|
||||
GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
#endif /* JS_THREADSAFE */
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
extern JS_PUBLIC_API(size_t)
|
||||
SystemCompartmentCount(const JSRuntime *rt);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "jstypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include "js/TemplateLib.h"
|
||||
# include "mozilla/Scoped.h"
|
||||
|
||||
/* The public JS engine namespace. */
|
||||
|
@ -146,11 +147,6 @@ PrintBacktrace()
|
|||
# define JS_OOM_POSSIBLY_FAIL_REPORT(cx) do {} while(0)
|
||||
# endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* SpiderMonkey code should not be calling these allocation functions directly.
|
||||
* Instead, all calls should go through JSRuntime, JSContext or OffTheBooks.
|
||||
* However, js_free() can be called directly.
|
||||
*/
|
||||
static JS_INLINE void* js_malloc(size_t bytes)
|
||||
{
|
||||
JS_OOM_POSSIBLY_FAIL();
|
||||
|
@ -381,82 +377,45 @@ JS_END_EXTERN_C
|
|||
#include <new>
|
||||
|
||||
/*
|
||||
* User guide to memory management within SpiderMonkey:
|
||||
* Low-level memory management in SpiderMonkey:
|
||||
*
|
||||
* Quick tips:
|
||||
* ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these
|
||||
* to be redefined (via JS_USE_CUSTOM_ALLOCATOR) and Gecko even #define's
|
||||
* these symbols.
|
||||
*
|
||||
* Allocation:
|
||||
* - Prefer to allocate using JSContext:
|
||||
* cx->{malloc_,realloc_,calloc_,new_,array_new}
|
||||
* ** Do not use the builtin C++ operator new and delete: these throw on
|
||||
* error and we cannot override them not to.
|
||||
*
|
||||
* - If no JSContext is available, use a JSRuntime:
|
||||
* rt->{malloc_,realloc_,calloc_,new_,array_new}
|
||||
* Allocation:
|
||||
*
|
||||
* - As a last resort, use unaccounted allocation ("OffTheBooks"):
|
||||
* js::OffTheBooks::{malloc_,realloc_,calloc_,new_,array_new}
|
||||
* - If the lifetime of the allocation is tied to the lifetime of a GC-thing
|
||||
* (that is, finalizing the GC-thing will free the allocation), call one of
|
||||
* the following functions:
|
||||
*
|
||||
* Deallocation:
|
||||
* - When the deallocation occurs on a slow path, use:
|
||||
* Foreground::{free_,delete_,array_delete}
|
||||
* JSContext::{malloc_,realloc_,calloc_,new_}
|
||||
* JSRuntime::{malloc_,realloc_,calloc_,new_}
|
||||
*
|
||||
* - Otherwise deallocate on a background thread using a JSContext:
|
||||
* cx->{free_,delete_,array_delete}
|
||||
* These functions accumulate the number of bytes allocated which is used as
|
||||
* part of the GC-triggering heuristic.
|
||||
*
|
||||
* - If no JSContext is available, use a JSRuntime:
|
||||
* rt->{free_,delete_,array_delete}
|
||||
* The difference between the JSContext and JSRuntime versions is that the
|
||||
* cx version reports an out-of-memory error on OOM. (This follows from the
|
||||
* general SpiderMonkey idiom that a JSContext-taking function reports its
|
||||
* own errors.)
|
||||
*
|
||||
* - As a last resort, use UnwantedForeground deallocation:
|
||||
* js::UnwantedForeground::{free_,delete_,array_delete}
|
||||
* - Otherwise, use js_malloc/js_realloc/js_calloc/js_free/js_new
|
||||
*
|
||||
* General tips:
|
||||
* Deallocation:
|
||||
*
|
||||
* - Mixing and matching these allocators is allowed (you may free memory
|
||||
* allocated by any allocator, with any deallocator).
|
||||
* - Ordinarily, use js_free/js_delete.
|
||||
*
|
||||
* - Never, ever use normal C/C++ memory management:
|
||||
* malloc, free, new, new[], delete, operator new, etc.
|
||||
* - For deallocations during GC finalization, use one of the following
|
||||
* operations on the FreeOp provided to the finalizer:
|
||||
*
|
||||
* - Never, ever use low-level SpiderMonkey allocators:
|
||||
* js_malloc(), js_free(), js_calloc(), js_realloc()
|
||||
* Their use is reserved for the other memory managers.
|
||||
* FreeOp::{free_,delete_}
|
||||
*
|
||||
* - Classes which have private constructors or destructors should have
|
||||
* JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR added to their
|
||||
* declaration.
|
||||
*
|
||||
* Details:
|
||||
*
|
||||
* Using vanilla new/new[] is unsafe in SpiderMonkey because they throw on
|
||||
* failure instead of returning NULL, which is what SpiderMonkey expects.
|
||||
* (Even overriding them is unsafe, as the system's C++ runtime library may
|
||||
* throw, which we do not support. We also can't just use the 'nothrow'
|
||||
* variant of new/new[], because we want to mediate *all* allocations
|
||||
* within SpiderMonkey, to satisfy any embedders using
|
||||
* JS_USE_CUSTOM_ALLOCATOR.)
|
||||
*
|
||||
* JSContexts and JSRuntimes keep track of memory allocated, and use this
|
||||
* accounting to schedule GC. OffTheBooks does not. We'd like to remove
|
||||
* OffTheBooks allocations as much as possible (bug 636558).
|
||||
*
|
||||
* On allocation failure, a JSContext correctly reports an error, which a
|
||||
* JSRuntime and OffTheBooks does not.
|
||||
*
|
||||
* A JSContext deallocates in a background thread. A JSRuntime might
|
||||
* deallocate in the background in the future, but does not now. Foreground
|
||||
* deallocation is preferable on slow paths. UnwantedForeground deallocations
|
||||
* occur where we have no JSContext or JSRuntime, and the deallocation is not
|
||||
* on a slow path. We want to remove UnwantedForeground deallocations (bug
|
||||
* 636561).
|
||||
*
|
||||
* JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR makes the allocation
|
||||
* classes friends with your class, giving them access to private
|
||||
* constructors and destructors.
|
||||
*
|
||||
* |make check| does a source level check on the number of uses OffTheBooks,
|
||||
* UnwantedForeground, js_malloc, js_free etc, to prevent regressions. If you
|
||||
* really must add one, update Makefile.in, and run |make check|.
|
||||
*
|
||||
* |make check| also statically prevents the use of vanilla new/new[].
|
||||
* The advantage of these operations is that the memory is batched and freed
|
||||
* on another thread.
|
||||
*/
|
||||
|
||||
#define JS_NEW_BODY(allocator, t, parms) \
|
||||
|
@ -464,190 +423,144 @@ JS_END_EXTERN_C
|
|||
return memory ? new(memory) t parms : NULL;
|
||||
|
||||
/*
|
||||
* Given a class which should provide new_() methods, add
|
||||
* Given a class which should provide 'new' methods, add
|
||||
* JS_DECLARE_NEW_METHODS (see JSContext for a usage example). This
|
||||
* adds new_()s with up to 12 parameters. Add more versions of new_ below if
|
||||
* adds news with up to 12 parameters. Add more versions of new below if
|
||||
* you need more than 12 parameters.
|
||||
*
|
||||
* Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS,
|
||||
* or the build will break.
|
||||
*/
|
||||
#define JS_DECLARE_NEW_METHODS(ALLOCATOR, QUALIFIERS)\
|
||||
#define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS)\
|
||||
template <class T>\
|
||||
QUALIFIERS T *new_() {\
|
||||
QUALIFIERS T *NEWNAME() {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, ())\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1>\
|
||||
QUALIFIERS T *new_(P1 p1) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12))\
|
||||
}\
|
||||
static const int JSMinAlignment = 8;\
|
||||
template <class T>\
|
||||
QUALIFIERS T *array_new(size_t n) {\
|
||||
/* The length is stored just before the vector memory. */\
|
||||
uint64_t numBytes64 = uint64_t(JSMinAlignment) + uint64_t(sizeof(T)) * uint64_t(n);\
|
||||
size_t numBytes = size_t(numBytes64);\
|
||||
if (numBytes64 != numBytes) {\
|
||||
JS_ASSERT(0); /* we want to know if this happens in debug builds */\
|
||||
return NULL;\
|
||||
}\
|
||||
void *memory = ALLOCATOR(numBytes);\
|
||||
if (!memory)\
|
||||
return NULL;\
|
||||
*(size_t *)memory = n;\
|
||||
memory = (void*)(uintptr_t(memory) + JSMinAlignment);\
|
||||
return new(memory) T[n];\
|
||||
}\
|
||||
|
||||
JS_DECLARE_NEW_METHODS(js_new, js_malloc, static JS_ALWAYS_INLINE)
|
||||
|
||||
#define JS_DECLARE_DELETE_METHODS(DEALLOCATOR, QUALIFIERS)\
|
||||
template <class T>\
|
||||
QUALIFIERS void delete_(T *p) {\
|
||||
if (p) {\
|
||||
p->~T();\
|
||||
DEALLOCATOR(p);\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
template <class T>\
|
||||
QUALIFIERS void array_delete(T *p) {\
|
||||
if (p) {\
|
||||
void* p0 = (void *)(uintptr_t(p) - js::OffTheBooks::JSMinAlignment);\
|
||||
size_t n = *(size_t *)p0;\
|
||||
for (size_t i = 0; i < n; i++)\
|
||||
(p + i)->~T();\
|
||||
DEALLOCATOR(p0);\
|
||||
}\
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE void
|
||||
js_delete(T *p)
|
||||
{
|
||||
if (p) {
|
||||
p->~T();
|
||||
js_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_malloc()
|
||||
{
|
||||
return (T *)js_malloc(sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_calloc()
|
||||
{
|
||||
return (T *)js_calloc(sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_malloc(size_t numElems)
|
||||
{
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
|
||||
return NULL;
|
||||
return (T *)js_malloc(numElems * sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_calloc(size_t numElems)
|
||||
{
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
|
||||
return NULL;
|
||||
return (T *)js_calloc(numElems * sizeof(T));
|
||||
}
|
||||
|
||||
/*
|
||||
* In general, all allocations should go through a JSContext or JSRuntime, so
|
||||
* that the garbage collector knows how much memory has been allocated. In
|
||||
* cases where it is difficult to use a JSContext or JSRuntime, OffTheBooks can
|
||||
* be used, though this is undesirable.
|
||||
*/
|
||||
namespace js {
|
||||
|
||||
class OffTheBooks {
|
||||
public:
|
||||
JS_DECLARE_NEW_METHODS(::js_malloc, JS_ALWAYS_INLINE static)
|
||||
|
||||
static JS_INLINE void* malloc_(size_t bytes) {
|
||||
return ::js_malloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* calloc_(size_t bytes) {
|
||||
return ::js_calloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* realloc_(void* p, size_t bytes) {
|
||||
return ::js_realloc(p, bytes);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* We generally prefer deallocating using JSContext because it can happen in
|
||||
* the background. On slow paths, we may prefer foreground allocation.
|
||||
*/
|
||||
class Foreground {
|
||||
public:
|
||||
/* See parentheses comment above. */
|
||||
static JS_ALWAYS_INLINE void free_(void* p) {
|
||||
::js_free(p);
|
||||
}
|
||||
|
||||
JS_DECLARE_DELETE_METHODS(::js_free, JS_ALWAYS_INLINE static)
|
||||
};
|
||||
|
||||
class UnwantedForeground : public Foreground {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ScopedFreePtrTraits
|
||||
{
|
||||
typedef T* type;
|
||||
static T* empty() { return NULL; }
|
||||
static void release(T* ptr) { Foreground::free_(ptr); }
|
||||
static void release(T* ptr) { js_free(ptr); }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||
|
||||
template <typename T>
|
||||
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T>
|
||||
{
|
||||
static void release(T *ptr) { Foreground::delete_(ptr); }
|
||||
static void release(T *ptr) { js_delete(ptr); }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Note lack of ; in JSRuntime below. This is intentional so "calling" this
|
||||
* looks "normal".
|
||||
*/
|
||||
#define JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR \
|
||||
friend class js::OffTheBooks;\
|
||||
friend class js::Foreground;\
|
||||
friend class js::UnwantedForeground;\
|
||||
friend struct ::JSContext;\
|
||||
friend struct ::JSRuntime
|
||||
|
||||
/*
|
||||
* The following classes are designed to cause assertions to detect
|
||||
* inadvertent use of guard objects as temporaries. In other words,
|
||||
|
|
|
@ -180,7 +180,7 @@ struct VectorImpl<T, N, AP, true>
|
|||
template <class T, size_t N, class AllocPolicy>
|
||||
class Vector : private AllocPolicy
|
||||
{
|
||||
typedef typename tl::StaticAssert<tl::IsRelocatableHeapType<T>::result>::result _;
|
||||
// typedef typename tl::StaticAssert<!tl::IsPostBarrieredType<T>::result>::result _;
|
||||
|
||||
/* utilities */
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
8a03481ec145a3a0e532637dd52bf80605b7a713
|
||||
4f78a759104eea6e7790c03ce0130299eeaa3968
|
|
@ -1,399 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 jsatom_h___
|
||||
#define jsatom_h___
|
||||
|
||||
#include <stddef.h>
|
||||
#include "jsversion.h"
|
||||
#include "jsalloc.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jslock.h"
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
struct JSIdArray {
|
||||
int length;
|
||||
js::HeapId vector[1]; /* actually, length jsid words */
|
||||
};
|
||||
|
||||
/* Engine-internal extensions of jsid */
|
||||
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
JSID_FROM_BITS(size_t bits)
|
||||
{
|
||||
jsid id;
|
||||
JSID_BITS(id) = bits;
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must not be used on atoms that are representable as integer jsids.
|
||||
* Prefer NameToId or AtomToId over this function:
|
||||
*
|
||||
* A PropertyName is an atom that does not contain an integer in the range
|
||||
* [0, UINT32_MAX]. However, jsid can only hold an integer in the range
|
||||
* [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of
|
||||
* integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
|
||||
* the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most
|
||||
* cases when creating a jsid, code does not have to care about this corner
|
||||
* case because:
|
||||
*
|
||||
* - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
|
||||
* integer atoms representable as integer jsids, and does this conversion.
|
||||
*
|
||||
* - When given a PropertyName*, NameToId can be used which which does not need
|
||||
* to do any dynamic checks.
|
||||
*
|
||||
* Thus, it is only the rare third case which needs this function, which
|
||||
* handles any JSAtom* that is known not to be representable with an int jsid.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
|
||||
{
|
||||
JS_ASSERT(((size_t)atom & 0x7) == 0);
|
||||
jsid id = JSID_FROM_BITS((size_t)atom);
|
||||
JS_ASSERT(id == INTERNED_STRING_TO_JSID(NULL, (JSString*)atom));
|
||||
return id;
|
||||
}
|
||||
|
||||
/* All strings stored in jsids are atomized, but are not necessarily property names. */
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id)
|
||||
{
|
||||
return JSID_IS_STRING(id);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id, JSAtom *atom)
|
||||
{
|
||||
return id == JSID_FROM_BITS((size_t)atom);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSAtom *
|
||||
JSID_TO_ATOM(jsid id)
|
||||
{
|
||||
return (JSAtom *)JSID_TO_STRING(id);
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(js::HashNumber) == 4);
|
||||
JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE js::HashNumber
|
||||
HashId(jsid id)
|
||||
{
|
||||
return HashGeneric(JSID_BITS(id));
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE Value
|
||||
IdToValue(jsid id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
return StringValue(JSID_TO_STRING(id));
|
||||
if (JS_LIKELY(JSID_IS_INT(id)))
|
||||
return Int32Value(JSID_TO_INT(id));
|
||||
if (JS_LIKELY(JSID_IS_OBJECT(id)))
|
||||
return ObjectValue(*JSID_TO_OBJECT(id));
|
||||
JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id) || JSID_IS_VOID(id));
|
||||
return UndefinedValue();
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE jsval
|
||||
IdToJsval(jsid id)
|
||||
{
|
||||
return IdToValue(id);
|
||||
}
|
||||
|
||||
template<>
|
||||
struct DefaultHasher<jsid>
|
||||
{
|
||||
typedef jsid Lookup;
|
||||
static HashNumber hash(const Lookup &l) {
|
||||
return HashNumber(JSID_BITS(l));
|
||||
}
|
||||
static bool match(const jsid &id, const Lookup &l) {
|
||||
return id == l;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a printable, lossless char[] representation of a string-type atom.
|
||||
* The lifetime of the result matches the lifetime of bytes.
|
||||
*/
|
||||
extern const char *
|
||||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes);
|
||||
|
||||
namespace js {
|
||||
|
||||
/* Compute a hash function from chars/length. */
|
||||
inline uint32_t
|
||||
HashChars(const jschar *chars, size_t length)
|
||||
{
|
||||
uint32_t h = 0;
|
||||
for (; length; chars++, length--)
|
||||
h = JS_ROTATE_LEFT32(h, 4) ^ *chars;
|
||||
return h;
|
||||
}
|
||||
|
||||
class AtomStateEntry
|
||||
{
|
||||
uintptr_t bits;
|
||||
|
||||
static const uintptr_t NO_TAG_MASK = uintptr_t(-1) - 1;
|
||||
|
||||
public:
|
||||
AtomStateEntry() : bits(0) {}
|
||||
AtomStateEntry(const AtomStateEntry &other) : bits(other.bits) {}
|
||||
AtomStateEntry(JSAtom *ptr, bool tagged)
|
||||
: bits(uintptr_t(ptr) | uintptr_t(tagged))
|
||||
{
|
||||
JS_ASSERT((uintptr_t(ptr) & 0x1) == 0);
|
||||
}
|
||||
|
||||
bool isTagged() const {
|
||||
return bits & 0x1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-branching code sequence. Note that the const_cast is safe because
|
||||
* the hash function doesn't consider the tag to be a portion of the key.
|
||||
*/
|
||||
void setTagged(bool enabled) const {
|
||||
const_cast<AtomStateEntry *>(this)->bits |= uintptr_t(enabled);
|
||||
}
|
||||
|
||||
JSAtom *asPtr() const;
|
||||
};
|
||||
|
||||
struct AtomHasher
|
||||
{
|
||||
struct Lookup
|
||||
{
|
||||
const jschar *chars;
|
||||
size_t length;
|
||||
const JSAtom *atom; /* Optional. */
|
||||
|
||||
Lookup(const jschar *chars, size_t length) : chars(chars), length(length), atom(NULL) {}
|
||||
inline Lookup(const JSAtom *atom);
|
||||
};
|
||||
|
||||
static HashNumber hash(const Lookup &l) { return HashChars(l.chars, l.length); }
|
||||
static inline bool match(const AtomStateEntry &entry, const Lookup &lookup);
|
||||
};
|
||||
|
||||
typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet;
|
||||
|
||||
/*
|
||||
* On encodings:
|
||||
*
|
||||
* - Some string functions have an optional FlationCoding argument that allow
|
||||
* the caller to force CESU-8 encoding handling.
|
||||
* - Functions that don't take a FlationCoding base their NormalEncoding
|
||||
* behavior on the js_CStringsAreUTF8 value. NormalEncoding is either raw
|
||||
* (simple zero-extension) or UTF-8 depending on js_CStringsAreUTF8.
|
||||
* - Functions that explicitly state their encoding do not use the
|
||||
* js_CStringsAreUTF8 value.
|
||||
*
|
||||
* CESU-8 (Compatibility Encoding Scheme for UTF-16: 8-bit) is a variant of
|
||||
* UTF-8 that allows us to store any wide character string as a narrow
|
||||
* character string. For strings containing mostly ascii, it saves space.
|
||||
* http://www.unicode.org/reports/tr26/
|
||||
*/
|
||||
|
||||
enum FlationCoding
|
||||
{
|
||||
NormalEncoding,
|
||||
CESU8Encoding
|
||||
};
|
||||
|
||||
class PropertyName;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSAtomState
|
||||
{
|
||||
js::AtomSet atoms;
|
||||
|
||||
/*
|
||||
* From this point until the end of struct definition the struct must
|
||||
* contain only js::PropertyName fields. We use this to access the storage
|
||||
* occupied by the common atoms in js_FinishCommonAtoms.
|
||||
*
|
||||
* js_common_atom_names defined in jsatom.cpp contains C strings for atoms
|
||||
* in the order of atom fields here. Therefore you must update that array
|
||||
* if you change member order here.
|
||||
*/
|
||||
|
||||
/* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */
|
||||
js::PropertyName *emptyAtom;
|
||||
|
||||
/*
|
||||
* Literal value and type names.
|
||||
* NB: booleanAtoms must come right before typeAtoms!
|
||||
*/
|
||||
js::PropertyName *booleanAtoms[2];
|
||||
js::PropertyName *typeAtoms[JSTYPE_LIMIT];
|
||||
js::PropertyName *nullAtom;
|
||||
|
||||
/* Standard class constructor or prototype names. */
|
||||
js::PropertyName *classAtoms[JSProto_LIMIT];
|
||||
|
||||
/* Various built-in or commonly-used atoms, pinned on first context. */
|
||||
#define DEFINE_ATOM(id, text) js::PropertyName *id##Atom;
|
||||
#define DEFINE_PROTOTYPE_ATOM(id) js::PropertyName *id##Atom;
|
||||
#define DEFINE_KEYWORD_ATOM(id) js::PropertyName *id##Atom;
|
||||
#include "jsatom.tbl"
|
||||
#undef DEFINE_ATOM
|
||||
#undef DEFINE_PROTOTYPE_ATOM
|
||||
#undef DEFINE_KEYWORD_ATOM
|
||||
|
||||
static const size_t commonAtomsOffset;
|
||||
|
||||
void junkAtoms() {
|
||||
#ifdef DEBUG
|
||||
memset(commonAtomsStart(), JS_FREE_PATTERN, sizeof(*this) - commonAtomsOffset);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSAtom **commonAtomsStart() {
|
||||
return reinterpret_cast<JSAtom **>(&emptyAtom);
|
||||
}
|
||||
|
||||
void checkStaticInvariants();
|
||||
};
|
||||
|
||||
extern bool
|
||||
AtomIsInterned(JSContext *cx, JSAtom *atom);
|
||||
|
||||
#define ATOM(name) js::HandlePropertyName::fromMarkedLocation(&cx->runtime->atomState.name##Atom)
|
||||
|
||||
#define COMMON_ATOM_INDEX(name) \
|
||||
((offsetof(JSAtomState, name##Atom) - JSAtomState::commonAtomsOffset) \
|
||||
/ sizeof(JSAtom*))
|
||||
#define COMMON_TYPE_ATOM_INDEX(type) \
|
||||
((offsetof(JSAtomState, typeAtoms[type]) - JSAtomState::commonAtomsOffset)\
|
||||
/ sizeof(JSAtom*))
|
||||
|
||||
#define NAME_OFFSET(name) offsetof(JSAtomState, name##Atom)
|
||||
#define OFFSET_TO_NAME(rt,off) (*(js::PropertyName **)((char*)&(rt)->atomState + (off)))
|
||||
#define CLASS_NAME_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name])
|
||||
#define CLASS_NAME(cx,name) ((cx)->runtime->atomState.classAtoms[JSProto_##name])
|
||||
|
||||
extern const char *const js_common_atom_names[];
|
||||
extern const size_t js_common_atom_count;
|
||||
|
||||
/*
|
||||
* Macros to access C strings for JSType and boolean literals.
|
||||
*/
|
||||
#define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + (type)])
|
||||
#define JS_TYPE_STR(type) (js_common_atom_names[1 + 2 + (type)])
|
||||
|
||||
/* Type names. */
|
||||
extern const char js_object_str[];
|
||||
extern const char js_undefined_str[];
|
||||
|
||||
/* Well-known predefined C strings. */
|
||||
#define JS_PROTO(name,code,init) extern const char js_##name##_str[];
|
||||
#include "jsproto.tbl"
|
||||
#undef JS_PROTO
|
||||
|
||||
#define DEFINE_ATOM(id, text) extern const char js_##id##_str[];
|
||||
#define DEFINE_PROTOTYPE_ATOM(id)
|
||||
#define DEFINE_KEYWORD_ATOM(id)
|
||||
#include "jsatom.tbl"
|
||||
#undef DEFINE_ATOM
|
||||
#undef DEFINE_PROTOTYPE_ATOM
|
||||
#undef DEFINE_KEYWORD_ATOM
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
extern const char js_close_str[];
|
||||
extern const char js_send_str[];
|
||||
#endif
|
||||
|
||||
/* Constant strings that are not atomized. */
|
||||
extern const char js_getter_str[];
|
||||
extern const char js_setter_str[];
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Initialize atom state. Return true on success, false on failure to allocate
|
||||
* memory. The caller must zero rt->atomState before calling this function and
|
||||
* only call it after js_InitGC successfully returns.
|
||||
*/
|
||||
extern JSBool
|
||||
InitAtomState(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Free and clear atom state including any interned string atoms. This
|
||||
* function must be called before js_FinishGC.
|
||||
*/
|
||||
extern void
|
||||
FinishAtomState(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Atom tracing and garbage collection hooks.
|
||||
*/
|
||||
extern void
|
||||
MarkAtomState(JSTracer *trc);
|
||||
|
||||
extern void
|
||||
SweepAtomState(JSRuntime *rt);
|
||||
|
||||
extern bool
|
||||
InitCommonAtoms(JSContext *cx);
|
||||
|
||||
extern void
|
||||
FinishCommonAtoms(JSRuntime *rt);
|
||||
|
||||
/* N.B. must correspond to boolean tagging behavior. */
|
||||
enum InternBehavior
|
||||
{
|
||||
DoNotInternAtom = false,
|
||||
InternAtom = true
|
||||
};
|
||||
|
||||
extern JSAtom *
|
||||
Atomize(JSContext *cx, const char *bytes, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom,
|
||||
js::FlationCoding fc = js::NormalEncoding);
|
||||
|
||||
extern JSAtom *
|
||||
AtomizeChars(JSContext *cx, const jschar *chars, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
extern JSAtom *
|
||||
AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
inline JSAtom *
|
||||
ToAtom(JSContext *cx, const js::Value &v);
|
||||
|
||||
bool
|
||||
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
|
||||
jsid *idp, MutableHandleValue vp);
|
||||
|
||||
inline bool
|
||||
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp)
|
||||
{
|
||||
RootedValue dummy(cx);
|
||||
return InternNonIntElementId(cx, obj, idval, idp, &dummy);
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRAtom(XDRState<mode> *xdr, JSAtom **atomp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsatom_h___ */
|
|
@ -1,154 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 ft=c: */
|
||||
/* 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/. */
|
||||
|
||||
/*
|
||||
* Declare pre-interned atoms for easy use by SpiderMonkey's C++ code.
|
||||
* These entries define two things, where <id> is the macros' first
|
||||
* argument:
|
||||
*
|
||||
* - js::PropertyName *<id>Atom: a member of JSAtomState pointing to the
|
||||
* atom itself. Usually accessed as cx->runtime->atomState.<id>Atom.
|
||||
*
|
||||
* - const char js_<id>_str[]: a global within SpiderMonkey, holding the
|
||||
* atom's name. Some macros skip this, because it's already defined
|
||||
* elsewhere.
|
||||
*
|
||||
* DEFINE_ATOM(id, name)
|
||||
* Define an atom whose JavaScript string's value is |name|.
|
||||
*
|
||||
* DEFINE_PROTOTYPE_ATOM(id)
|
||||
* Define an atom whose name is the same as one of those defined in
|
||||
* jsproto.tbl. The code that processes that has already declared and
|
||||
* defined the js_<id>_str global, so this defines only the JSAtomState
|
||||
* member.
|
||||
*
|
||||
* DEFINE_KEYWORD_ATOM(id)
|
||||
* Define an atom whose name is the same as one of those defined in
|
||||
* jskeyword.tbl. The code that processes that has already declared and
|
||||
* defined the js_<id>_str global, so this defines only the JSAtomState
|
||||
* member.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
DEFINE_ATOM(anonymous, "anonymous")
|
||||
DEFINE_ATOM(apply, "apply")
|
||||
DEFINE_ATOM(arguments, "arguments")
|
||||
DEFINE_ATOM(arity, "arity")
|
||||
DEFINE_ATOM(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT")
|
||||
DEFINE_ATOM(call, "call")
|
||||
DEFINE_ATOM(callee, "callee")
|
||||
DEFINE_ATOM(caller, "caller")
|
||||
DEFINE_ATOM(classPrototype, "prototype")
|
||||
DEFINE_ATOM(columnNumber, "columnNumber")
|
||||
DEFINE_ATOM(constructor, "constructor")
|
||||
DEFINE_ATOM(each, "each")
|
||||
DEFINE_ATOM(eval, "eval")
|
||||
DEFINE_ATOM(fileName, "fileName")
|
||||
DEFINE_ATOM(get, "get")
|
||||
DEFINE_ATOM(global, "global")
|
||||
DEFINE_ATOM(ignoreCase, "ignoreCase")
|
||||
DEFINE_ATOM(index, "index")
|
||||
DEFINE_ATOM(input, "input")
|
||||
DEFINE_ATOM(toISOString, "toISOString")
|
||||
DEFINE_ATOM(iterator, "iterator")
|
||||
DEFINE_ATOM(iteratorIntrinsic, "__iterator__")
|
||||
DEFINE_ATOM(join, "join")
|
||||
DEFINE_ATOM(lastIndex, "lastIndex")
|
||||
DEFINE_ATOM(length, "length")
|
||||
DEFINE_ATOM(lineNumber, "lineNumber")
|
||||
DEFINE_ATOM(message, "message")
|
||||
DEFINE_ATOM(multiline, "multiline")
|
||||
DEFINE_ATOM(name, "name")
|
||||
DEFINE_ATOM(next, "next")
|
||||
DEFINE_ATOM(noSuchMethod, "__noSuchMethod__")
|
||||
DEFINE_ATOM(objectNull, "[object Null]")
|
||||
DEFINE_ATOM(objectUndefined, "[object Undefined]")
|
||||
DEFINE_ATOM(of, "of")
|
||||
DEFINE_ATOM(proto, "__proto__")
|
||||
DEFINE_ATOM(set, "set")
|
||||
DEFINE_ATOM(source, "source")
|
||||
DEFINE_ATOM(stack, "stack")
|
||||
DEFINE_ATOM(sticky, "sticky")
|
||||
DEFINE_ATOM(toGMTString, "toGMTString")
|
||||
DEFINE_ATOM(toLocaleString, "toLocaleString")
|
||||
DEFINE_ATOM(toSource, "toSource")
|
||||
DEFINE_ATOM(toString, "toString")
|
||||
DEFINE_ATOM(toUTCString, "toUTCString")
|
||||
DEFINE_ATOM(valueOf, "valueOf")
|
||||
DEFINE_ATOM(toJSON, "toJSON")
|
||||
DEFINE_ATOM(void0, "(void 0)")
|
||||
DEFINE_ATOM(enumerable, "enumerable")
|
||||
DEFINE_ATOM(configurable, "configurable")
|
||||
DEFINE_ATOM(writable, "writable")
|
||||
DEFINE_ATOM(value, "value")
|
||||
DEFINE_ATOM(test, "test")
|
||||
DEFINE_ATOM(useStrict, "use strict")
|
||||
DEFINE_ATOM(loc, "loc")
|
||||
DEFINE_ATOM(line, "line")
|
||||
DEFINE_ATOM(Infinity, "Infinity")
|
||||
DEFINE_ATOM(NaN, "NaN")
|
||||
DEFINE_ATOM(builder, "builder")
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
DEFINE_ATOM(etago, "</")
|
||||
DEFINE_ATOM(namespace, "namespace")
|
||||
DEFINE_ATOM(ptagc, "/>")
|
||||
DEFINE_ATOM(qualifier, "::")
|
||||
DEFINE_ATOM(space, " ")
|
||||
DEFINE_ATOM(stago, "<")
|
||||
DEFINE_ATOM(star, "*")
|
||||
DEFINE_ATOM(starQualifier, "*::")
|
||||
DEFINE_ATOM(tagc, ">")
|
||||
DEFINE_ATOM(xml, "xml")
|
||||
DEFINE_ATOM(functionNamespaceURI, "@mozilla.org/js/function")
|
||||
#endif
|
||||
|
||||
DEFINE_PROTOTYPE_ATOM(Proxy)
|
||||
DEFINE_ATOM(getOwnPropertyDescriptor, "getOwnPropertyDescriptor")
|
||||
DEFINE_ATOM(getPropertyDescriptor, "getPropertyDescriptor")
|
||||
DEFINE_ATOM(defineProperty, "defineProperty")
|
||||
DEFINE_KEYWORD_ATOM(delete)
|
||||
DEFINE_ATOM(getOwnPropertyNames, "getOwnPropertyNames")
|
||||
DEFINE_ATOM(enumerate, "enumerate")
|
||||
DEFINE_ATOM(fix, "fix")
|
||||
DEFINE_ATOM(has, "has")
|
||||
DEFINE_ATOM(hasOwn, "hasOwn")
|
||||
DEFINE_ATOM(keys, "keys")
|
||||
DEFINE_ATOM(iterate, "iterate")
|
||||
DEFINE_PROTOTYPE_ATOM(WeakMap)
|
||||
DEFINE_ATOM(buffer, "buffer")
|
||||
DEFINE_ATOM(byteLength, "byteLength")
|
||||
DEFINE_ATOM(byteOffset, "byteOffset")
|
||||
DEFINE_ATOM(shape, "shape")
|
||||
DEFINE_KEYWORD_ATOM(return)
|
||||
DEFINE_KEYWORD_ATOM(throw)
|
||||
DEFINE_ATOM(url, "url")
|
||||
DEFINE_ATOM(innermost, "innermost")
|
||||
|
||||
DEFINE_ATOM(XMLList, "XMLList")
|
||||
DEFINE_ATOM(decodeURI, "decodeURI")
|
||||
DEFINE_ATOM(decodeURIComponent, "decodeURIComponent")
|
||||
DEFINE_ATOM(defineGetter, "__defineGetter__")
|
||||
DEFINE_ATOM(defineSetter, "__defineSetter__")
|
||||
DEFINE_ATOM(encodeURI, "encodeURI")
|
||||
DEFINE_ATOM(encodeURIComponent, "encodeURIComponent")
|
||||
DEFINE_ATOM(escape, "escape")
|
||||
DEFINE_ATOM(hasOwnProperty, "hasOwnProperty")
|
||||
DEFINE_ATOM(isFinite, "isFinite")
|
||||
DEFINE_ATOM(isNaN, "isNaN")
|
||||
DEFINE_ATOM(isPrototypeOf, "isPrototypeOf")
|
||||
DEFINE_ATOM(isXMLName, "isXMLName")
|
||||
DEFINE_ATOM(lookupGetter, "__lookupGetter__")
|
||||
DEFINE_ATOM(lookupSetter, "__lookupSetter__")
|
||||
DEFINE_ATOM(parseFloat, "parseFloat")
|
||||
DEFINE_ATOM(parseInt, "parseInt")
|
||||
DEFINE_ATOM(propertyIsEnumerable, "propertyIsEnumerable")
|
||||
DEFINE_ATOM(unescape, "unescape")
|
||||
DEFINE_ATOM(uneval, "uneval")
|
||||
DEFINE_ATOM(unwatch, "unwatch")
|
||||
DEFINE_ATOM(watch, "watch")
|
||||
DEFINE_ATOM(_CallFunction, "_CallFunction")
|
|
@ -210,9 +210,7 @@ typedef JSType
|
|||
typedef JSObject *
|
||||
(* ObjectOp)(JSContext *cx, HandleObject obj);
|
||||
typedef void
|
||||
(* ClearOp)(JSContext *cx, HandleObject obj);
|
||||
typedef void
|
||||
(* FinalizeOp)(FreeOp *fop, JSObject *obj);
|
||||
(* FinalizeOp)(FreeOp *fop, RawObject obj);
|
||||
|
||||
#define JS_CLASS_MEMBERS \
|
||||
const char *name; \
|
||||
|
@ -308,13 +306,12 @@ struct ObjectOps
|
|||
JSNewEnumerateOp enumerate;
|
||||
TypeOfOp typeOf;
|
||||
ObjectOp thisObject;
|
||||
ClearOp clear;
|
||||
};
|
||||
|
||||
#define JS_NULL_OBJECT_OPS \
|
||||
{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \
|
||||
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \
|
||||
NULL,NULL,NULL,NULL,NULL}
|
||||
NULL,NULL,NULL,NULL}
|
||||
|
||||
struct Class
|
||||
{
|
||||
|
@ -397,10 +394,6 @@ ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
|
|||
inline bool
|
||||
IsObjectWithClass(const Value &v, ESClassValue classValue, JSContext *cx);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
inline bool
|
||||
IsPoisonedSpecialId(js::SpecialId iden)
|
||||
{
|
||||
|
@ -409,14 +402,14 @@ IsPoisonedSpecialId(js::SpecialId iden)
|
|||
return false;
|
||||
}
|
||||
|
||||
template <> struct RootMethods<js::SpecialId>
|
||||
template <> struct RootMethods<SpecialId>
|
||||
{
|
||||
static js::SpecialId initial() { return js::SpecialId(); }
|
||||
static SpecialId initial() { return SpecialId(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(js::SpecialId id) { return IsPoisonedSpecialId(id); }
|
||||
static bool poisoned(SpecialId id) { return IsPoisonedSpecialId(id); }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -13,54 +13,49 @@
|
|||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
|
||||
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallStackFrame(JSContext *cx, JSStackFrame *target);
|
||||
|
||||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#if defined(__cplusplus)
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterScriptCompartment)
|
||||
struct FrameDescription
|
||||
{
|
||||
protected:
|
||||
JSCrossCompartmentCall *call;
|
||||
|
||||
public:
|
||||
AutoEnterScriptCompartment() : call(NULL) {}
|
||||
|
||||
bool enter(JSContext *cx, JSScript *target);
|
||||
|
||||
bool entered() const { return call != NULL; }
|
||||
|
||||
~AutoEnterScriptCompartment() {
|
||||
if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
}
|
||||
JSScript *script;
|
||||
unsigned lineno;
|
||||
JSFunction *fun;
|
||||
};
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterFrameCompartment) : public AutoEnterScriptCompartment
|
||||
struct StackDescription
|
||||
{
|
||||
public:
|
||||
bool enter(JSContext *cx, JSStackFrame *target);
|
||||
unsigned nframes;
|
||||
FrameDescription *frames;
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
extern JS_PUBLIC_API(StackDescription *)
|
||||
DescribeStack(JSContext *cx, unsigned maxFrames);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern JS_PUBLIC_API(void)
|
||||
FreeStackDescription(JSContext *cx, StackDescription *desc);
|
||||
|
||||
extern JS_PUBLIC_API(char *)
|
||||
FormatStackDump(JSContext *cx, char *buf,
|
||||
JSBool showArgs, JSBool showLocals,
|
||||
JSBool showThisProps);
|
||||
|
||||
}
|
||||
|
||||
# ifdef DEBUG
|
||||
JS_FRIEND_API(void) js_DumpValue(const js::Value &val);
|
||||
JS_FRIEND_API(void) js_DumpId(jsid id);
|
||||
JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = NULL);
|
||||
# endif
|
||||
#endif
|
||||
JS_FRIEND_API(void) js_DumpBacktrace(JSContext *cx);
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpBacktrace(JSContext *cx);
|
||||
|
||||
extern JS_PUBLIC_API(JSCompartment *)
|
||||
JS_EnterCompartmentOfScript(JSContext *cx, JSScript *target);
|
||||
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, unsigned indent);
|
||||
|
@ -200,14 +195,16 @@ extern JS_PUBLIC_API(JSPrincipals *)
|
|||
JS_GetScriptOriginPrincipals(JSScript *script);
|
||||
|
||||
/*
|
||||
* Stack Frame Iterator
|
||||
* This function does not work when IonMonkey is active. It remains for legacy
|
||||
* code: caps/principal clamping, which will be removed shortly after
|
||||
* compartment-per-global, and jsd, which can only be used when IonMonkey is
|
||||
* disabled.
|
||||
*
|
||||
* Used to iterate through the JS stack frames to extract
|
||||
* information from the frames.
|
||||
* To find the calling script and line number, use JS_DescribeSciptedCaller.
|
||||
* To summarize the call stack, use JS::DescribeStack.
|
||||
*/
|
||||
|
||||
extern JS_PUBLIC_API(JSStackFrame *)
|
||||
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp);
|
||||
JS_BrokenFrameIterator(JSContext *cx, JSStackFrame **iteratorp);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_GetFrameScript(JSContext *cx, JSStackFrame *fp);
|
||||
|
@ -219,7 +216,7 @@ extern JS_PUBLIC_API(void *)
|
|||
JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation);
|
||||
JS_SetTopFrameAnnotation(JSContext *cx, void *annotation);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp);
|
||||
|
@ -295,6 +292,12 @@ 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);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -397,48 +400,6 @@ js_RevertVersion(JSContext *cx);
|
|||
extern JS_PUBLIC_API(const JSDebugHooks *)
|
||||
JS_GetGlobalDebugHooks(JSRuntime *rt);
|
||||
|
||||
/**
|
||||
* Start any profilers that are available and have been configured on for this
|
||||
* platform. This is NOT thread safe.
|
||||
*
|
||||
* The profileName is used by some profilers to describe the current profiling
|
||||
* run. It may be used for part of the filename of the output, but the
|
||||
* specifics depend on the profiler. Many profilers will ignore it. Passing in
|
||||
* NULL is legal; some profilers may use it to output to stdout or similar.
|
||||
*
|
||||
* Returns true if no profilers fail to start.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_StartProfiling(const char *profileName);
|
||||
|
||||
/**
|
||||
* Stop any profilers that were previously started with JS_StartProfiling.
|
||||
* Returns true if no profilers fail to stop.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_StopProfiling(const char *profileName);
|
||||
|
||||
/**
|
||||
* Write the current profile data to the given file, if applicable to whatever
|
||||
* profiler is being used.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_DumpProfile(const char *outfile, const char *profileName);
|
||||
|
||||
/**
|
||||
* Pause currently active profilers (only supported by some profilers). Returns
|
||||
* whether any profilers failed to pause. (Profilers that do not support
|
||||
* pause/resume do not count.)
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_PauseProfilers(const char *profileName);
|
||||
|
||||
/**
|
||||
* Resume suspended profilers
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_ResumeProfilers(const char *profileName);
|
||||
|
||||
/**
|
||||
* Add various profiling-related functions as properties of the given object.
|
||||
*/
|
||||
|
@ -449,53 +410,6 @@ JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj);
|
|||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_DefineDebuggerObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
/**
|
||||
* The profiling API calls are not able to report errors, so they use a
|
||||
* thread-unsafe global memory buffer to hold the last error encountered. This
|
||||
* should only be called after something returns false.
|
||||
*/
|
||||
JS_PUBLIC_API(const char *)
|
||||
JS_UnsafeGetLastProfilingError();
|
||||
|
||||
#ifdef MOZ_CALLGRIND
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StopCallgrind();
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StartCallgrind();
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_DumpCallgrind(const char *outfile);
|
||||
|
||||
#endif /* MOZ_CALLGRIND */
|
||||
|
||||
#ifdef MOZ_VTUNE
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_StartVtune(const char *profileName);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_StopVtune();
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_PauseVtune();
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_ResumeVtune();
|
||||
|
||||
#endif /* MOZ_VTUNE */
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StartPerf();
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StopPerf();
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_DumpBytecode(JSContext *cx, JSScript *script);
|
||||
|
||||
|
|
|
@ -151,7 +151,8 @@ 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::Value *statep, jsid *idp);
|
||||
JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
|
||||
js::MutableHandleValue statep, js::MutableHandleId idp);
|
||||
|
||||
struct JSFunctionSpecWithHelp {
|
||||
const char *name;
|
||||
|
@ -183,25 +184,6 @@ JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook);
|
|||
|
||||
namespace js {
|
||||
|
||||
struct RuntimeFriendFields {
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
* as possible.
|
||||
*/
|
||||
volatile int32_t interrupt;
|
||||
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit;
|
||||
|
||||
RuntimeFriendFields()
|
||||
: interrupt(0),
|
||||
nativeStackLimit(0) { }
|
||||
|
||||
static const RuntimeFriendFields *get(const JSRuntime *rt) {
|
||||
return reinterpret_cast<const RuntimeFriendFields *>(rt);
|
||||
}
|
||||
};
|
||||
|
||||
inline JSRuntime *
|
||||
GetRuntime(const JSContext *cx)
|
||||
{
|
||||
|
@ -277,9 +259,6 @@ TraceWeakMaps(WeakMapTracer *trc);
|
|||
extern JS_FRIEND_API(bool)
|
||||
GCThingIsMarkedGray(void *thing);
|
||||
|
||||
extern JS_FRIEND_API(JSCompartment*)
|
||||
GetGCThingCompartment(void *thing);
|
||||
|
||||
typedef void
|
||||
(GCThingCallback)(void *closure, void *gcthing);
|
||||
|
||||
|
@ -397,6 +376,18 @@ NotifyAnimationActivity(RawObject obj);
|
|||
JS_FRIEND_API(bool)
|
||||
IsOriginalScriptFunction(JSFunction *fun);
|
||||
|
||||
/*
|
||||
* Return the outermost enclosing function (script) of the scripted caller.
|
||||
* This function returns NULL in several cases:
|
||||
* - no script is running on the context
|
||||
* - the caller is in global or eval code
|
||||
* In particular, this function will "stop" its outermost search at eval() and
|
||||
* thus it will really return the outermost enclosing function *since the
|
||||
* innermost eval*.
|
||||
*/
|
||||
JS_FRIEND_API(JSScript *)
|
||||
GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx);
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
|
||||
unsigned nargs, unsigned attrs);
|
||||
|
@ -421,10 +412,19 @@ GetFunctionNativeReserved(RawObject fun, size_t which);
|
|||
JS_FRIEND_API(void)
|
||||
SetFunctionNativeReserved(RawObject fun, size_t which, const Value &val);
|
||||
|
||||
inline JSObject *
|
||||
GetObjectProto(RawObject obj)
|
||||
inline bool
|
||||
GetObjectProto(JSContext *cx, JSObject *obj, JSObject **proto)
|
||||
{
|
||||
return reinterpret_cast<const shadow::Object*>(obj)->type->proto;
|
||||
js::Class *clasp = GetObjectClass(obj);
|
||||
if (clasp == &js::ObjectProxyClass ||
|
||||
clasp == &js::OuterWindowProxyClass ||
|
||||
clasp == &js::FunctionProxyClass)
|
||||
{
|
||||
return JS_GetPrototype(cx, obj, proto);
|
||||
}
|
||||
|
||||
*proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void *
|
||||
|
@ -636,8 +636,8 @@ ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip);
|
|||
JS_FRIEND_API(void *)
|
||||
GetOwnerThread(const JSContext *cx);
|
||||
|
||||
JS_FRIEND_API(unsigned)
|
||||
GetContextOutstandingRequests(const JSContext *cx);
|
||||
JS_FRIEND_API(bool)
|
||||
ContextHasOutstandingRequests(const JSContext *cx);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(JSCompartment *)
|
||||
|
@ -677,9 +677,6 @@ typedef Vector<JSCompartment*, 0, SystemAllocPolicy> CompartmentVector;
|
|||
extern JS_FRIEND_API(const CompartmentVector&)
|
||||
GetRuntimeCompartments(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(size_t)
|
||||
SizeOfJSContext();
|
||||
|
||||
#define GCREASONS(D) \
|
||||
/* Reasons internal to the JS engine */ \
|
||||
D(API) \
|
||||
|
@ -836,6 +833,9 @@ NotifyDidPaint(JSRuntime *rt);
|
|||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalGCEnabled(JSRuntime *rt);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableIncrementalGC(JSRuntime *rt);
|
||||
|
||||
|
@ -988,10 +988,10 @@ uint32_t GetListBaseExpandoSlot();
|
|||
* out-of-band for js_DateGet*)
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_DateIsValid(JSContext *cx, JSObject* obj);
|
||||
js_DateIsValid(JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(double)
|
||||
js_DateGetMsecSinceEpoch(JSContext *cx, JSRawObject obj);
|
||||
js_DateGetMsecSinceEpoch(JSRawObject obj);
|
||||
|
||||
/* Implemented in jscntxt.cpp. */
|
||||
|
||||
|
@ -1051,6 +1051,8 @@ typedef uint32_t JSArrayBufferViewType;
|
|||
|
||||
/*
|
||||
* Create a new typed array with nelements elements.
|
||||
*
|
||||
* These functions (except the WithBuffer variants) fill in the array with zeros.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
|
@ -1221,7 +1223,7 @@ JS_GetObjectAsArrayBuffer(JSContext *cx, JSObject *obj, uint32_t *length, uint8_
|
|||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSArrayBufferViewType)
|
||||
JS_GetTypedArrayType(JSObject *obj, JSContext *cx);
|
||||
JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
|
||||
|
@ -1230,7 +1232,7 @@ JS_GetTypedArrayType(JSObject *obj, JSContext *cx);
|
|||
* accessor JSAPI calls defined below.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsArrayBufferObject(JSObject *obj, JSContext *cx);
|
||||
JS_IsArrayBufferObject(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return the available byte length of an array buffer.
|
||||
|
@ -1241,11 +1243,12 @@ JS_IsArrayBufferObject(JSObject *obj, JSContext *cx);
|
|||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *cx);
|
||||
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return a pointer to an array buffer's data. The buffer is still owned by the
|
||||
* array buffer object, and should not be modified on another thread.
|
||||
* array buffer object, and should not be modified on another thread. The
|
||||
* returned pointer is stable across GCs.
|
||||
*
|
||||
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
|
||||
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
|
||||
|
@ -1253,7 +1256,7 @@ JS_GetArrayBufferByteLength(JSObject *obj, JSContext *cx);
|
|||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetArrayBufferData(JSObject *obj, JSContext *cx);
|
||||
JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return the number of elements in a typed array.
|
||||
|
@ -1315,30 +1318,30 @@ JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx);
|
|||
*/
|
||||
|
||||
extern JS_FRIEND_API(int8_t *)
|
||||
JS_GetInt8ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(int16_t *)
|
||||
JS_GetInt16ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint16_t *)
|
||||
JS_GetUint16ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(int32_t *)
|
||||
JS_GetInt32ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint32_t *)
|
||||
JS_GetUint32ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(float *)
|
||||
JS_GetFloat32ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(double *)
|
||||
JS_GetFloat64ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
|
||||
* versions when possible.
|
||||
*/
|
||||
extern JS_FRIEND_API(void *)
|
||||
JS_GetArrayBufferViewData(JSObject *obj, JSContext *cx);
|
||||
JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Check whether obj supports JS_GetDataView* APIs. Note that this may fail and
|
||||
|
@ -1358,7 +1361,7 @@ JS_IsDataViewObject(JSContext *cx, JSObject *obj, JSBool *isDataView);
|
|||
* unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetDataViewByteOffset(JSObject *obj, JSContext *cx);
|
||||
JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return the byte length of a data view.
|
||||
|
@ -1369,7 +1372,7 @@ JS_GetDataViewByteOffset(JSObject *obj, JSContext *cx);
|
|||
* unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetDataViewByteLength(JSObject *obj, JSContext *cx);
|
||||
JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return a pointer to the beginning of the data referenced by a DataView.
|
||||
|
@ -1380,7 +1383,7 @@ JS_GetDataViewByteLength(JSObject *obj, JSContext *cx);
|
|||
* unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
JS_FRIEND_API(void *)
|
||||
JS_GetDataViewData(JSObject *obj, JSContext *cx);
|
||||
JS_GetDataViewData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
/*
|
||||
|
@ -1396,10 +1399,17 @@ typedef bool
|
|||
void *specializedThis, unsigned argc, JS::Value *vp);
|
||||
|
||||
struct JSJitInfo {
|
||||
enum OpType {
|
||||
Getter,
|
||||
Setter,
|
||||
Method
|
||||
};
|
||||
|
||||
JSJitPropertyOp op;
|
||||
uint32_t protoID;
|
||||
uint32_t depth;
|
||||
bool isInfallible; /* Is op fallible? Getters only */
|
||||
OpType type;
|
||||
bool isInfallible; /* Is op fallible? False in setters. */
|
||||
bool isConstant; /* Getting a construction-time constant? */
|
||||
};
|
||||
|
||||
|
@ -1420,4 +1430,95 @@ SET_JITINFO(JSFunction * func, const JSJitInfo *info)
|
|||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Engine-internal extensions of jsid. This code is here only until we
|
||||
* eliminate Gecko's dependencies on it!
|
||||
*/
|
||||
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
JSID_FROM_BITS(size_t bits)
|
||||
{
|
||||
jsid id;
|
||||
JSID_BITS(id) = bits;
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must not be used on atoms that are representable as integer jsids.
|
||||
* Prefer NameToId or AtomToId over this function:
|
||||
*
|
||||
* A PropertyName is an atom that does not contain an integer in the range
|
||||
* [0, UINT32_MAX]. However, jsid can only hold an integer in the range
|
||||
* [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of
|
||||
* integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
|
||||
* the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most
|
||||
* cases when creating a jsid, code does not have to care about this corner
|
||||
* case because:
|
||||
*
|
||||
* - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
|
||||
* integer atoms representable as integer jsids, and does this conversion.
|
||||
*
|
||||
* - When given a PropertyName*, NameToId can be used which which does not need
|
||||
* to do any dynamic checks.
|
||||
*
|
||||
* Thus, it is only the rare third case which needs this function, which
|
||||
* handles any JSAtom* that is known not to be representable with an int jsid.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
|
||||
{
|
||||
JS_ASSERT(((size_t)atom & 0x7) == 0);
|
||||
jsid id = JSID_FROM_BITS((size_t)atom);
|
||||
JS_ASSERT(id == INTERNED_STRING_TO_JSID(NULL, (JSString*)atom));
|
||||
return id;
|
||||
}
|
||||
|
||||
/* All strings stored in jsids are atomized, but are not necessarily property names. */
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id)
|
||||
{
|
||||
return JSID_IS_STRING(id);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id, JSAtom *atom)
|
||||
{
|
||||
return id == JSID_FROM_BITS((size_t)atom);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSAtom *
|
||||
JSID_TO_ATOM(jsid id)
|
||||
{
|
||||
return (JSAtom *)JSID_TO_STRING(id);
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE Value
|
||||
IdToValue(jsid id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
return StringValue(JSID_TO_STRING(id));
|
||||
if (JS_LIKELY(JSID_IS_INT(id)))
|
||||
return Int32Value(JSID_TO_INT(id));
|
||||
if (JS_LIKELY(JSID_IS_OBJECT(id)))
|
||||
return ObjectValue(*JSID_TO_OBJECT(id));
|
||||
JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id) || JSID_IS_VOID(id));
|
||||
return UndefinedValue();
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE jsval
|
||||
IdToJsval(jsid id)
|
||||
{
|
||||
return IdToValue(id);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* jsfriendapi_h___ */
|
||||
|
|
|
@ -43,6 +43,10 @@ class GCHelperThread;
|
|||
struct Shape;
|
||||
struct SliceBudget;
|
||||
|
||||
namespace ion {
|
||||
class IonCode;
|
||||
}
|
||||
|
||||
namespace gc {
|
||||
|
||||
enum State {
|
||||
|
@ -111,6 +115,7 @@ MapAllocToTraceKind(AllocKind thingKind)
|
|||
JSTRACE_STRING, /* FINALIZE_SHORT_STRING */
|
||||
JSTRACE_STRING, /* FINALIZE_STRING */
|
||||
JSTRACE_STRING, /* FINALIZE_EXTERNAL_STRING */
|
||||
JSTRACE_IONCODE, /* FINALIZE_IONCODE */
|
||||
};
|
||||
return map[thingKind];
|
||||
}
|
||||
|
@ -419,6 +424,7 @@ struct ArenaLists {
|
|||
void queueStringsForSweep(FreeOp *fop);
|
||||
void queueShapesForSweep(FreeOp *fop);
|
||||
void queueScriptsForSweep(FreeOp *fop);
|
||||
void queueIonCodeForSweep(FreeOp *fop);
|
||||
|
||||
bool foregroundFinalize(FreeOp *fop, AllocKind thingKind, SliceBudget &sliceBudget);
|
||||
static void backgroundFinalize(FreeOp *fop, ArenaHeader *listHead, bool onBackgroundThread);
|
||||
|
@ -633,8 +639,8 @@ class GCHelperThread {
|
|||
static void freeElementsAndArray(void **array, void **end) {
|
||||
JS_ASSERT(array <= end);
|
||||
for (void **p = array; p != end; ++p)
|
||||
js::Foreground::free_(*p);
|
||||
js::Foreground::free_(array);
|
||||
js_free(*p);
|
||||
js_free(array);
|
||||
}
|
||||
|
||||
static void threadMain(void* arg);
|
||||
|
@ -762,7 +768,7 @@ struct MarkStack {
|
|||
if (ballastcap == 0)
|
||||
return true;
|
||||
|
||||
ballast = (T *)js_malloc(sizeof(T) * ballastcap);
|
||||
ballast = js_pod_malloc<T>(ballastcap);
|
||||
if (!ballast)
|
||||
return false;
|
||||
ballastLimit = ballast + ballastcap;
|
||||
|
@ -843,7 +849,7 @@ struct MarkStack {
|
|||
|
||||
T *newStack;
|
||||
if (stack == ballast) {
|
||||
newStack = (T *)js_malloc(sizeof(T) * newcap);
|
||||
newStack = js_pod_malloc<T>(newcap);
|
||||
if (!newStack)
|
||||
return false;
|
||||
for (T *src = stack, *dst = newStack; src < tos; )
|
||||
|
@ -924,7 +930,8 @@ struct GCMarker : public JSTracer {
|
|||
XmlTag,
|
||||
ArenaTag,
|
||||
SavedValueArrayTag,
|
||||
LastTag = SavedValueArrayTag
|
||||
IonCodeTag,
|
||||
LastTag = IonCodeTag
|
||||
};
|
||||
|
||||
static const uintptr_t StackTagMask = 7;
|
||||
|
@ -961,8 +968,13 @@ struct GCMarker : public JSTracer {
|
|||
void pushXML(JSXML *xml) {
|
||||
pushTaggedPtr(XmlTag, xml);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void pushIonCode(ion::IonCode *code) {
|
||||
pushTaggedPtr(IonCodeTag, code);
|
||||
}
|
||||
|
||||
uint32_t getMarkColor() const {
|
||||
return color;
|
||||
}
|
||||
|
@ -1198,7 +1210,20 @@ MaybeVerifyBarriers(JSContext *cx, bool always = false)
|
|||
} /* namespace gc */
|
||||
|
||||
static inline JSCompartment *
|
||||
GetObjectCompartment(JSObject *obj) { return reinterpret_cast<js::gc::Cell *>(obj)->compartment(); }
|
||||
GetGCThingCompartment(void *thing)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
return reinterpret_cast<gc::Cell *>(thing)->compartment();
|
||||
}
|
||||
|
||||
static inline JSCompartment *
|
||||
GetObjectCompartment(JSObject *obj)
|
||||
{
|
||||
return GetGCThingCompartment(obj);
|
||||
}
|
||||
|
||||
void
|
||||
PurgeJITCaches(JSCompartment *c);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
# define JS_ATOMIC_ADD(p,v) PR_ATOMIC_ADD((int32_t *)(p), (int32_t)(v))
|
||||
# define JS_ATOMIC_SET(p,v) PR_ATOMIC_SET((int32_t *)(p), (int32_t)(v))
|
||||
|
||||
namespace js {
|
||||
unsigned GetCPUCount();
|
||||
}
|
||||
|
||||
#else /* JS_THREADSAFE */
|
||||
|
||||
typedef struct PRThread PRThread;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define JSON_PARSER_BUFSIZE 1024
|
||||
|
||||
extern JSObject *
|
||||
js_InitJSONClass(JSContext *cx, JSObject *obj);
|
||||
js_InitJSONClass(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
extern JSBool
|
||||
js_Stringify(JSContext *cx, js::MutableHandleValue vp,
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set sw=4 ts=8 et tw=80 ft=c:
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
#include "jsversion.h"
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
# define XML_INIT js_InitXMLClass
|
||||
# define NAMESPACE_INIT js_InitNamespaceClass
|
||||
# define QNAME_INIT js_InitQNameClass
|
||||
# define XMLFILTER_INIT js_InitXMLFilterClass
|
||||
#else
|
||||
# define XML_INIT js_InitNullClass
|
||||
# define NAMESPACE_INIT js_InitNullClass
|
||||
# define QNAME_INIT js_InitNullClass
|
||||
# define XMLFILTER_INIT js_InitNullClass
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerator codes in the second column must not change -- they are part of
|
||||
* the JS XDR API. Client modules including jsproto.tbl should consider
|
||||
* wrapping the inclusion with JS_BEGIN_EXTERN_C and JS_END_EXTERN_C.
|
||||
*/
|
||||
JS_PROTO(Null, 0, js_InitNullClass)
|
||||
JS_PROTO(Object, 1, js_InitObjectClass)
|
||||
JS_PROTO(Function, 2, js_InitFunctionClass)
|
||||
JS_PROTO(Array, 3, js_InitArrayClass)
|
||||
JS_PROTO(Boolean, 4, js_InitBooleanClass)
|
||||
JS_PROTO(JSON, 5, js_InitJSONClass)
|
||||
JS_PROTO(Date, 6, js_InitDateClass)
|
||||
JS_PROTO(Math, 7, js_InitMathClass)
|
||||
JS_PROTO(Number, 8, js_InitNumberClass)
|
||||
JS_PROTO(String, 9, js_InitStringClass)
|
||||
JS_PROTO(RegExp, 10, js_InitRegExpClass)
|
||||
JS_PROTO(XML, 11, XML_INIT)
|
||||
JS_PROTO(Namespace, 12, NAMESPACE_INIT)
|
||||
JS_PROTO(QName, 13, QNAME_INIT)
|
||||
JS_PROTO(Error, 14, js_InitExceptionClasses)
|
||||
JS_PROTO(InternalError, 15, js_InitExceptionClasses)
|
||||
JS_PROTO(EvalError, 16, js_InitExceptionClasses)
|
||||
JS_PROTO(RangeError, 17, js_InitExceptionClasses)
|
||||
JS_PROTO(ReferenceError, 18, js_InitExceptionClasses)
|
||||
JS_PROTO(SyntaxError, 19, js_InitExceptionClasses)
|
||||
JS_PROTO(TypeError, 20, js_InitExceptionClasses)
|
||||
JS_PROTO(URIError, 21, js_InitExceptionClasses)
|
||||
JS_PROTO(Iterator, 22, js_InitIteratorClasses)
|
||||
JS_PROTO(StopIteration, 23, js_InitIteratorClasses)
|
||||
JS_PROTO(ArrayBuffer, 24, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Int8Array, 25, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint8Array, 26, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Int16Array, 27, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint16Array, 28, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Int32Array, 29, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint32Array, 30, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Float32Array, 31, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Float64Array, 32, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint8ClampedArray, 33, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Proxy, 34, js_InitProxyClass)
|
||||
JS_PROTO(AnyName, 35, js_InitNullClass)
|
||||
JS_PROTO(WeakMap, 36, js_InitWeakMapClass)
|
||||
JS_PROTO(Map, 37, js_InitMapClass)
|
||||
JS_PROTO(Set, 38, js_InitSetClass)
|
||||
JS_PROTO(DataView, 39, js_InitTypedArrayClasses)
|
||||
JS_PROTO(ParallelArray, 40, js_InitParallelArrayClass)
|
||||
|
||||
#undef XML_INIT
|
||||
#undef NAMESPACE_INIT
|
||||
#undef QNAME_INIT
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* 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 higher-order macro for enumerating all JSProtoKey values. */
|
||||
|
||||
#ifndef jsprototypes_h___
|
||||
#define jsprototypes_h___
|
||||
|
||||
#include "jsversion.h"
|
||||
|
||||
/*
|
||||
* Enumerator codes in the second column must not change -- they are part of
|
||||
* the JS XDR API. Also note the symbols in the third column are extern "C";
|
||||
* clients should use extern "C" {} as appropriate when using this macro.
|
||||
*/
|
||||
|
||||
#define JS_FOR_EACH_PROTOTYPE(macro) \
|
||||
macro(Null, 0, js_InitNullClass) \
|
||||
macro(Object, 1, js_InitObjectClass) \
|
||||
macro(Function, 2, js_InitFunctionClass) \
|
||||
macro(Array, 3, js_InitArrayClass) \
|
||||
macro(Boolean, 4, js_InitBooleanClass) \
|
||||
macro(JSON, 5, js_InitJSONClass) \
|
||||
macro(Date, 6, js_InitDateClass) \
|
||||
macro(Math, 7, js_InitMathClass) \
|
||||
macro(Number, 8, js_InitNumberClass) \
|
||||
macro(String, 9, js_InitStringClass) \
|
||||
macro(RegExp, 10, js_InitRegExpClass) \
|
||||
macro(XML, 11, js_InitXMLClass) \
|
||||
macro(Namespace, 12, js_InitNamespaceClass) \
|
||||
macro(QName, 13, js_InitQNameClass) \
|
||||
macro(Error, 14, js_InitExceptionClasses) \
|
||||
macro(InternalError, 15, js_InitExceptionClasses) \
|
||||
macro(EvalError, 16, js_InitExceptionClasses) \
|
||||
macro(RangeError, 17, js_InitExceptionClasses) \
|
||||
macro(ReferenceError, 18, js_InitExceptionClasses) \
|
||||
macro(SyntaxError, 19, js_InitExceptionClasses) \
|
||||
macro(TypeError, 20, js_InitExceptionClasses) \
|
||||
macro(URIError, 21, js_InitExceptionClasses) \
|
||||
macro(Iterator, 22, js_InitIteratorClasses) \
|
||||
macro(StopIteration, 23, js_InitIteratorClasses) \
|
||||
macro(ArrayBuffer, 24, js_InitTypedArrayClasses) \
|
||||
macro(Int8Array, 25, js_InitTypedArrayClasses) \
|
||||
macro(Uint8Array, 26, js_InitTypedArrayClasses) \
|
||||
macro(Int16Array, 27, js_InitTypedArrayClasses) \
|
||||
macro(Uint16Array, 28, js_InitTypedArrayClasses) \
|
||||
macro(Int32Array, 29, js_InitTypedArrayClasses) \
|
||||
macro(Uint32Array, 30, js_InitTypedArrayClasses) \
|
||||
macro(Float32Array, 31, js_InitTypedArrayClasses) \
|
||||
macro(Float64Array, 32, js_InitTypedArrayClasses) \
|
||||
macro(Uint8ClampedArray, 33, js_InitTypedArrayClasses) \
|
||||
macro(Proxy, 34, js_InitProxyClass) \
|
||||
macro(AnyName, 35, js_InitNullClass) \
|
||||
macro(WeakMap, 36, js_InitWeakMapClass) \
|
||||
macro(Map, 37, js_InitMapClass) \
|
||||
macro(Set, 38, js_InitSetClass) \
|
||||
macro(DataView, 39, js_InitTypedArrayClasses) \
|
||||
macro(ParallelArray, 40, js_InitParallelArrayClass) \
|
||||
|
||||
#endif /* jsprototypes_h___ */
|
|
@ -51,7 +51,7 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||
bool mHasPrototype;
|
||||
protected:
|
||||
// Subclasses may set this in their constructor.
|
||||
void setHasPrototype(bool hasPrototype) { mHasPrototype = hasPrototype; };
|
||||
void setHasPrototype(bool hasPrototype) { mHasPrototype = hasPrototype; }
|
||||
|
||||
public:
|
||||
explicit BaseProxyHandler(void *family);
|
||||
|
@ -112,7 +112,7 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||
virtual bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp);
|
||||
virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
|
||||
virtual JSType typeOf(JSContext *cx, JSObject *proxy);
|
||||
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *proxy);
|
||||
|
@ -123,7 +123,7 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||
virtual void finalize(JSFreeOp *fop, JSObject *proxy);
|
||||
virtual bool getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver,
|
||||
uint32_t index, Value *vp, bool *present);
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **proto);
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
/* See comment for weakmapKeyDelegateOp in jsclass.h. */
|
||||
virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
|
||||
|
@ -165,7 +165,7 @@ class JS_PUBLIC_API(IndirectProxyHandler) : public BaseProxyHandler {
|
|||
Value *argv, Value *rval) MOZ_OVERRIDE;
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp,
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool *bp) MOZ_OVERRIDE;
|
||||
virtual JSType typeOf(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE;
|
||||
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue,
|
||||
|
@ -241,7 +241,7 @@ class Proxy {
|
|||
static bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp);
|
||||
static bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
|
||||
static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
|
||||
static bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
|
||||
static bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
|
||||
static JSType typeOf(JSContext *cx, JSObject *proxy);
|
||||
static bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
|
||||
static JSString *obj_toString(JSContext *cx, JSObject *proxy);
|
||||
|
@ -249,6 +249,9 @@ class Proxy {
|
|||
static bool regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g);
|
||||
static bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
|
||||
static bool iteratorNext(JSContext *cx, JSObject *proxy, Value *vp);
|
||||
static bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
static JSObject * const LazyProto;
|
||||
};
|
||||
|
||||
inline bool IsObjectProxyClass(const Class *clasp)
|
||||
|
@ -352,7 +355,7 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv,
|
|||
JS_BEGIN_EXTERN_C
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
js_InitProxyClass(JSContext *cx, JSObject *obj);
|
||||
js_InitProxyClass(JSContext *cx, JSHandleObject obj);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -47,11 +47,9 @@ typedef uint8_t jssrcnote;
|
|||
typedef uintptr_t jsatomid;
|
||||
|
||||
/* Struct typedefs. */
|
||||
typedef struct JSArgumentFormatMap JSArgumentFormatMap;
|
||||
typedef struct JSGCThing JSGCThing;
|
||||
typedef struct JSGenerator JSGenerator;
|
||||
typedef struct JSNativeEnumerator JSNativeEnumerator;
|
||||
typedef struct JSSharpObjectMap JSSharpObjectMap;
|
||||
typedef struct JSTryNote JSTryNote;
|
||||
|
||||
/* Friend "Advanced API" typedefs. */
|
||||
|
@ -81,7 +79,6 @@ class JSDependentString;
|
|||
class JSExtensibleString;
|
||||
class JSExternalString;
|
||||
class JSLinearString;
|
||||
class JSFixedString;
|
||||
class JSRope;
|
||||
class JSAtom;
|
||||
class JSWrapper;
|
||||
|
@ -179,8 +176,8 @@ namespace frontend {
|
|||
|
||||
struct BytecodeEmitter;
|
||||
struct Definition;
|
||||
struct FunctionBox;
|
||||
struct ObjectBox;
|
||||
class FunctionBox;
|
||||
class ObjectBox;
|
||||
struct Token;
|
||||
struct TokenPos;
|
||||
struct TokenPtr;
|
||||
|
@ -218,12 +215,15 @@ typedef JS::Handle<JSAtom*> HandleAtom;
|
|||
typedef JS::Handle<PropertyName*> HandlePropertyName;
|
||||
|
||||
typedef JS::MutableHandle<Shape*> MutableHandleShape;
|
||||
typedef JS::MutableHandle<JSAtom*> MutableHandleAtom;
|
||||
|
||||
typedef JS::Rooted<Shape*> RootedShape;
|
||||
typedef JS::Rooted<BaseShape*> RootedBaseShape;
|
||||
typedef JS::Rooted<types::TypeObject*> RootedTypeObject;
|
||||
typedef JS::Rooted<JSAtom*> RootedAtom;
|
||||
typedef JS::Rooted<PropertyName*> RootedPropertyName;
|
||||
typedef JSAtom * RawAtom;
|
||||
|
||||
typedef js::Rooted<Shape*> RootedShape;
|
||||
typedef js::Rooted<BaseShape*> RootedBaseShape;
|
||||
typedef js::Rooted<types::TypeObject*> RootedTypeObject;
|
||||
typedef js::Rooted<JSAtom*> RootedAtom;
|
||||
typedef js::Rooted<PropertyName*> RootedPropertyName;
|
||||
|
||||
enum XDRMode {
|
||||
XDR_ENCODE,
|
||||
|
@ -298,7 +298,7 @@ typedef void
|
|||
/* called just before script destruction */
|
||||
typedef void
|
||||
(* JSDestroyScriptHook)(JSFreeOp *fop,
|
||||
JSScript *script,
|
||||
JSRawScript script,
|
||||
void *callerdata);
|
||||
|
||||
typedef void
|
||||
|
@ -370,7 +370,7 @@ typedef JSObject *
|
|||
|
||||
/* Signature for class initialization ops. */
|
||||
typedef JSObject *
|
||||
(* JSClassInitializerOp)(JSContext *cx, JSObject *obj);
|
||||
(* JSClassInitializerOp)(JSContext *cx, JSHandleObject obj);
|
||||
|
||||
/*
|
||||
* Hook that creates an iterator object for a given object. Returns the
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
/*
|
||||
* JS public API typedefs.
|
||||
*/
|
||||
|
||||
#include "jsprototypes.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
/*
|
||||
|
@ -106,8 +108,8 @@ typedef enum JSType {
|
|||
|
||||
/* Dense index into cached prototypes and class atoms for standard objects. */
|
||||
typedef enum JSProtoKey {
|
||||
#define JS_PROTO(name,code,init) JSProto_##name = code,
|
||||
#include "jsproto.tbl"
|
||||
#define PROTOKEY_AND_INITIALIZER(name,code,init) JSProto_##name = code,
|
||||
JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER)
|
||||
#undef JS_PROTO
|
||||
JSProto_LIMIT
|
||||
} JSProtoKey;
|
||||
|
@ -162,6 +164,7 @@ typedef enum {
|
|||
* Trace kinds internal to the engine. The embedding can only them if it
|
||||
* implements JSTraceCallback.
|
||||
*/
|
||||
JSTRACE_IONCODE,
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
JSTRACE_XML,
|
||||
#endif
|
||||
|
@ -200,6 +203,7 @@ typedef struct JSTracer JSTracer;
|
|||
|
||||
#ifdef __cplusplus
|
||||
class JSFlatString;
|
||||
class JSStableString; // long story
|
||||
class JSString;
|
||||
#else
|
||||
typedef struct JSFlatString JSFlatString;
|
||||
|
@ -217,7 +221,7 @@ JS_END_EXTERN_C
|
|||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace JS {
|
||||
namespace js {
|
||||
|
||||
template <typename T>
|
||||
class Rooted;
|
||||
|
@ -237,6 +241,7 @@ enum ThingRootKind
|
|||
THING_ROOT_PROPERTY_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_TYPE,
|
||||
THING_ROOT_BINDINGS,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
||||
|
@ -248,12 +253,18 @@ struct RootKind;
|
|||
* JSAPI users may use JSRooted... types without having the class definition
|
||||
* available.
|
||||
*/
|
||||
template <> struct RootKind<JSObject *> { static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }; };
|
||||
template <> struct RootKind<JSFunction *> { static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }; };
|
||||
template <> struct RootKind<JSString *> { static ThingRootKind rootKind() { return THING_ROOT_STRING; }; };
|
||||
template <> struct RootKind<JSScript *> { static ThingRootKind rootKind() { return THING_ROOT_SCRIPT; }; };
|
||||
template <> struct RootKind<jsid> { static ThingRootKind rootKind() { return THING_ROOT_ID; }; };
|
||||
template <> struct RootKind<Value> { static ThingRootKind rootKind() { return THING_ROOT_VALUE; }; };
|
||||
template<typename T, ThingRootKind Kind>
|
||||
struct SpecificRootKind
|
||||
{
|
||||
static ThingRootKind rootKind() { return Kind; }
|
||||
};
|
||||
|
||||
template <> struct RootKind<JSObject *> : SpecificRootKind<JSObject *, THING_ROOT_OBJECT> {};
|
||||
template <> struct RootKind<JSFunction *> : SpecificRootKind<JSFunction *, THING_ROOT_OBJECT> {};
|
||||
template <> struct RootKind<JSString *> : SpecificRootKind<JSString *, THING_ROOT_STRING> {};
|
||||
template <> struct RootKind<JSScript *> : SpecificRootKind<JSScript *, THING_ROOT_SCRIPT> {};
|
||||
template <> struct RootKind<jsid> : SpecificRootKind<jsid, THING_ROOT_ID> {};
|
||||
template <> struct RootKind<JS::Value> : SpecificRootKind<JS::Value, THING_ROOT_VALUE> {};
|
||||
|
||||
struct ContextFriendFields {
|
||||
JSRuntime *const runtime;
|
||||
|
@ -290,7 +301,34 @@ struct ContextFriendFields {
|
|||
#endif
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
struct RuntimeFriendFields {
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
* as possible.
|
||||
*/
|
||||
volatile int32_t interrupt;
|
||||
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit;
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
/*
|
||||
* Stack allocated GC roots for stack GC heap pointers, which may be
|
||||
* overwritten if moved during a GC.
|
||||
*/
|
||||
Rooted<void*> *thingGCRooters[THING_ROOT_LIMIT];
|
||||
#endif
|
||||
|
||||
RuntimeFriendFields()
|
||||
: interrupt(0),
|
||||
nativeStackLimit(0) { }
|
||||
|
||||
static const RuntimeFriendFields *get(const JSRuntime *rt) {
|
||||
return reinterpret_cast<const RuntimeFriendFields *>(rt);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -264,6 +264,28 @@ Swap(T &t, T &u)
|
|||
u = Move(tmp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool
|
||||
IsPowerOfTwo(T t)
|
||||
{
|
||||
return t && !(t & (t - 1));
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static inline U
|
||||
ComputeByteAlignment(T bytes, U alignment)
|
||||
{
|
||||
JS_ASSERT(IsPowerOfTwo(alignment));
|
||||
return (alignment - (bytes % alignment)) % alignment;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static inline T
|
||||
AlignBytes(T bytes, U alignment)
|
||||
{
|
||||
return bytes + ComputeByteAlignment(bytes, alignment);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE static size_t
|
||||
UnsignedPtrDiff(const void *bigger, const void *smaller)
|
||||
{
|
||||
|
@ -433,8 +455,9 @@ typedef size_t jsbitmap;
|
|||
# define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \
|
||||
JS_BEGIN_MACRO \
|
||||
_Pragma("clang diagnostic push") \
|
||||
/* If these _Pragmas cause warnings for you, try disabling ccache. */ \
|
||||
_Pragma("clang diagnostic ignored \"-Wunused-value\"") \
|
||||
expr; \
|
||||
{ expr; } \
|
||||
_Pragma("clang diagnostic pop") \
|
||||
JS_END_MACRO
|
||||
#elif (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
|
|
|
@ -193,6 +193,11 @@ typedef uint64_t JSValueShiftedTag;
|
|||
#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type)))
|
||||
#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT)
|
||||
|
||||
#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL
|
||||
#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT
|
||||
#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32
|
||||
#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING
|
||||
|
||||
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL
|
||||
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT
|
||||
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED
|
||||
|
@ -219,6 +224,8 @@ typedef enum JSWhyMagic
|
|||
JS_FORWARD_TO_CALL_OBJECT, /* args object element stored in call object */
|
||||
JS_BLOCK_NEEDS_CLONE, /* value of static block object slot */
|
||||
JS_HASH_KEY_EMPTY, /* see class js::HashableValue */
|
||||
JS_ION_ERROR, /* error while running Ion code */
|
||||
JS_ION_BAILOUT, /* status code to signal EnterIon will OSR into Interpret */
|
||||
JS_GENERIC_MAGIC /* for local use */
|
||||
} JSWhyMagic;
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* License, v. 2.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___
|
||||
|
||||
/*
|
||||
* JS configuration macros.
|
||||
*/
|
||||
|
@ -166,3 +169,5 @@
|
|||
# define NEW_OBJECT_REPRESENTATION_ONLY() \
|
||||
MOZ_NOT_REACHED("don't call this! to be used in the new object representation")
|
||||
#endif
|
||||
|
||||
#endif /* jsversion_h___ */
|
||||
|
|
|
@ -208,7 +208,7 @@ class JS_FRIEND_API(DirectWrapper) : public Wrapper, public DirectProxyHandler
|
|||
virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE;
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp) MOZ_OVERRIDE;
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE;
|
||||
virtual bool defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint,
|
||||
|
@ -253,12 +253,13 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public DirectWrapper
|
|||
virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE;
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp) MOZ_OVERRIDE;
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE;
|
||||
virtual bool regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g) MOZ_OVERRIDE;
|
||||
virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp) MOZ_OVERRIDE;
|
||||
virtual bool iteratorNext(JSContext *cx, JSObject *wrapper, Value *vp);
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
static CrossCompartmentWrapper singleton;
|
||||
static CrossCompartmentWrapper singletonWithPrototype;
|
||||
|
@ -311,7 +312,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
|||
virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
|
||||
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *proxy);
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, unsigned indent);
|
||||
|
@ -320,7 +321,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
|||
virtual bool iteratorNext(JSContext *cx, JSObject *proxy, Value *vp);
|
||||
virtual bool getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver,
|
||||
uint32_t index, Value *vp, bool *present);
|
||||
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
static DeadObjectProxy singleton;
|
||||
};
|
||||
|
@ -351,12 +352,12 @@ UnwrapObject(JSObject *obj, bool stopAtOuter = true, unsigned *flagsp = NULL);
|
|||
// code should never be unwrapping outer window wrappers, we always stop at
|
||||
// outer windows.
|
||||
JS_FRIEND_API(JSObject *)
|
||||
UnwrapObjectChecked(JSContext *cx, JSObject *obj);
|
||||
UnwrapObjectChecked(JSContext *cx, RawObject obj);
|
||||
|
||||
// Unwrap only the outermost security wrapper, with the same semantics as
|
||||
// above. This is the checked version of Wrapper::wrappedObject.
|
||||
JS_FRIEND_API(JSObject *)
|
||||
UnwrapOneChecked(JSContext *cx, JSObject *obj);
|
||||
UnwrapOneChecked(JSContext *cx, HandleObject obj);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsCrossCompartmentWrapper(RawObject obj);
|
||||
|
@ -365,7 +366,7 @@ JSObject *
|
|||
NewDeadProxyObject(JSContext *cx, JSObject *parent);
|
||||
|
||||
void
|
||||
NukeCrossCompartmentWrapper(JSObject *wrapper);
|
||||
NukeCrossCompartmentWrapper(JSContext *cx, JSObject *wrapper);
|
||||
|
||||
bool
|
||||
RemapWrapper(JSContext *cx, JSObject *wobj, JSObject *newTarget);
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#define mozilla_Likely_h_
|
||||
|
||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 2))
|
||||
# define MOZ_LIKELY(x) (__builtin_expect((x), 1))
|
||||
# define MOZ_UNLIKELY(x) (__builtin_expect((x), 0))
|
||||
# define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1))
|
||||
# define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0))
|
||||
#else
|
||||
# define MOZ_LIKELY(x) (x)
|
||||
# define MOZ_UNLIKELY(x) (x)
|
||||
# define MOZ_LIKELY(x) (!!(x))
|
||||
# define MOZ_UNLIKELY(x) (!!(x))
|
||||
#endif
|
||||
|
||||
#endif /* mozilla_Likely_h_ */
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#define mozilla_SHA1_h_
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
class SHA1Sum {
|
||||
union {
|
||||
|
@ -37,9 +39,9 @@ class SHA1Sum {
|
|||
|
||||
public:
|
||||
static const unsigned int HashSize = 20;
|
||||
SHA1Sum();
|
||||
void update(const uint8_t *dataIn, uint32_t len);
|
||||
void finish(uint8_t hashout[20]);
|
||||
MFBT_API() SHA1Sum();
|
||||
MFBT_API(void) update(const void* dataIn, uint32_t len);
|
||||
MFBT_API(void) finish(uint8_t hashout[20]);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,11 @@
|
|||
*
|
||||
* Extension:
|
||||
*
|
||||
* In addition, this header provides class |Scoped| and macro |SCOPED_TEMPLATE|
|
||||
* to simplify the definition of RAII classes for other scenarios. These macros
|
||||
* have been used to automatically close file descriptors/file handles when
|
||||
* reaching the end of the scope, graphics contexts, etc.
|
||||
* In addition, this header provides class |Scoped| and macros |SCOPED_TEMPLATE|
|
||||
* and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE| to simplify the definition
|
||||
* of RAII classes for other scenarios. These macros have been used to
|
||||
* automatically close file descriptors/file handles when reaching the end of
|
||||
* the scope, graphics contexts, etc.
|
||||
*/
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
@ -223,6 +224,48 @@ struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
|
|||
};
|
||||
SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
||||
|
||||
/*
|
||||
* MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE makes it easy to create scoped
|
||||
* pointers for types with custom deleters; just overload
|
||||
* TypeSpecificDelete(T*) in the same namespace as T to call the deleter for
|
||||
* type T.
|
||||
*
|
||||
* @param name The name of the class to define.
|
||||
* @param Type A struct implementing clean-up. See the implementations
|
||||
* for more details.
|
||||
* *param Deleter The function that is used to delete/destroy/free a
|
||||
* non-null value of Type*.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, \
|
||||
* PR_Close)
|
||||
* ...
|
||||
* {
|
||||
* ScopedPRFileDesc file(PR_OpenFile(...));
|
||||
* ...
|
||||
* } // file is closed with PR_Close here
|
||||
*/
|
||||
#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \
|
||||
template <> inline void TypeSpecificDelete(Type * value) { Deleter(value); } \
|
||||
typedef ::mozilla::TypeSpecificScopedPointer<Type> name;
|
||||
|
||||
template <typename T> void TypeSpecificDelete(T * value);
|
||||
|
||||
template <typename T>
|
||||
struct TypeSpecificScopedPointerTraits
|
||||
{
|
||||
typedef T* type;
|
||||
const static type empty() { return NULL; }
|
||||
const static void release(type value)
|
||||
{
|
||||
if (value)
|
||||
TypeSpecificDelete(value);
|
||||
}
|
||||
};
|
||||
|
||||
SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits)
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif // mozilla_Scoped_h_
|
||||
|
|
|
@ -1 +1 @@
|
|||
22a636cde41437897d9f7dbccdbcb871065f48ec
|
||||
a0001da73e82abc77d183d416ca2b4b97e9e9ee1
|
|
@ -11,6 +11,7 @@
|
|||
#include "jsapi.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Root.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
/*
|
||||
|
@ -172,7 +173,7 @@ class EncapsulatedPtr
|
|||
operator T*() const { return value; }
|
||||
|
||||
protected:
|
||||
void pre() { T::writeBarrierPre(value); }
|
||||
void pre();
|
||||
};
|
||||
|
||||
template <class T, class Unioned = uintptr_t>
|
||||
|
@ -217,6 +218,36 @@ class HeapPtr : public EncapsulatedPtr<T, Unioned>
|
|||
HeapPtr<T2> &v2, T2 *val2);
|
||||
};
|
||||
|
||||
/*
|
||||
* FixedHeapPtr is designed for one very narrow case: replacing immutable raw
|
||||
* pointers to GC-managed things, implicitly converting to a handle type for
|
||||
* ease of use. Pointers encapsulated by this type must:
|
||||
*
|
||||
* be immutable (no incremental write barriers),
|
||||
* never point into the nursery (no generational write barriers), and
|
||||
* be traced via MarkRuntime (we use fromMarkedLocation).
|
||||
*
|
||||
* In short: you *really* need to know what you're doing before you use this
|
||||
* class!
|
||||
*/
|
||||
template <class T>
|
||||
class FixedHeapPtr
|
||||
{
|
||||
T *value;
|
||||
|
||||
public:
|
||||
operator T*() const { return value; }
|
||||
T * operator->() const { return value; }
|
||||
|
||||
operator Handle<T*>() const {
|
||||
return Handle<T*>::fromMarkedLocation(&value);
|
||||
}
|
||||
|
||||
void init(T *ptr) {
|
||||
value = ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
{
|
||||
|
|
|
@ -66,7 +66,8 @@ enum AllocKind {
|
|||
FINALIZE_SHORT_STRING,
|
||||
FINALIZE_STRING,
|
||||
FINALIZE_EXTERNAL_STRING,
|
||||
FINALIZE_LAST = FINALIZE_EXTERNAL_STRING
|
||||
FINALIZE_IONCODE,
|
||||
FINALIZE_LAST = FINALIZE_IONCODE
|
||||
};
|
||||
|
||||
static const unsigned FINALIZE_LIMIT = FINALIZE_LAST + 1;
|
||||
|
@ -103,26 +104,32 @@ struct Cell
|
|||
};
|
||||
|
||||
/*
|
||||
* Page size is 4096 by default, except for SPARC, where it is 8192.
|
||||
* 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.
|
||||
* Bug 692267: Move page size definition to gc/Memory.h and include it
|
||||
* directly once jsgc.h is no longer an installed header.
|
||||
*/
|
||||
#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
|
||||
#if (defined(SOLARIS) || defined(__FreeBSD__)) && \
|
||||
(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;
|
||||
|
||||
const size_t ChunkShift = 20;
|
||||
const size_t ChunkSize = size_t(1) << ChunkShift;
|
||||
const size_t ChunkMask = ChunkSize - 1;
|
||||
|
||||
const size_t ArenaShift = PageShift;
|
||||
const size_t ArenaSize = PageSize;
|
||||
const size_t ArenaMask = ArenaSize - 1;
|
||||
|
||||
/*
|
||||
* This is the maximum number of arenas we allow in the FreeCommitted state
|
||||
* before we trigger a GC_SHRINK to release free arenas to the OS.
|
||||
|
|
|
@ -11,13 +11,11 @@
|
|||
#ifdef __cplusplus
|
||||
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
namespace JS {
|
||||
#include "jspubtd.h"
|
||||
|
||||
/*
|
||||
* Moving GC Stack Rooting
|
||||
|
@ -62,11 +60,24 @@ namespace JS {
|
|||
* separate rooting analysis.
|
||||
*/
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
namespace js {
|
||||
|
||||
template <typename T> class Rooted;
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods { };
|
||||
struct RootMethods {};
|
||||
|
||||
template <typename T>
|
||||
class HandleBase {};
|
||||
|
||||
template <typename T>
|
||||
class MutableHandleBase {};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
|
||||
/*
|
||||
* Handle provides an implicit constructor for NullPtr so that, given:
|
||||
|
@ -83,9 +94,6 @@ struct NullPtr
|
|||
template <typename T>
|
||||
class MutableHandle;
|
||||
|
||||
template <typename T>
|
||||
class HandleBase {};
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -95,7 +103,7 @@ class HandleBase {};
|
|||
* specialization, define a HandleBase<T> specialization containing them.
|
||||
*/
|
||||
template <typename T>
|
||||
class Handle : public HandleBase<T>
|
||||
class Handle : public js::HandleBase<T>
|
||||
{
|
||||
public:
|
||||
/* Creates a handle from a handle of a type convertible to T. */
|
||||
|
@ -136,7 +144,7 @@ class Handle : public HandleBase<T>
|
|||
*/
|
||||
template <typename S>
|
||||
inline
|
||||
Handle(Rooted<S> &root,
|
||||
Handle(js::Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
/* Construct a read only handle from a mutable handle. */
|
||||
|
@ -167,9 +175,6 @@ typedef Handle<JSString*> HandleString;
|
|||
typedef Handle<jsid> HandleId;
|
||||
typedef Handle<Value> HandleValue;
|
||||
|
||||
template <typename T>
|
||||
class MutableHandleBase {};
|
||||
|
||||
/*
|
||||
* Similar to a handle, but the underlying storage can be changed. This is
|
||||
* useful for outparams.
|
||||
|
@ -179,7 +184,7 @@ class MutableHandleBase {};
|
|||
* them.
|
||||
*/
|
||||
template <typename T>
|
||||
class MutableHandle : public MutableHandleBase<T>
|
||||
class MutableHandle : public js::MutableHandleBase<T>
|
||||
{
|
||||
public:
|
||||
template <typename S>
|
||||
|
@ -191,12 +196,12 @@ class MutableHandle : public MutableHandleBase<T>
|
|||
|
||||
template <typename S>
|
||||
inline
|
||||
MutableHandle(Rooted<S> *root,
|
||||
MutableHandle(js::Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
void set(T v)
|
||||
{
|
||||
JS_ASSERT(!RootMethods<T>::poisoned(v));
|
||||
JS_ASSERT(!js::RootMethods<T>::poisoned(v));
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
|
@ -228,14 +233,88 @@ class MutableHandle : public MutableHandleBase<T>
|
|||
void operator =(S v) MOZ_DELETE;
|
||||
};
|
||||
|
||||
typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<JSFunction*> MutableHandleFunction;
|
||||
typedef MutableHandle<JSScript*> MutableHandleScript;
|
||||
typedef MutableHandle<JSString*> MutableHandleString;
|
||||
typedef MutableHandle<jsid> MutableHandleId;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
|
||||
/*
|
||||
* Raw pointer used as documentation that a parameter does not need to be
|
||||
* rooted.
|
||||
*/
|
||||
typedef JSObject * RawObject;
|
||||
typedef JSFunction * RawFunction;
|
||||
typedef JSScript * RawScript;
|
||||
typedef JSString * RawString;
|
||||
typedef jsid RawId;
|
||||
typedef Value RawValue;
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* InternalHandle is a handle to an internal pointer into a gcthing. Use
|
||||
* InternalHandle when you have a pointer to a direct field of a gcthing, or
|
||||
* when you need a parameter type for something that *may* be a pointer to a
|
||||
* direct field of a gcthing.
|
||||
*/
|
||||
template <typename T>
|
||||
class InternalHandle { };
|
||||
|
||||
template <typename T>
|
||||
class InternalHandle<T*>
|
||||
{
|
||||
void * const *holder;
|
||||
size_t offset;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Create an InternalHandle using a Handle to the gcthing containing the
|
||||
* field in question, and a pointer to the field.
|
||||
*/
|
||||
template<typename H>
|
||||
InternalHandle(const JS::Handle<H> &handle, T *field)
|
||||
: holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get()))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an InternalHandle to a field within a Rooted<>.
|
||||
*/
|
||||
template<typename R>
|
||||
InternalHandle(const Rooted<R> &root, T *field)
|
||||
: holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
|
||||
{
|
||||
}
|
||||
|
||||
T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
|
||||
|
||||
const T& operator *() const { return *get(); }
|
||||
T* operator ->() const { return get(); }
|
||||
|
||||
static InternalHandle<T*> fromMarkedLocation(T *fieldPtr) {
|
||||
return InternalHandle(fieldPtr);
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* Create an InternalHandle to something that is not a pointer to a
|
||||
* gcthing, and so does not need to be rooted in the first place. Use these
|
||||
* InternalHandles to pass pointers into functions that also need to accept
|
||||
* regular InternalHandles to gcthing fields.
|
||||
*
|
||||
* Make this private to prevent accidental misuse; this is only for
|
||||
* fromMarkedLocation().
|
||||
*/
|
||||
InternalHandle(T *field)
|
||||
: holder(reinterpret_cast<void * const *>(&NullPtr::constNullValue)),
|
||||
offset(uintptr_t(field))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* By default, pointers should use the inheritance hierarchy to find their
|
||||
|
@ -243,7 +322,7 @@ typedef JSObject * RawObject;
|
|||
* Rooted<T> may be used without the class definition being available.
|
||||
*/
|
||||
template <typename T>
|
||||
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); }; };
|
||||
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); } };
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods<T *>
|
||||
|
@ -253,6 +332,12 @@ struct RootMethods<T *>
|
|||
static bool poisoned(T *v) { return IsPoisonedPtr(v); }
|
||||
};
|
||||
|
||||
#if !(defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING))
|
||||
// Defined in vm/String.h.
|
||||
template <>
|
||||
class Rooted<JSStableString *>;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
class RootedBase {};
|
||||
|
||||
|
@ -267,10 +352,10 @@ class RootedBase {};
|
|||
template <typename T>
|
||||
class Rooted : public RootedBase<T>
|
||||
{
|
||||
void init(JSContext *cx_)
|
||||
void init(JSContext *cxArg)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cx_);
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cxArg);
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Rooted<T>**>(&cx->thingGCRooters[kind]);
|
||||
|
@ -281,9 +366,52 @@ class Rooted : public RootedBase<T>
|
|||
#endif
|
||||
}
|
||||
|
||||
void init(JSRuntime *rtArg)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
RuntimeFriendFields *rt = const_cast<RuntimeFriendFields *>(RuntimeFriendFields::get(rtArg));
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Rooted<T>**>(&rt->thingGCRooters[kind]);
|
||||
this->prev = *stack;
|
||||
*stack = this;
|
||||
|
||||
JS_ASSERT(!RootMethods<T>::poisoned(ptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
Rooted(JSContext *cx) : ptr(RootMethods<T>::initial()) { init(cx); }
|
||||
Rooted(JSContext *cx, T initial) : ptr(initial) { init(cx); }
|
||||
Rooted(JSRuntime *rt
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(RootMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(rt);
|
||||
}
|
||||
|
||||
Rooted(JSRuntime *rt, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(rt);
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(RootMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
~Rooted()
|
||||
{
|
||||
|
@ -318,40 +446,15 @@ class Rooted : public RootedBase<T>
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
Rooted<T> **stack, *prev;
|
||||
#endif
|
||||
T ptr;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
Rooted() MOZ_DELETE;
|
||||
Rooted(const Rooted &) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
|
@ -367,7 +470,7 @@ typedef Rooted<Value> RootedValue;
|
|||
*/
|
||||
class SkipRoot
|
||||
{
|
||||
#if defined(DEBUG) && defined(JSGC_ROOT_ANALYSIS)
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
|
||||
SkipRoot **stack, *prev;
|
||||
const uint8_t *start;
|
||||
|
@ -419,64 +522,123 @@ class SkipRoot
|
|||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(js::Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(js::Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void) EnterAssertNoGCScope();
|
||||
JS_FRIEND_API(void) LeaveAssertNoGCScope();
|
||||
JS_FRIEND_API(bool) InNoGCScope();
|
||||
|
||||
/*
|
||||
* This typedef is to annotate parameters that we have manually verified do not
|
||||
* need rooting, as opposed to parameters that have not yet been considered.
|
||||
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
|
||||
* attempted while the guard object is live. If you have a GC-unsafe operation
|
||||
* to perform, use this guard object to protect your operation.
|
||||
*/
|
||||
typedef JSObject *RawObject;
|
||||
class AutoAssertNoGC
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_FRIEND_API(bool) IsRootingUnnecessaryForContext(JSContext *cx);
|
||||
JS_FRIEND_API(void) SetRootingUnnecessaryForContext(JSContext *cx, bool value);
|
||||
JS_FRIEND_API(bool) RelaxRootChecksForContext(JSContext *cx);
|
||||
#endif
|
||||
|
||||
class AssertRootingUnnecessary {
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
#ifdef DEBUG
|
||||
JSContext *cx;
|
||||
bool prev;
|
||||
#endif
|
||||
public:
|
||||
AssertRootingUnnecessary(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
AutoAssertNoGC(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
#ifdef DEBUG
|
||||
this->cx = cx;
|
||||
prev = IsRootingUnnecessaryForContext(cx);
|
||||
SetRootingUnnecessaryForContext(cx, true);
|
||||
EnterAssertNoGCScope();
|
||||
#endif
|
||||
}
|
||||
|
||||
~AssertRootingUnnecessary() {
|
||||
~AutoAssertNoGC() {
|
||||
#ifdef DEBUG
|
||||
SetRootingUnnecessaryForContext(cx, prev);
|
||||
LeaveAssertNoGCScope();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* AssertCanGC will assert if it is called inside of an AutoAssertNoGC region.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
JS_ALWAYS_INLINE void
|
||||
AssertCanGC()
|
||||
{
|
||||
JS_ASSERT(!InNoGCScope());
|
||||
}
|
||||
#else
|
||||
# define AssertCanGC()
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
extern void
|
||||
CheckStackRoots(JSContext *cx);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(bool) NeedRelaxedRootChecks();
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Hook for dynamic root analysis. Checks the native stack and poisons
|
||||
* references to GC things which have not been rooted.
|
||||
*/
|
||||
inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!IsRootingUnnecessaryForContext(cx));
|
||||
# if defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
if (relax && RelaxRootChecksForContext(cx))
|
||||
AssertCanGC();
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
if (relax && NeedRelaxedRootChecks())
|
||||
return;
|
||||
CheckStackRoots(cx);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
namespace gc {
|
||||
struct Cell;
|
||||
} /* namespace gc */
|
||||
|
||||
/* Base class for automatic read-only object rooting during compilation. */
|
||||
class CompilerRootNode
|
||||
{
|
||||
protected:
|
||||
CompilerRootNode(js::gc::Cell *ptr)
|
||||
: next(NULL), ptr(ptr)
|
||||
{ }
|
||||
|
||||
public:
|
||||
void **address() { return (void **)&ptr; }
|
||||
|
||||
public:
|
||||
CompilerRootNode *next;
|
||||
|
||||
protected:
|
||||
js::gc::Cell *ptr;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ enum Phase {
|
|||
PHASE_SWEEP_STRING,
|
||||
PHASE_SWEEP_SCRIPT,
|
||||
PHASE_SWEEP_SHAPE,
|
||||
PHASE_SWEEP_IONCODE,
|
||||
PHASE_SWEEP_DISCARD_CODE,
|
||||
PHASE_DISCARD_ANALYSIS,
|
||||
PHASE_DISCARD_TI,
|
||||
|
|
|
@ -360,3 +360,18 @@ MSG_DEF(JSMSG_PAR_ARRAY_REDUCE_EMPTY, 306, 0, JSEXN_ERR, "cannot reduce empty Pa
|
|||
MSG_DEF(JSMSG_PAR_ARRAY_ALREADY_FLAT, 307, 0, JSEXN_ERR, "cannot flatten 1-dimensional ParallelArray object")
|
||||
MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_CONFLICT, 308, 0, JSEXN_ERR, "no conflict resolution function provided")
|
||||
MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BOUNDS, 309, 0, JSEXN_ERR, "index in scatter vector out of bounds")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE, 310, 0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 311, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_NEW, 312, 0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_INVALID, 313, 0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor")
|
||||
MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC, 314, 0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_NEW, 315, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 316, 0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 317, 0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable")
|
||||
MSG_DEF(JSMSG_INVALID_TRAP_RESULT, 318, 2, JSEXN_TYPEERR, "trap {1} for {0} returned an invalid result")
|
||||
MSG_DEF(JSMSG_CANT_SKIP_NC, 319, 0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property")
|
||||
MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 320, 0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property")
|
||||
MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 321, 0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter")
|
||||
MSG_DEF(JSMSG_CANT_SET_NW_NC, 322, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property")
|
||||
MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 323, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter")
|
||||
MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 324, 2, JSEXN_TYPEERR, "{0} does not refer to {1}")
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#ifndef jshashtable_h_
|
||||
#define jshashtable_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "TemplateLib.h"
|
||||
#include "Utility.h"
|
||||
|
||||
|
@ -340,8 +342,7 @@ class HashTable : private AllocPolicy
|
|||
|
||||
MOZ_WARN_UNUSED_RESULT bool init(uint32_t length)
|
||||
{
|
||||
/* Make sure that init isn't called twice. */
|
||||
JS_ASSERT(table == NULL);
|
||||
JS_ASSERT(!initialized());
|
||||
|
||||
/*
|
||||
* Correct for sMaxAlphaFrac such that the table will not resize
|
||||
|
@ -1013,10 +1014,6 @@ class HashMap
|
|||
|
||||
friend class Impl::Enum;
|
||||
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashMap(const HashMap &);
|
||||
HashMap &operator=(const HashMap &);
|
||||
|
||||
Impl impl;
|
||||
|
||||
public:
|
||||
|
@ -1218,6 +1215,11 @@ class HashMap
|
|||
if (Ptr p = lookup(l))
|
||||
remove(p);
|
||||
}
|
||||
|
||||
private:
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashMap(const HashMap &hm) MOZ_DELETE;
|
||||
HashMap &operator=(const HashMap &hm) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1251,10 +1253,6 @@ class HashSet
|
|||
|
||||
friend class Impl::Enum;
|
||||
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashSet(const HashSet &);
|
||||
HashSet &operator=(const HashSet &);
|
||||
|
||||
Impl impl;
|
||||
|
||||
public:
|
||||
|
@ -1418,6 +1416,11 @@ class HashSet
|
|||
if (Ptr p = lookup(l))
|
||||
remove(p);
|
||||
}
|
||||
|
||||
private:
|
||||
/* Not implicitly copyable (expensive). May add explicit |clone| later. */
|
||||
HashSet(const HashSet &hs) MOZ_DELETE;
|
||||
HashSet &operator=(const HashSet &hs) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -8,10 +8,8 @@
|
|||
#ifndef js_MemoryMetrics_h
|
||||
#define js_MemoryMetrics_h
|
||||
|
||||
/*
|
||||
* These declarations are not within jsapi.h because they are highly likely
|
||||
* to change in the future. Depend on them at your own risk.
|
||||
*/
|
||||
// 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 <string.h>
|
||||
|
||||
|
@ -21,11 +19,31 @@
|
|||
#include "js/Utility.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
// In memory reporting, we have concept of "sundries", line items which are too
|
||||
// small to be worth reporting individually. Under some circumstances, a memory
|
||||
// reporter gets tossed into the sundries bucket if it's smaller than
|
||||
// MemoryReportingSundriesThreshold() bytes.
|
||||
//
|
||||
// We need to define this value here, rather than in the code which actually
|
||||
// generates the memory reports, because HugeStringInfo uses this value.
|
||||
JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold();
|
||||
|
||||
} // namespace js
|
||||
|
||||
namespace JS {
|
||||
|
||||
/* Data for tracking analysis/inference memory usage. */
|
||||
// Data for tracking analysis/inference memory usage.
|
||||
struct TypeInferenceSizes
|
||||
{
|
||||
TypeInferenceSizes()
|
||||
: scripts(0)
|
||||
, objects(0)
|
||||
, tables(0)
|
||||
, temporary(0)
|
||||
{}
|
||||
|
||||
size_t scripts;
|
||||
size_t objects;
|
||||
size_t tables;
|
||||
|
@ -39,6 +57,34 @@ struct TypeInferenceSizes
|
|||
}
|
||||
};
|
||||
|
||||
// Holds data about a huge string (one which uses more HugeStringInfo::MinSize
|
||||
// bytes of memory), so we can report it individually.
|
||||
struct HugeStringInfo
|
||||
{
|
||||
HugeStringInfo()
|
||||
: length(0)
|
||||
, size(0)
|
||||
{
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
}
|
||||
|
||||
// A string needs to take up this many bytes of storage before we consider
|
||||
// it to be "huge".
|
||||
static size_t MinSize()
|
||||
{
|
||||
return js::MemoryReportingSundriesThreshold();
|
||||
}
|
||||
|
||||
// A string's size in memory is not necessarily equal to twice its length
|
||||
// because the allocator and the JS engine both may round up.
|
||||
size_t length;
|
||||
size_t size;
|
||||
|
||||
// We record the first 32 chars of the escaped string here. (We escape the
|
||||
// string so we can use a char[] instead of a jschar[] here.
|
||||
char buffer[32];
|
||||
};
|
||||
|
||||
// These measurements relate directly to the JSRuntime, and not to
|
||||
// compartments within it.
|
||||
struct RuntimeSizes
|
||||
|
@ -49,15 +95,15 @@ struct RuntimeSizes
|
|||
, contexts(0)
|
||||
, dtoa(0)
|
||||
, temporary(0)
|
||||
, mjitCode(0)
|
||||
, jaegerCode(0)
|
||||
, ionCode(0)
|
||||
, regexpCode(0)
|
||||
, unusedCodeMemory(0)
|
||||
, stackCommitted(0)
|
||||
, unusedCode(0)
|
||||
, stack(0)
|
||||
, gcMarker(0)
|
||||
, mathCache(0)
|
||||
, scriptFilenames(0)
|
||||
, scriptSources(0)
|
||||
, compartmentObjects(0)
|
||||
{}
|
||||
|
||||
size_t object;
|
||||
|
@ -65,34 +111,102 @@ struct RuntimeSizes
|
|||
size_t contexts;
|
||||
size_t dtoa;
|
||||
size_t temporary;
|
||||
size_t mjitCode;
|
||||
size_t jaegerCode;
|
||||
size_t ionCode;
|
||||
size_t regexpCode;
|
||||
size_t unusedCodeMemory;
|
||||
size_t stackCommitted;
|
||||
size_t unusedCode;
|
||||
size_t stack;
|
||||
size_t gcMarker;
|
||||
size_t mathCache;
|
||||
size_t scriptFilenames;
|
||||
size_t scriptSources;
|
||||
|
||||
// This is the exception to the "RuntimeSizes doesn't measure things within
|
||||
// compartments" rule. We combine the sizes of all the JSCompartment
|
||||
// objects into a single measurement because each one is fairly small, and
|
||||
// they're all the same size.
|
||||
size_t compartmentObjects;
|
||||
};
|
||||
|
||||
struct CompartmentStats
|
||||
{
|
||||
CompartmentStats() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
CompartmentStats()
|
||||
: extra1(0)
|
||||
, extra2(0)
|
||||
, gcHeapArenaAdmin(0)
|
||||
, gcHeapUnusedGcThings(0)
|
||||
, gcHeapObjectsNonFunction(0)
|
||||
, gcHeapObjectsFunction(0)
|
||||
, gcHeapStrings(0)
|
||||
, gcHeapShapesTree(0)
|
||||
, gcHeapShapesDict(0)
|
||||
, gcHeapShapesBase(0)
|
||||
, gcHeapScripts(0)
|
||||
, gcHeapTypeObjects(0)
|
||||
, gcHeapIonCodes(0)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
, gcHeapXML(0)
|
||||
#endif
|
||||
, objectsExtraSlots(0)
|
||||
, objectsExtraElements(0)
|
||||
, objectsExtraArgumentsData(0)
|
||||
, objectsExtraRegExpStatics(0)
|
||||
, objectsExtraPropertyIteratorData(0)
|
||||
, objectsExtraPrivate(0)
|
||||
, nonHugeStringChars(0)
|
||||
, shapesExtraTreeTables(0)
|
||||
, shapesExtraDictTables(0)
|
||||
, shapesExtraTreeShapeKids(0)
|
||||
, shapesCompartmentTables(0)
|
||||
, scriptData(0)
|
||||
, jaegerData(0)
|
||||
, ionData(0)
|
||||
, compartmentObject(0)
|
||||
, crossCompartmentWrappers(0)
|
||||
, regexpCompartment(0)
|
||||
, debuggeesSet(0)
|
||||
{}
|
||||
|
||||
CompartmentStats(const CompartmentStats &other)
|
||||
: extra1(other.extra1)
|
||||
, extra2(other.extra2)
|
||||
, gcHeapArenaAdmin(other.gcHeapArenaAdmin)
|
||||
, gcHeapUnusedGcThings(other.gcHeapUnusedGcThings)
|
||||
, gcHeapObjectsNonFunction(other.gcHeapObjectsNonFunction)
|
||||
, gcHeapObjectsFunction(other.gcHeapObjectsFunction)
|
||||
, gcHeapStrings(other.gcHeapStrings)
|
||||
, gcHeapShapesTree(other.gcHeapShapesTree)
|
||||
, gcHeapShapesDict(other.gcHeapShapesDict)
|
||||
, gcHeapShapesBase(other.gcHeapShapesBase)
|
||||
, gcHeapScripts(other.gcHeapScripts)
|
||||
, gcHeapTypeObjects(other.gcHeapTypeObjects)
|
||||
, gcHeapIonCodes(other.gcHeapIonCodes)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
, gcHeapXML(other.gcHeapXML)
|
||||
#endif
|
||||
, objectsExtraSlots(other.objectsExtraSlots)
|
||||
, objectsExtraElements(other.objectsExtraElements)
|
||||
, objectsExtraArgumentsData(other.objectsExtraArgumentsData)
|
||||
, objectsExtraRegExpStatics(other.objectsExtraRegExpStatics)
|
||||
, objectsExtraPropertyIteratorData(other.objectsExtraPropertyIteratorData)
|
||||
, objectsExtraPrivate(other.objectsExtraPrivate)
|
||||
, nonHugeStringChars(other.nonHugeStringChars)
|
||||
, shapesExtraTreeTables(other.shapesExtraTreeTables)
|
||||
, shapesExtraDictTables(other.shapesExtraDictTables)
|
||||
, shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids)
|
||||
, shapesCompartmentTables(other.shapesCompartmentTables)
|
||||
, scriptData(other.scriptData)
|
||||
, jaegerData(other.jaegerData)
|
||||
, ionData(other.ionData)
|
||||
, compartmentObject(other.compartmentObject)
|
||||
, crossCompartmentWrappers(other.crossCompartmentWrappers)
|
||||
, regexpCompartment(other.regexpCompartment)
|
||||
, debuggeesSet(other.debuggeesSet)
|
||||
, typeInferenceSizes(other.typeInferenceSizes)
|
||||
{
|
||||
hugeStrings.append(other.hugeStrings);
|
||||
}
|
||||
|
||||
// These fields can be used by embedders.
|
||||
void *extra1;
|
||||
void *extra2;
|
||||
|
||||
// If you add a new number, remember to update add() and maybe
|
||||
// gcHeapThingsSize()!
|
||||
// If you add a new number, remember to update the constructors, add(), and
|
||||
// maybe gcHeapThingsSize()!
|
||||
size_t gcHeapArenaAdmin;
|
||||
size_t gcHeapUnusedGcThings;
|
||||
|
||||
|
@ -104,27 +218,36 @@ struct CompartmentStats
|
|||
size_t gcHeapShapesBase;
|
||||
size_t gcHeapScripts;
|
||||
size_t gcHeapTypeObjects;
|
||||
size_t gcHeapIonCodes;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
size_t gcHeapXML;
|
||||
#endif
|
||||
|
||||
size_t objectSlots;
|
||||
size_t objectElements;
|
||||
size_t objectMisc;
|
||||
size_t objectPrivate;
|
||||
size_t stringChars;
|
||||
size_t objectsExtraSlots;
|
||||
size_t objectsExtraElements;
|
||||
size_t objectsExtraArgumentsData;
|
||||
size_t objectsExtraRegExpStatics;
|
||||
size_t objectsExtraPropertyIteratorData;
|
||||
size_t objectsExtraPrivate;
|
||||
size_t nonHugeStringChars;
|
||||
size_t shapesExtraTreeTables;
|
||||
size_t shapesExtraDictTables;
|
||||
size_t shapesExtraTreeShapeKids;
|
||||
size_t shapesCompartmentTables;
|
||||
size_t scriptData;
|
||||
size_t mjitData;
|
||||
size_t jaegerData;
|
||||
size_t ionData;
|
||||
size_t compartmentObject;
|
||||
size_t crossCompartmentWrappers;
|
||||
size_t regexpCompartment;
|
||||
size_t debuggeesSet;
|
||||
|
||||
TypeInferenceSizes typeInferenceSizes;
|
||||
js::Vector<HugeStringInfo, 0, js::SystemAllocPolicy> hugeStrings;
|
||||
|
||||
// Add cStats's numbers to this object's numbers.
|
||||
void add(CompartmentStats &cStats) {
|
||||
void add(CompartmentStats &cStats)
|
||||
{
|
||||
#define ADD(x) this->x += cStats.x
|
||||
|
||||
ADD(gcHeapArenaAdmin);
|
||||
|
@ -138,26 +261,34 @@ struct CompartmentStats
|
|||
ADD(gcHeapShapesBase);
|
||||
ADD(gcHeapScripts);
|
||||
ADD(gcHeapTypeObjects);
|
||||
ADD(gcHeapIonCodes);
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
ADD(gcHeapXML);
|
||||
#endif
|
||||
|
||||
ADD(objectSlots);
|
||||
ADD(objectElements);
|
||||
ADD(objectMisc);
|
||||
ADD(objectPrivate);
|
||||
ADD(stringChars);
|
||||
ADD(objectsExtraSlots);
|
||||
ADD(objectsExtraElements);
|
||||
ADD(objectsExtraArgumentsData);
|
||||
ADD(objectsExtraRegExpStatics);
|
||||
ADD(objectsExtraPropertyIteratorData);
|
||||
ADD(objectsExtraPrivate);
|
||||
ADD(nonHugeStringChars);
|
||||
ADD(shapesExtraTreeTables);
|
||||
ADD(shapesExtraDictTables);
|
||||
ADD(shapesExtraTreeShapeKids);
|
||||
ADD(shapesCompartmentTables);
|
||||
ADD(scriptData);
|
||||
ADD(mjitData);
|
||||
ADD(jaegerData);
|
||||
ADD(ionData);
|
||||
ADD(compartmentObject);
|
||||
ADD(crossCompartmentWrappers);
|
||||
ADD(regexpCompartment);
|
||||
ADD(debuggeesSet);
|
||||
|
||||
#undef ADD
|
||||
|
||||
typeInferenceSizes.add(cStats.typeInferenceSizes);
|
||||
hugeStrings.append(cStats.hugeStrings);
|
||||
}
|
||||
|
||||
// The size of all the live things in the GC heap.
|
||||
|
@ -239,7 +370,7 @@ CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *
|
|||
extern JS_PUBLIC_API(int64_t)
|
||||
GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
#endif /* JS_THREADSAFE */
|
||||
#endif // JS_THREADSAFE
|
||||
|
||||
extern JS_PUBLIC_API(size_t)
|
||||
SystemCompartmentCount(const JSRuntime *rt);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "jstypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include "js/TemplateLib.h"
|
||||
# include "mozilla/Scoped.h"
|
||||
|
||||
/* The public JS engine namespace. */
|
||||
|
@ -146,11 +147,6 @@ PrintBacktrace()
|
|||
# define JS_OOM_POSSIBLY_FAIL_REPORT(cx) do {} while(0)
|
||||
# endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* SpiderMonkey code should not be calling these allocation functions directly.
|
||||
* Instead, all calls should go through JSRuntime, JSContext or OffTheBooks.
|
||||
* However, js_free() can be called directly.
|
||||
*/
|
||||
static JS_INLINE void* js_malloc(size_t bytes)
|
||||
{
|
||||
JS_OOM_POSSIBLY_FAIL();
|
||||
|
@ -381,82 +377,45 @@ JS_END_EXTERN_C
|
|||
#include <new>
|
||||
|
||||
/*
|
||||
* User guide to memory management within SpiderMonkey:
|
||||
* Low-level memory management in SpiderMonkey:
|
||||
*
|
||||
* Quick tips:
|
||||
* ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these
|
||||
* to be redefined (via JS_USE_CUSTOM_ALLOCATOR) and Gecko even #define's
|
||||
* these symbols.
|
||||
*
|
||||
* Allocation:
|
||||
* - Prefer to allocate using JSContext:
|
||||
* cx->{malloc_,realloc_,calloc_,new_,array_new}
|
||||
* ** Do not use the builtin C++ operator new and delete: these throw on
|
||||
* error and we cannot override them not to.
|
||||
*
|
||||
* - If no JSContext is available, use a JSRuntime:
|
||||
* rt->{malloc_,realloc_,calloc_,new_,array_new}
|
||||
* Allocation:
|
||||
*
|
||||
* - As a last resort, use unaccounted allocation ("OffTheBooks"):
|
||||
* js::OffTheBooks::{malloc_,realloc_,calloc_,new_,array_new}
|
||||
* - If the lifetime of the allocation is tied to the lifetime of a GC-thing
|
||||
* (that is, finalizing the GC-thing will free the allocation), call one of
|
||||
* the following functions:
|
||||
*
|
||||
* Deallocation:
|
||||
* - When the deallocation occurs on a slow path, use:
|
||||
* Foreground::{free_,delete_,array_delete}
|
||||
* JSContext::{malloc_,realloc_,calloc_,new_}
|
||||
* JSRuntime::{malloc_,realloc_,calloc_,new_}
|
||||
*
|
||||
* - Otherwise deallocate on a background thread using a JSContext:
|
||||
* cx->{free_,delete_,array_delete}
|
||||
* These functions accumulate the number of bytes allocated which is used as
|
||||
* part of the GC-triggering heuristic.
|
||||
*
|
||||
* - If no JSContext is available, use a JSRuntime:
|
||||
* rt->{free_,delete_,array_delete}
|
||||
* The difference between the JSContext and JSRuntime versions is that the
|
||||
* cx version reports an out-of-memory error on OOM. (This follows from the
|
||||
* general SpiderMonkey idiom that a JSContext-taking function reports its
|
||||
* own errors.)
|
||||
*
|
||||
* - As a last resort, use UnwantedForeground deallocation:
|
||||
* js::UnwantedForeground::{free_,delete_,array_delete}
|
||||
* - Otherwise, use js_malloc/js_realloc/js_calloc/js_free/js_new
|
||||
*
|
||||
* General tips:
|
||||
* Deallocation:
|
||||
*
|
||||
* - Mixing and matching these allocators is allowed (you may free memory
|
||||
* allocated by any allocator, with any deallocator).
|
||||
* - Ordinarily, use js_free/js_delete.
|
||||
*
|
||||
* - Never, ever use normal C/C++ memory management:
|
||||
* malloc, free, new, new[], delete, operator new, etc.
|
||||
* - For deallocations during GC finalization, use one of the following
|
||||
* operations on the FreeOp provided to the finalizer:
|
||||
*
|
||||
* - Never, ever use low-level SpiderMonkey allocators:
|
||||
* js_malloc(), js_free(), js_calloc(), js_realloc()
|
||||
* Their use is reserved for the other memory managers.
|
||||
* FreeOp::{free_,delete_}
|
||||
*
|
||||
* - Classes which have private constructors or destructors should have
|
||||
* JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR added to their
|
||||
* declaration.
|
||||
*
|
||||
* Details:
|
||||
*
|
||||
* Using vanilla new/new[] is unsafe in SpiderMonkey because they throw on
|
||||
* failure instead of returning NULL, which is what SpiderMonkey expects.
|
||||
* (Even overriding them is unsafe, as the system's C++ runtime library may
|
||||
* throw, which we do not support. We also can't just use the 'nothrow'
|
||||
* variant of new/new[], because we want to mediate *all* allocations
|
||||
* within SpiderMonkey, to satisfy any embedders using
|
||||
* JS_USE_CUSTOM_ALLOCATOR.)
|
||||
*
|
||||
* JSContexts and JSRuntimes keep track of memory allocated, and use this
|
||||
* accounting to schedule GC. OffTheBooks does not. We'd like to remove
|
||||
* OffTheBooks allocations as much as possible (bug 636558).
|
||||
*
|
||||
* On allocation failure, a JSContext correctly reports an error, which a
|
||||
* JSRuntime and OffTheBooks does not.
|
||||
*
|
||||
* A JSContext deallocates in a background thread. A JSRuntime might
|
||||
* deallocate in the background in the future, but does not now. Foreground
|
||||
* deallocation is preferable on slow paths. UnwantedForeground deallocations
|
||||
* occur where we have no JSContext or JSRuntime, and the deallocation is not
|
||||
* on a slow path. We want to remove UnwantedForeground deallocations (bug
|
||||
* 636561).
|
||||
*
|
||||
* JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR makes the allocation
|
||||
* classes friends with your class, giving them access to private
|
||||
* constructors and destructors.
|
||||
*
|
||||
* |make check| does a source level check on the number of uses OffTheBooks,
|
||||
* UnwantedForeground, js_malloc, js_free etc, to prevent regressions. If you
|
||||
* really must add one, update Makefile.in, and run |make check|.
|
||||
*
|
||||
* |make check| also statically prevents the use of vanilla new/new[].
|
||||
* The advantage of these operations is that the memory is batched and freed
|
||||
* on another thread.
|
||||
*/
|
||||
|
||||
#define JS_NEW_BODY(allocator, t, parms) \
|
||||
|
@ -464,190 +423,144 @@ JS_END_EXTERN_C
|
|||
return memory ? new(memory) t parms : NULL;
|
||||
|
||||
/*
|
||||
* Given a class which should provide new_() methods, add
|
||||
* Given a class which should provide 'new' methods, add
|
||||
* JS_DECLARE_NEW_METHODS (see JSContext for a usage example). This
|
||||
* adds new_()s with up to 12 parameters. Add more versions of new_ below if
|
||||
* adds news with up to 12 parameters. Add more versions of new below if
|
||||
* you need more than 12 parameters.
|
||||
*
|
||||
* Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS,
|
||||
* or the build will break.
|
||||
*/
|
||||
#define JS_DECLARE_NEW_METHODS(ALLOCATOR, QUALIFIERS)\
|
||||
#define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS)\
|
||||
template <class T>\
|
||||
QUALIFIERS T *new_() {\
|
||||
QUALIFIERS T *NEWNAME() {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, ())\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1>\
|
||||
QUALIFIERS T *new_(P1 p1) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {\
|
||||
QUALIFIERS T *NEWNAME(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12))\
|
||||
}\
|
||||
static const int JSMinAlignment = 8;\
|
||||
template <class T>\
|
||||
QUALIFIERS T *array_new(size_t n) {\
|
||||
/* The length is stored just before the vector memory. */\
|
||||
uint64_t numBytes64 = uint64_t(JSMinAlignment) + uint64_t(sizeof(T)) * uint64_t(n);\
|
||||
size_t numBytes = size_t(numBytes64);\
|
||||
if (numBytes64 != numBytes) {\
|
||||
JS_ASSERT(0); /* we want to know if this happens in debug builds */\
|
||||
return NULL;\
|
||||
}\
|
||||
void *memory = ALLOCATOR(numBytes);\
|
||||
if (!memory)\
|
||||
return NULL;\
|
||||
*(size_t *)memory = n;\
|
||||
memory = (void*)(uintptr_t(memory) + JSMinAlignment);\
|
||||
return new(memory) T[n];\
|
||||
}\
|
||||
|
||||
JS_DECLARE_NEW_METHODS(js_new, js_malloc, static JS_ALWAYS_INLINE)
|
||||
|
||||
#define JS_DECLARE_DELETE_METHODS(DEALLOCATOR, QUALIFIERS)\
|
||||
template <class T>\
|
||||
QUALIFIERS void delete_(T *p) {\
|
||||
if (p) {\
|
||||
p->~T();\
|
||||
DEALLOCATOR(p);\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
template <class T>\
|
||||
QUALIFIERS void array_delete(T *p) {\
|
||||
if (p) {\
|
||||
void* p0 = (void *)(uintptr_t(p) - js::OffTheBooks::JSMinAlignment);\
|
||||
size_t n = *(size_t *)p0;\
|
||||
for (size_t i = 0; i < n; i++)\
|
||||
(p + i)->~T();\
|
||||
DEALLOCATOR(p0);\
|
||||
}\
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE void
|
||||
js_delete(T *p)
|
||||
{
|
||||
if (p) {
|
||||
p->~T();
|
||||
js_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_malloc()
|
||||
{
|
||||
return (T *)js_malloc(sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_calloc()
|
||||
{
|
||||
return (T *)js_calloc(sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_malloc(size_t numElems)
|
||||
{
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
|
||||
return NULL;
|
||||
return (T *)js_malloc(numElems * sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_calloc(size_t numElems)
|
||||
{
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
|
||||
return NULL;
|
||||
return (T *)js_calloc(numElems * sizeof(T));
|
||||
}
|
||||
|
||||
/*
|
||||
* In general, all allocations should go through a JSContext or JSRuntime, so
|
||||
* that the garbage collector knows how much memory has been allocated. In
|
||||
* cases where it is difficult to use a JSContext or JSRuntime, OffTheBooks can
|
||||
* be used, though this is undesirable.
|
||||
*/
|
||||
namespace js {
|
||||
|
||||
class OffTheBooks {
|
||||
public:
|
||||
JS_DECLARE_NEW_METHODS(::js_malloc, JS_ALWAYS_INLINE static)
|
||||
|
||||
static JS_INLINE void* malloc_(size_t bytes) {
|
||||
return ::js_malloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* calloc_(size_t bytes) {
|
||||
return ::js_calloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* realloc_(void* p, size_t bytes) {
|
||||
return ::js_realloc(p, bytes);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* We generally prefer deallocating using JSContext because it can happen in
|
||||
* the background. On slow paths, we may prefer foreground allocation.
|
||||
*/
|
||||
class Foreground {
|
||||
public:
|
||||
/* See parentheses comment above. */
|
||||
static JS_ALWAYS_INLINE void free_(void* p) {
|
||||
::js_free(p);
|
||||
}
|
||||
|
||||
JS_DECLARE_DELETE_METHODS(::js_free, JS_ALWAYS_INLINE static)
|
||||
};
|
||||
|
||||
class UnwantedForeground : public Foreground {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ScopedFreePtrTraits
|
||||
{
|
||||
typedef T* type;
|
||||
static T* empty() { return NULL; }
|
||||
static void release(T* ptr) { Foreground::free_(ptr); }
|
||||
static void release(T* ptr) { js_free(ptr); }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||
|
||||
template <typename T>
|
||||
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T>
|
||||
{
|
||||
static void release(T *ptr) { Foreground::delete_(ptr); }
|
||||
static void release(T *ptr) { js_delete(ptr); }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Note lack of ; in JSRuntime below. This is intentional so "calling" this
|
||||
* looks "normal".
|
||||
*/
|
||||
#define JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR \
|
||||
friend class js::OffTheBooks;\
|
||||
friend class js::Foreground;\
|
||||
friend class js::UnwantedForeground;\
|
||||
friend struct ::JSContext;\
|
||||
friend struct ::JSRuntime
|
||||
|
||||
/*
|
||||
* The following classes are designed to cause assertions to detect
|
||||
* inadvertent use of guard objects as temporaries. In other words,
|
||||
|
|
|
@ -180,7 +180,7 @@ struct VectorImpl<T, N, AP, true>
|
|||
template <class T, size_t N, class AllocPolicy>
|
||||
class Vector : private AllocPolicy
|
||||
{
|
||||
typedef typename tl::StaticAssert<tl::IsRelocatableHeapType<T>::result>::result _;
|
||||
// typedef typename tl::StaticAssert<!tl::IsPostBarrieredType<T>::result>::result _;
|
||||
|
||||
/* utilities */
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
8a03481ec145a3a0e532637dd52bf80605b7a713
|
||||
4f78a759104eea6e7790c03ce0130299eeaa3968
|
|
@ -1,399 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 jsatom_h___
|
||||
#define jsatom_h___
|
||||
|
||||
#include <stddef.h>
|
||||
#include "jsversion.h"
|
||||
#include "jsalloc.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jslock.h"
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
struct JSIdArray {
|
||||
int length;
|
||||
js::HeapId vector[1]; /* actually, length jsid words */
|
||||
};
|
||||
|
||||
/* Engine-internal extensions of jsid */
|
||||
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
JSID_FROM_BITS(size_t bits)
|
||||
{
|
||||
jsid id;
|
||||
JSID_BITS(id) = bits;
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must not be used on atoms that are representable as integer jsids.
|
||||
* Prefer NameToId or AtomToId over this function:
|
||||
*
|
||||
* A PropertyName is an atom that does not contain an integer in the range
|
||||
* [0, UINT32_MAX]. However, jsid can only hold an integer in the range
|
||||
* [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of
|
||||
* integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
|
||||
* the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most
|
||||
* cases when creating a jsid, code does not have to care about this corner
|
||||
* case because:
|
||||
*
|
||||
* - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
|
||||
* integer atoms representable as integer jsids, and does this conversion.
|
||||
*
|
||||
* - When given a PropertyName*, NameToId can be used which which does not need
|
||||
* to do any dynamic checks.
|
||||
*
|
||||
* Thus, it is only the rare third case which needs this function, which
|
||||
* handles any JSAtom* that is known not to be representable with an int jsid.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
|
||||
{
|
||||
JS_ASSERT(((size_t)atom & 0x7) == 0);
|
||||
jsid id = JSID_FROM_BITS((size_t)atom);
|
||||
JS_ASSERT(id == INTERNED_STRING_TO_JSID(NULL, (JSString*)atom));
|
||||
return id;
|
||||
}
|
||||
|
||||
/* All strings stored in jsids are atomized, but are not necessarily property names. */
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id)
|
||||
{
|
||||
return JSID_IS_STRING(id);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id, JSAtom *atom)
|
||||
{
|
||||
return id == JSID_FROM_BITS((size_t)atom);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSAtom *
|
||||
JSID_TO_ATOM(jsid id)
|
||||
{
|
||||
return (JSAtom *)JSID_TO_STRING(id);
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(js::HashNumber) == 4);
|
||||
JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE js::HashNumber
|
||||
HashId(jsid id)
|
||||
{
|
||||
return HashGeneric(JSID_BITS(id));
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE Value
|
||||
IdToValue(jsid id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
return StringValue(JSID_TO_STRING(id));
|
||||
if (JS_LIKELY(JSID_IS_INT(id)))
|
||||
return Int32Value(JSID_TO_INT(id));
|
||||
if (JS_LIKELY(JSID_IS_OBJECT(id)))
|
||||
return ObjectValue(*JSID_TO_OBJECT(id));
|
||||
JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id) || JSID_IS_VOID(id));
|
||||
return UndefinedValue();
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE jsval
|
||||
IdToJsval(jsid id)
|
||||
{
|
||||
return IdToValue(id);
|
||||
}
|
||||
|
||||
template<>
|
||||
struct DefaultHasher<jsid>
|
||||
{
|
||||
typedef jsid Lookup;
|
||||
static HashNumber hash(const Lookup &l) {
|
||||
return HashNumber(JSID_BITS(l));
|
||||
}
|
||||
static bool match(const jsid &id, const Lookup &l) {
|
||||
return id == l;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a printable, lossless char[] representation of a string-type atom.
|
||||
* The lifetime of the result matches the lifetime of bytes.
|
||||
*/
|
||||
extern const char *
|
||||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes);
|
||||
|
||||
namespace js {
|
||||
|
||||
/* Compute a hash function from chars/length. */
|
||||
inline uint32_t
|
||||
HashChars(const jschar *chars, size_t length)
|
||||
{
|
||||
uint32_t h = 0;
|
||||
for (; length; chars++, length--)
|
||||
h = JS_ROTATE_LEFT32(h, 4) ^ *chars;
|
||||
return h;
|
||||
}
|
||||
|
||||
class AtomStateEntry
|
||||
{
|
||||
uintptr_t bits;
|
||||
|
||||
static const uintptr_t NO_TAG_MASK = uintptr_t(-1) - 1;
|
||||
|
||||
public:
|
||||
AtomStateEntry() : bits(0) {}
|
||||
AtomStateEntry(const AtomStateEntry &other) : bits(other.bits) {}
|
||||
AtomStateEntry(JSAtom *ptr, bool tagged)
|
||||
: bits(uintptr_t(ptr) | uintptr_t(tagged))
|
||||
{
|
||||
JS_ASSERT((uintptr_t(ptr) & 0x1) == 0);
|
||||
}
|
||||
|
||||
bool isTagged() const {
|
||||
return bits & 0x1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-branching code sequence. Note that the const_cast is safe because
|
||||
* the hash function doesn't consider the tag to be a portion of the key.
|
||||
*/
|
||||
void setTagged(bool enabled) const {
|
||||
const_cast<AtomStateEntry *>(this)->bits |= uintptr_t(enabled);
|
||||
}
|
||||
|
||||
JSAtom *asPtr() const;
|
||||
};
|
||||
|
||||
struct AtomHasher
|
||||
{
|
||||
struct Lookup
|
||||
{
|
||||
const jschar *chars;
|
||||
size_t length;
|
||||
const JSAtom *atom; /* Optional. */
|
||||
|
||||
Lookup(const jschar *chars, size_t length) : chars(chars), length(length), atom(NULL) {}
|
||||
inline Lookup(const JSAtom *atom);
|
||||
};
|
||||
|
||||
static HashNumber hash(const Lookup &l) { return HashChars(l.chars, l.length); }
|
||||
static inline bool match(const AtomStateEntry &entry, const Lookup &lookup);
|
||||
};
|
||||
|
||||
typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet;
|
||||
|
||||
/*
|
||||
* On encodings:
|
||||
*
|
||||
* - Some string functions have an optional FlationCoding argument that allow
|
||||
* the caller to force CESU-8 encoding handling.
|
||||
* - Functions that don't take a FlationCoding base their NormalEncoding
|
||||
* behavior on the js_CStringsAreUTF8 value. NormalEncoding is either raw
|
||||
* (simple zero-extension) or UTF-8 depending on js_CStringsAreUTF8.
|
||||
* - Functions that explicitly state their encoding do not use the
|
||||
* js_CStringsAreUTF8 value.
|
||||
*
|
||||
* CESU-8 (Compatibility Encoding Scheme for UTF-16: 8-bit) is a variant of
|
||||
* UTF-8 that allows us to store any wide character string as a narrow
|
||||
* character string. For strings containing mostly ascii, it saves space.
|
||||
* http://www.unicode.org/reports/tr26/
|
||||
*/
|
||||
|
||||
enum FlationCoding
|
||||
{
|
||||
NormalEncoding,
|
||||
CESU8Encoding
|
||||
};
|
||||
|
||||
class PropertyName;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSAtomState
|
||||
{
|
||||
js::AtomSet atoms;
|
||||
|
||||
/*
|
||||
* From this point until the end of struct definition the struct must
|
||||
* contain only js::PropertyName fields. We use this to access the storage
|
||||
* occupied by the common atoms in js_FinishCommonAtoms.
|
||||
*
|
||||
* js_common_atom_names defined in jsatom.cpp contains C strings for atoms
|
||||
* in the order of atom fields here. Therefore you must update that array
|
||||
* if you change member order here.
|
||||
*/
|
||||
|
||||
/* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */
|
||||
js::PropertyName *emptyAtom;
|
||||
|
||||
/*
|
||||
* Literal value and type names.
|
||||
* NB: booleanAtoms must come right before typeAtoms!
|
||||
*/
|
||||
js::PropertyName *booleanAtoms[2];
|
||||
js::PropertyName *typeAtoms[JSTYPE_LIMIT];
|
||||
js::PropertyName *nullAtom;
|
||||
|
||||
/* Standard class constructor or prototype names. */
|
||||
js::PropertyName *classAtoms[JSProto_LIMIT];
|
||||
|
||||
/* Various built-in or commonly-used atoms, pinned on first context. */
|
||||
#define DEFINE_ATOM(id, text) js::PropertyName *id##Atom;
|
||||
#define DEFINE_PROTOTYPE_ATOM(id) js::PropertyName *id##Atom;
|
||||
#define DEFINE_KEYWORD_ATOM(id) js::PropertyName *id##Atom;
|
||||
#include "jsatom.tbl"
|
||||
#undef DEFINE_ATOM
|
||||
#undef DEFINE_PROTOTYPE_ATOM
|
||||
#undef DEFINE_KEYWORD_ATOM
|
||||
|
||||
static const size_t commonAtomsOffset;
|
||||
|
||||
void junkAtoms() {
|
||||
#ifdef DEBUG
|
||||
memset(commonAtomsStart(), JS_FREE_PATTERN, sizeof(*this) - commonAtomsOffset);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSAtom **commonAtomsStart() {
|
||||
return reinterpret_cast<JSAtom **>(&emptyAtom);
|
||||
}
|
||||
|
||||
void checkStaticInvariants();
|
||||
};
|
||||
|
||||
extern bool
|
||||
AtomIsInterned(JSContext *cx, JSAtom *atom);
|
||||
|
||||
#define ATOM(name) js::HandlePropertyName::fromMarkedLocation(&cx->runtime->atomState.name##Atom)
|
||||
|
||||
#define COMMON_ATOM_INDEX(name) \
|
||||
((offsetof(JSAtomState, name##Atom) - JSAtomState::commonAtomsOffset) \
|
||||
/ sizeof(JSAtom*))
|
||||
#define COMMON_TYPE_ATOM_INDEX(type) \
|
||||
((offsetof(JSAtomState, typeAtoms[type]) - JSAtomState::commonAtomsOffset)\
|
||||
/ sizeof(JSAtom*))
|
||||
|
||||
#define NAME_OFFSET(name) offsetof(JSAtomState, name##Atom)
|
||||
#define OFFSET_TO_NAME(rt,off) (*(js::PropertyName **)((char*)&(rt)->atomState + (off)))
|
||||
#define CLASS_NAME_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name])
|
||||
#define CLASS_NAME(cx,name) ((cx)->runtime->atomState.classAtoms[JSProto_##name])
|
||||
|
||||
extern const char *const js_common_atom_names[];
|
||||
extern const size_t js_common_atom_count;
|
||||
|
||||
/*
|
||||
* Macros to access C strings for JSType and boolean literals.
|
||||
*/
|
||||
#define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + (type)])
|
||||
#define JS_TYPE_STR(type) (js_common_atom_names[1 + 2 + (type)])
|
||||
|
||||
/* Type names. */
|
||||
extern const char js_object_str[];
|
||||
extern const char js_undefined_str[];
|
||||
|
||||
/* Well-known predefined C strings. */
|
||||
#define JS_PROTO(name,code,init) extern const char js_##name##_str[];
|
||||
#include "jsproto.tbl"
|
||||
#undef JS_PROTO
|
||||
|
||||
#define DEFINE_ATOM(id, text) extern const char js_##id##_str[];
|
||||
#define DEFINE_PROTOTYPE_ATOM(id)
|
||||
#define DEFINE_KEYWORD_ATOM(id)
|
||||
#include "jsatom.tbl"
|
||||
#undef DEFINE_ATOM
|
||||
#undef DEFINE_PROTOTYPE_ATOM
|
||||
#undef DEFINE_KEYWORD_ATOM
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
extern const char js_close_str[];
|
||||
extern const char js_send_str[];
|
||||
#endif
|
||||
|
||||
/* Constant strings that are not atomized. */
|
||||
extern const char js_getter_str[];
|
||||
extern const char js_setter_str[];
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Initialize atom state. Return true on success, false on failure to allocate
|
||||
* memory. The caller must zero rt->atomState before calling this function and
|
||||
* only call it after js_InitGC successfully returns.
|
||||
*/
|
||||
extern JSBool
|
||||
InitAtomState(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Free and clear atom state including any interned string atoms. This
|
||||
* function must be called before js_FinishGC.
|
||||
*/
|
||||
extern void
|
||||
FinishAtomState(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Atom tracing and garbage collection hooks.
|
||||
*/
|
||||
extern void
|
||||
MarkAtomState(JSTracer *trc);
|
||||
|
||||
extern void
|
||||
SweepAtomState(JSRuntime *rt);
|
||||
|
||||
extern bool
|
||||
InitCommonAtoms(JSContext *cx);
|
||||
|
||||
extern void
|
||||
FinishCommonAtoms(JSRuntime *rt);
|
||||
|
||||
/* N.B. must correspond to boolean tagging behavior. */
|
||||
enum InternBehavior
|
||||
{
|
||||
DoNotInternAtom = false,
|
||||
InternAtom = true
|
||||
};
|
||||
|
||||
extern JSAtom *
|
||||
Atomize(JSContext *cx, const char *bytes, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom,
|
||||
js::FlationCoding fc = js::NormalEncoding);
|
||||
|
||||
extern JSAtom *
|
||||
AtomizeChars(JSContext *cx, const jschar *chars, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
extern JSAtom *
|
||||
AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
inline JSAtom *
|
||||
ToAtom(JSContext *cx, const js::Value &v);
|
||||
|
||||
bool
|
||||
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
|
||||
jsid *idp, MutableHandleValue vp);
|
||||
|
||||
inline bool
|
||||
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp)
|
||||
{
|
||||
RootedValue dummy(cx);
|
||||
return InternNonIntElementId(cx, obj, idval, idp, &dummy);
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRAtom(XDRState<mode> *xdr, JSAtom **atomp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsatom_h___ */
|
|
@ -1,154 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 ft=c: */
|
||||
/* 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/. */
|
||||
|
||||
/*
|
||||
* Declare pre-interned atoms for easy use by SpiderMonkey's C++ code.
|
||||
* These entries define two things, where <id> is the macros' first
|
||||
* argument:
|
||||
*
|
||||
* - js::PropertyName *<id>Atom: a member of JSAtomState pointing to the
|
||||
* atom itself. Usually accessed as cx->runtime->atomState.<id>Atom.
|
||||
*
|
||||
* - const char js_<id>_str[]: a global within SpiderMonkey, holding the
|
||||
* atom's name. Some macros skip this, because it's already defined
|
||||
* elsewhere.
|
||||
*
|
||||
* DEFINE_ATOM(id, name)
|
||||
* Define an atom whose JavaScript string's value is |name|.
|
||||
*
|
||||
* DEFINE_PROTOTYPE_ATOM(id)
|
||||
* Define an atom whose name is the same as one of those defined in
|
||||
* jsproto.tbl. The code that processes that has already declared and
|
||||
* defined the js_<id>_str global, so this defines only the JSAtomState
|
||||
* member.
|
||||
*
|
||||
* DEFINE_KEYWORD_ATOM(id)
|
||||
* Define an atom whose name is the same as one of those defined in
|
||||
* jskeyword.tbl. The code that processes that has already declared and
|
||||
* defined the js_<id>_str global, so this defines only the JSAtomState
|
||||
* member.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
DEFINE_ATOM(anonymous, "anonymous")
|
||||
DEFINE_ATOM(apply, "apply")
|
||||
DEFINE_ATOM(arguments, "arguments")
|
||||
DEFINE_ATOM(arity, "arity")
|
||||
DEFINE_ATOM(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT")
|
||||
DEFINE_ATOM(call, "call")
|
||||
DEFINE_ATOM(callee, "callee")
|
||||
DEFINE_ATOM(caller, "caller")
|
||||
DEFINE_ATOM(classPrototype, "prototype")
|
||||
DEFINE_ATOM(columnNumber, "columnNumber")
|
||||
DEFINE_ATOM(constructor, "constructor")
|
||||
DEFINE_ATOM(each, "each")
|
||||
DEFINE_ATOM(eval, "eval")
|
||||
DEFINE_ATOM(fileName, "fileName")
|
||||
DEFINE_ATOM(get, "get")
|
||||
DEFINE_ATOM(global, "global")
|
||||
DEFINE_ATOM(ignoreCase, "ignoreCase")
|
||||
DEFINE_ATOM(index, "index")
|
||||
DEFINE_ATOM(input, "input")
|
||||
DEFINE_ATOM(toISOString, "toISOString")
|
||||
DEFINE_ATOM(iterator, "iterator")
|
||||
DEFINE_ATOM(iteratorIntrinsic, "__iterator__")
|
||||
DEFINE_ATOM(join, "join")
|
||||
DEFINE_ATOM(lastIndex, "lastIndex")
|
||||
DEFINE_ATOM(length, "length")
|
||||
DEFINE_ATOM(lineNumber, "lineNumber")
|
||||
DEFINE_ATOM(message, "message")
|
||||
DEFINE_ATOM(multiline, "multiline")
|
||||
DEFINE_ATOM(name, "name")
|
||||
DEFINE_ATOM(next, "next")
|
||||
DEFINE_ATOM(noSuchMethod, "__noSuchMethod__")
|
||||
DEFINE_ATOM(objectNull, "[object Null]")
|
||||
DEFINE_ATOM(objectUndefined, "[object Undefined]")
|
||||
DEFINE_ATOM(of, "of")
|
||||
DEFINE_ATOM(proto, "__proto__")
|
||||
DEFINE_ATOM(set, "set")
|
||||
DEFINE_ATOM(source, "source")
|
||||
DEFINE_ATOM(stack, "stack")
|
||||
DEFINE_ATOM(sticky, "sticky")
|
||||
DEFINE_ATOM(toGMTString, "toGMTString")
|
||||
DEFINE_ATOM(toLocaleString, "toLocaleString")
|
||||
DEFINE_ATOM(toSource, "toSource")
|
||||
DEFINE_ATOM(toString, "toString")
|
||||
DEFINE_ATOM(toUTCString, "toUTCString")
|
||||
DEFINE_ATOM(valueOf, "valueOf")
|
||||
DEFINE_ATOM(toJSON, "toJSON")
|
||||
DEFINE_ATOM(void0, "(void 0)")
|
||||
DEFINE_ATOM(enumerable, "enumerable")
|
||||
DEFINE_ATOM(configurable, "configurable")
|
||||
DEFINE_ATOM(writable, "writable")
|
||||
DEFINE_ATOM(value, "value")
|
||||
DEFINE_ATOM(test, "test")
|
||||
DEFINE_ATOM(useStrict, "use strict")
|
||||
DEFINE_ATOM(loc, "loc")
|
||||
DEFINE_ATOM(line, "line")
|
||||
DEFINE_ATOM(Infinity, "Infinity")
|
||||
DEFINE_ATOM(NaN, "NaN")
|
||||
DEFINE_ATOM(builder, "builder")
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
DEFINE_ATOM(etago, "</")
|
||||
DEFINE_ATOM(namespace, "namespace")
|
||||
DEFINE_ATOM(ptagc, "/>")
|
||||
DEFINE_ATOM(qualifier, "::")
|
||||
DEFINE_ATOM(space, " ")
|
||||
DEFINE_ATOM(stago, "<")
|
||||
DEFINE_ATOM(star, "*")
|
||||
DEFINE_ATOM(starQualifier, "*::")
|
||||
DEFINE_ATOM(tagc, ">")
|
||||
DEFINE_ATOM(xml, "xml")
|
||||
DEFINE_ATOM(functionNamespaceURI, "@mozilla.org/js/function")
|
||||
#endif
|
||||
|
||||
DEFINE_PROTOTYPE_ATOM(Proxy)
|
||||
DEFINE_ATOM(getOwnPropertyDescriptor, "getOwnPropertyDescriptor")
|
||||
DEFINE_ATOM(getPropertyDescriptor, "getPropertyDescriptor")
|
||||
DEFINE_ATOM(defineProperty, "defineProperty")
|
||||
DEFINE_KEYWORD_ATOM(delete)
|
||||
DEFINE_ATOM(getOwnPropertyNames, "getOwnPropertyNames")
|
||||
DEFINE_ATOM(enumerate, "enumerate")
|
||||
DEFINE_ATOM(fix, "fix")
|
||||
DEFINE_ATOM(has, "has")
|
||||
DEFINE_ATOM(hasOwn, "hasOwn")
|
||||
DEFINE_ATOM(keys, "keys")
|
||||
DEFINE_ATOM(iterate, "iterate")
|
||||
DEFINE_PROTOTYPE_ATOM(WeakMap)
|
||||
DEFINE_ATOM(buffer, "buffer")
|
||||
DEFINE_ATOM(byteLength, "byteLength")
|
||||
DEFINE_ATOM(byteOffset, "byteOffset")
|
||||
DEFINE_ATOM(shape, "shape")
|
||||
DEFINE_KEYWORD_ATOM(return)
|
||||
DEFINE_KEYWORD_ATOM(throw)
|
||||
DEFINE_ATOM(url, "url")
|
||||
DEFINE_ATOM(innermost, "innermost")
|
||||
|
||||
DEFINE_ATOM(XMLList, "XMLList")
|
||||
DEFINE_ATOM(decodeURI, "decodeURI")
|
||||
DEFINE_ATOM(decodeURIComponent, "decodeURIComponent")
|
||||
DEFINE_ATOM(defineGetter, "__defineGetter__")
|
||||
DEFINE_ATOM(defineSetter, "__defineSetter__")
|
||||
DEFINE_ATOM(encodeURI, "encodeURI")
|
||||
DEFINE_ATOM(encodeURIComponent, "encodeURIComponent")
|
||||
DEFINE_ATOM(escape, "escape")
|
||||
DEFINE_ATOM(hasOwnProperty, "hasOwnProperty")
|
||||
DEFINE_ATOM(isFinite, "isFinite")
|
||||
DEFINE_ATOM(isNaN, "isNaN")
|
||||
DEFINE_ATOM(isPrototypeOf, "isPrototypeOf")
|
||||
DEFINE_ATOM(isXMLName, "isXMLName")
|
||||
DEFINE_ATOM(lookupGetter, "__lookupGetter__")
|
||||
DEFINE_ATOM(lookupSetter, "__lookupSetter__")
|
||||
DEFINE_ATOM(parseFloat, "parseFloat")
|
||||
DEFINE_ATOM(parseInt, "parseInt")
|
||||
DEFINE_ATOM(propertyIsEnumerable, "propertyIsEnumerable")
|
||||
DEFINE_ATOM(unescape, "unescape")
|
||||
DEFINE_ATOM(uneval, "uneval")
|
||||
DEFINE_ATOM(unwatch, "unwatch")
|
||||
DEFINE_ATOM(watch, "watch")
|
||||
DEFINE_ATOM(_CallFunction, "_CallFunction")
|
|
@ -210,9 +210,7 @@ typedef JSType
|
|||
typedef JSObject *
|
||||
(* ObjectOp)(JSContext *cx, HandleObject obj);
|
||||
typedef void
|
||||
(* ClearOp)(JSContext *cx, HandleObject obj);
|
||||
typedef void
|
||||
(* FinalizeOp)(FreeOp *fop, JSObject *obj);
|
||||
(* FinalizeOp)(FreeOp *fop, RawObject obj);
|
||||
|
||||
#define JS_CLASS_MEMBERS \
|
||||
const char *name; \
|
||||
|
@ -308,13 +306,12 @@ struct ObjectOps
|
|||
JSNewEnumerateOp enumerate;
|
||||
TypeOfOp typeOf;
|
||||
ObjectOp thisObject;
|
||||
ClearOp clear;
|
||||
};
|
||||
|
||||
#define JS_NULL_OBJECT_OPS \
|
||||
{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \
|
||||
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \
|
||||
NULL,NULL,NULL,NULL,NULL}
|
||||
NULL,NULL,NULL,NULL}
|
||||
|
||||
struct Class
|
||||
{
|
||||
|
@ -397,10 +394,6 @@ ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
|
|||
inline bool
|
||||
IsObjectWithClass(const Value &v, ESClassValue classValue, JSContext *cx);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
inline bool
|
||||
IsPoisonedSpecialId(js::SpecialId iden)
|
||||
{
|
||||
|
@ -409,14 +402,14 @@ IsPoisonedSpecialId(js::SpecialId iden)
|
|||
return false;
|
||||
}
|
||||
|
||||
template <> struct RootMethods<js::SpecialId>
|
||||
template <> struct RootMethods<SpecialId>
|
||||
{
|
||||
static js::SpecialId initial() { return js::SpecialId(); }
|
||||
static SpecialId initial() { return SpecialId(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(js::SpecialId id) { return IsPoisonedSpecialId(id); }
|
||||
static bool poisoned(SpecialId id) { return IsPoisonedSpecialId(id); }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -13,54 +13,49 @@
|
|||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
|
||||
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallStackFrame(JSContext *cx, JSStackFrame *target);
|
||||
|
||||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#if defined(__cplusplus)
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterScriptCompartment)
|
||||
struct FrameDescription
|
||||
{
|
||||
protected:
|
||||
JSCrossCompartmentCall *call;
|
||||
|
||||
public:
|
||||
AutoEnterScriptCompartment() : call(NULL) {}
|
||||
|
||||
bool enter(JSContext *cx, JSScript *target);
|
||||
|
||||
bool entered() const { return call != NULL; }
|
||||
|
||||
~AutoEnterScriptCompartment() {
|
||||
if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
}
|
||||
JSScript *script;
|
||||
unsigned lineno;
|
||||
JSFunction *fun;
|
||||
};
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterFrameCompartment) : public AutoEnterScriptCompartment
|
||||
struct StackDescription
|
||||
{
|
||||
public:
|
||||
bool enter(JSContext *cx, JSStackFrame *target);
|
||||
unsigned nframes;
|
||||
FrameDescription *frames;
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
extern JS_PUBLIC_API(StackDescription *)
|
||||
DescribeStack(JSContext *cx, unsigned maxFrames);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern JS_PUBLIC_API(void)
|
||||
FreeStackDescription(JSContext *cx, StackDescription *desc);
|
||||
|
||||
extern JS_PUBLIC_API(char *)
|
||||
FormatStackDump(JSContext *cx, char *buf,
|
||||
JSBool showArgs, JSBool showLocals,
|
||||
JSBool showThisProps);
|
||||
|
||||
}
|
||||
|
||||
# ifdef DEBUG
|
||||
JS_FRIEND_API(void) js_DumpValue(const js::Value &val);
|
||||
JS_FRIEND_API(void) js_DumpId(jsid id);
|
||||
JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = NULL);
|
||||
# endif
|
||||
#endif
|
||||
JS_FRIEND_API(void) js_DumpBacktrace(JSContext *cx);
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpBacktrace(JSContext *cx);
|
||||
|
||||
extern JS_PUBLIC_API(JSCompartment *)
|
||||
JS_EnterCompartmentOfScript(JSContext *cx, JSScript *target);
|
||||
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, unsigned indent);
|
||||
|
@ -200,14 +195,16 @@ extern JS_PUBLIC_API(JSPrincipals *)
|
|||
JS_GetScriptOriginPrincipals(JSScript *script);
|
||||
|
||||
/*
|
||||
* Stack Frame Iterator
|
||||
* This function does not work when IonMonkey is active. It remains for legacy
|
||||
* code: caps/principal clamping, which will be removed shortly after
|
||||
* compartment-per-global, and jsd, which can only be used when IonMonkey is
|
||||
* disabled.
|
||||
*
|
||||
* Used to iterate through the JS stack frames to extract
|
||||
* information from the frames.
|
||||
* To find the calling script and line number, use JS_DescribeSciptedCaller.
|
||||
* To summarize the call stack, use JS::DescribeStack.
|
||||
*/
|
||||
|
||||
extern JS_PUBLIC_API(JSStackFrame *)
|
||||
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp);
|
||||
JS_BrokenFrameIterator(JSContext *cx, JSStackFrame **iteratorp);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_GetFrameScript(JSContext *cx, JSStackFrame *fp);
|
||||
|
@ -219,7 +216,7 @@ extern JS_PUBLIC_API(void *)
|
|||
JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation);
|
||||
JS_SetTopFrameAnnotation(JSContext *cx, void *annotation);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp);
|
||||
|
@ -295,6 +292,12 @@ 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);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -397,48 +400,6 @@ js_RevertVersion(JSContext *cx);
|
|||
extern JS_PUBLIC_API(const JSDebugHooks *)
|
||||
JS_GetGlobalDebugHooks(JSRuntime *rt);
|
||||
|
||||
/**
|
||||
* Start any profilers that are available and have been configured on for this
|
||||
* platform. This is NOT thread safe.
|
||||
*
|
||||
* The profileName is used by some profilers to describe the current profiling
|
||||
* run. It may be used for part of the filename of the output, but the
|
||||
* specifics depend on the profiler. Many profilers will ignore it. Passing in
|
||||
* NULL is legal; some profilers may use it to output to stdout or similar.
|
||||
*
|
||||
* Returns true if no profilers fail to start.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_StartProfiling(const char *profileName);
|
||||
|
||||
/**
|
||||
* Stop any profilers that were previously started with JS_StartProfiling.
|
||||
* Returns true if no profilers fail to stop.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_StopProfiling(const char *profileName);
|
||||
|
||||
/**
|
||||
* Write the current profile data to the given file, if applicable to whatever
|
||||
* profiler is being used.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_DumpProfile(const char *outfile, const char *profileName);
|
||||
|
||||
/**
|
||||
* Pause currently active profilers (only supported by some profilers). Returns
|
||||
* whether any profilers failed to pause. (Profilers that do not support
|
||||
* pause/resume do not count.)
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_PauseProfilers(const char *profileName);
|
||||
|
||||
/**
|
||||
* Resume suspended profilers
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_ResumeProfilers(const char *profileName);
|
||||
|
||||
/**
|
||||
* Add various profiling-related functions as properties of the given object.
|
||||
*/
|
||||
|
@ -449,53 +410,6 @@ JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj);
|
|||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_DefineDebuggerObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
/**
|
||||
* The profiling API calls are not able to report errors, so they use a
|
||||
* thread-unsafe global memory buffer to hold the last error encountered. This
|
||||
* should only be called after something returns false.
|
||||
*/
|
||||
JS_PUBLIC_API(const char *)
|
||||
JS_UnsafeGetLastProfilingError();
|
||||
|
||||
#ifdef MOZ_CALLGRIND
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StopCallgrind();
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StartCallgrind();
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_DumpCallgrind(const char *outfile);
|
||||
|
||||
#endif /* MOZ_CALLGRIND */
|
||||
|
||||
#ifdef MOZ_VTUNE
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_StartVtune(const char *profileName);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_StopVtune();
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_PauseVtune();
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_ResumeVtune();
|
||||
|
||||
#endif /* MOZ_VTUNE */
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StartPerf();
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_StopPerf();
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_DumpBytecode(JSContext *cx, JSScript *script);
|
||||
|
||||
|
|
|
@ -151,7 +151,8 @@ 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::Value *statep, jsid *idp);
|
||||
JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
|
||||
js::MutableHandleValue statep, js::MutableHandleId idp);
|
||||
|
||||
struct JSFunctionSpecWithHelp {
|
||||
const char *name;
|
||||
|
@ -183,25 +184,6 @@ JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook);
|
|||
|
||||
namespace js {
|
||||
|
||||
struct RuntimeFriendFields {
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
* as possible.
|
||||
*/
|
||||
volatile int32_t interrupt;
|
||||
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit;
|
||||
|
||||
RuntimeFriendFields()
|
||||
: interrupt(0),
|
||||
nativeStackLimit(0) { }
|
||||
|
||||
static const RuntimeFriendFields *get(const JSRuntime *rt) {
|
||||
return reinterpret_cast<const RuntimeFriendFields *>(rt);
|
||||
}
|
||||
};
|
||||
|
||||
inline JSRuntime *
|
||||
GetRuntime(const JSContext *cx)
|
||||
{
|
||||
|
@ -277,9 +259,6 @@ TraceWeakMaps(WeakMapTracer *trc);
|
|||
extern JS_FRIEND_API(bool)
|
||||
GCThingIsMarkedGray(void *thing);
|
||||
|
||||
extern JS_FRIEND_API(JSCompartment*)
|
||||
GetGCThingCompartment(void *thing);
|
||||
|
||||
typedef void
|
||||
(GCThingCallback)(void *closure, void *gcthing);
|
||||
|
||||
|
@ -397,6 +376,18 @@ NotifyAnimationActivity(RawObject obj);
|
|||
JS_FRIEND_API(bool)
|
||||
IsOriginalScriptFunction(JSFunction *fun);
|
||||
|
||||
/*
|
||||
* Return the outermost enclosing function (script) of the scripted caller.
|
||||
* This function returns NULL in several cases:
|
||||
* - no script is running on the context
|
||||
* - the caller is in global or eval code
|
||||
* In particular, this function will "stop" its outermost search at eval() and
|
||||
* thus it will really return the outermost enclosing function *since the
|
||||
* innermost eval*.
|
||||
*/
|
||||
JS_FRIEND_API(JSScript *)
|
||||
GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx);
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
|
||||
unsigned nargs, unsigned attrs);
|
||||
|
@ -421,10 +412,19 @@ GetFunctionNativeReserved(RawObject fun, size_t which);
|
|||
JS_FRIEND_API(void)
|
||||
SetFunctionNativeReserved(RawObject fun, size_t which, const Value &val);
|
||||
|
||||
inline JSObject *
|
||||
GetObjectProto(RawObject obj)
|
||||
inline bool
|
||||
GetObjectProto(JSContext *cx, JSObject *obj, JSObject **proto)
|
||||
{
|
||||
return reinterpret_cast<const shadow::Object*>(obj)->type->proto;
|
||||
js::Class *clasp = GetObjectClass(obj);
|
||||
if (clasp == &js::ObjectProxyClass ||
|
||||
clasp == &js::OuterWindowProxyClass ||
|
||||
clasp == &js::FunctionProxyClass)
|
||||
{
|
||||
return JS_GetPrototype(cx, obj, proto);
|
||||
}
|
||||
|
||||
*proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void *
|
||||
|
@ -636,8 +636,8 @@ ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip);
|
|||
JS_FRIEND_API(void *)
|
||||
GetOwnerThread(const JSContext *cx);
|
||||
|
||||
JS_FRIEND_API(unsigned)
|
||||
GetContextOutstandingRequests(const JSContext *cx);
|
||||
JS_FRIEND_API(bool)
|
||||
ContextHasOutstandingRequests(const JSContext *cx);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(JSCompartment *)
|
||||
|
@ -677,9 +677,6 @@ typedef Vector<JSCompartment*, 0, SystemAllocPolicy> CompartmentVector;
|
|||
extern JS_FRIEND_API(const CompartmentVector&)
|
||||
GetRuntimeCompartments(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(size_t)
|
||||
SizeOfJSContext();
|
||||
|
||||
#define GCREASONS(D) \
|
||||
/* Reasons internal to the JS engine */ \
|
||||
D(API) \
|
||||
|
@ -836,6 +833,9 @@ NotifyDidPaint(JSRuntime *rt);
|
|||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalGCEnabled(JSRuntime *rt);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableIncrementalGC(JSRuntime *rt);
|
||||
|
||||
|
@ -988,10 +988,10 @@ uint32_t GetListBaseExpandoSlot();
|
|||
* out-of-band for js_DateGet*)
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_DateIsValid(JSContext *cx, JSObject* obj);
|
||||
js_DateIsValid(JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(double)
|
||||
js_DateGetMsecSinceEpoch(JSContext *cx, JSRawObject obj);
|
||||
js_DateGetMsecSinceEpoch(JSRawObject obj);
|
||||
|
||||
/* Implemented in jscntxt.cpp. */
|
||||
|
||||
|
@ -1051,6 +1051,8 @@ typedef uint32_t JSArrayBufferViewType;
|
|||
|
||||
/*
|
||||
* Create a new typed array with nelements elements.
|
||||
*
|
||||
* These functions (except the WithBuffer variants) fill in the array with zeros.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
|
@ -1221,7 +1223,7 @@ JS_GetObjectAsArrayBuffer(JSContext *cx, JSObject *obj, uint32_t *length, uint8_
|
|||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSArrayBufferViewType)
|
||||
JS_GetTypedArrayType(JSObject *obj, JSContext *cx);
|
||||
JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
|
||||
|
@ -1230,7 +1232,7 @@ JS_GetTypedArrayType(JSObject *obj, JSContext *cx);
|
|||
* accessor JSAPI calls defined below.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
JS_IsArrayBufferObject(JSObject *obj, JSContext *cx);
|
||||
JS_IsArrayBufferObject(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return the available byte length of an array buffer.
|
||||
|
@ -1241,11 +1243,12 @@ JS_IsArrayBufferObject(JSObject *obj, JSContext *cx);
|
|||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *cx);
|
||||
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return a pointer to an array buffer's data. The buffer is still owned by the
|
||||
* array buffer object, and should not be modified on another thread.
|
||||
* array buffer object, and should not be modified on another thread. The
|
||||
* returned pointer is stable across GCs.
|
||||
*
|
||||
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
|
||||
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an
|
||||
|
@ -1253,7 +1256,7 @@ JS_GetArrayBufferByteLength(JSObject *obj, JSContext *cx);
|
|||
* builds may be unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetArrayBufferData(JSObject *obj, JSContext *cx);
|
||||
JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return the number of elements in a typed array.
|
||||
|
@ -1315,30 +1318,30 @@ JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx);
|
|||
*/
|
||||
|
||||
extern JS_FRIEND_API(int8_t *)
|
||||
JS_GetInt8ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint8_t *)
|
||||
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(int16_t *)
|
||||
JS_GetInt16ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint16_t *)
|
||||
JS_GetUint16ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(int32_t *)
|
||||
JS_GetInt32ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(uint32_t *)
|
||||
JS_GetUint32ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(float *)
|
||||
JS_GetFloat32ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
extern JS_FRIEND_API(double *)
|
||||
JS_GetFloat64ArrayData(JSObject *obj, JSContext *cx);
|
||||
JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
|
||||
* versions when possible.
|
||||
*/
|
||||
extern JS_FRIEND_API(void *)
|
||||
JS_GetArrayBufferViewData(JSObject *obj, JSContext *cx);
|
||||
JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Check whether obj supports JS_GetDataView* APIs. Note that this may fail and
|
||||
|
@ -1358,7 +1361,7 @@ JS_IsDataViewObject(JSContext *cx, JSObject *obj, JSBool *isDataView);
|
|||
* unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetDataViewByteOffset(JSObject *obj, JSContext *cx);
|
||||
JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return the byte length of a data view.
|
||||
|
@ -1369,7 +1372,7 @@ JS_GetDataViewByteOffset(JSObject *obj, JSContext *cx);
|
|||
* unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
JS_FRIEND_API(uint32_t)
|
||||
JS_GetDataViewByteLength(JSObject *obj, JSContext *cx);
|
||||
JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
/*
|
||||
* Return a pointer to the beginning of the data referenced by a DataView.
|
||||
|
@ -1380,7 +1383,7 @@ JS_GetDataViewByteLength(JSObject *obj, JSContext *cx);
|
|||
* unable to assert when unwrapping should be disallowed.
|
||||
*/
|
||||
JS_FRIEND_API(void *)
|
||||
JS_GetDataViewData(JSObject *obj, JSContext *cx);
|
||||
JS_GetDataViewData(JSObject *obj, JSContext *maybecx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
/*
|
||||
|
@ -1396,10 +1399,17 @@ typedef bool
|
|||
void *specializedThis, unsigned argc, JS::Value *vp);
|
||||
|
||||
struct JSJitInfo {
|
||||
enum OpType {
|
||||
Getter,
|
||||
Setter,
|
||||
Method
|
||||
};
|
||||
|
||||
JSJitPropertyOp op;
|
||||
uint32_t protoID;
|
||||
uint32_t depth;
|
||||
bool isInfallible; /* Is op fallible? Getters only */
|
||||
OpType type;
|
||||
bool isInfallible; /* Is op fallible? False in setters. */
|
||||
bool isConstant; /* Getting a construction-time constant? */
|
||||
};
|
||||
|
||||
|
@ -1420,4 +1430,95 @@ SET_JITINFO(JSFunction * func, const JSJitInfo *info)
|
|||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Engine-internal extensions of jsid. This code is here only until we
|
||||
* eliminate Gecko's dependencies on it!
|
||||
*/
|
||||
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
JSID_FROM_BITS(size_t bits)
|
||||
{
|
||||
jsid id;
|
||||
JSID_BITS(id) = bits;
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must not be used on atoms that are representable as integer jsids.
|
||||
* Prefer NameToId or AtomToId over this function:
|
||||
*
|
||||
* A PropertyName is an atom that does not contain an integer in the range
|
||||
* [0, UINT32_MAX]. However, jsid can only hold an integer in the range
|
||||
* [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of
|
||||
* integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
|
||||
* the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most
|
||||
* cases when creating a jsid, code does not have to care about this corner
|
||||
* case because:
|
||||
*
|
||||
* - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
|
||||
* integer atoms representable as integer jsids, and does this conversion.
|
||||
*
|
||||
* - When given a PropertyName*, NameToId can be used which which does not need
|
||||
* to do any dynamic checks.
|
||||
*
|
||||
* Thus, it is only the rare third case which needs this function, which
|
||||
* handles any JSAtom* that is known not to be representable with an int jsid.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
|
||||
{
|
||||
JS_ASSERT(((size_t)atom & 0x7) == 0);
|
||||
jsid id = JSID_FROM_BITS((size_t)atom);
|
||||
JS_ASSERT(id == INTERNED_STRING_TO_JSID(NULL, (JSString*)atom));
|
||||
return id;
|
||||
}
|
||||
|
||||
/* All strings stored in jsids are atomized, but are not necessarily property names. */
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id)
|
||||
{
|
||||
return JSID_IS_STRING(id);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
JSID_IS_ATOM(jsid id, JSAtom *atom)
|
||||
{
|
||||
return id == JSID_FROM_BITS((size_t)atom);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSAtom *
|
||||
JSID_TO_ATOM(jsid id)
|
||||
{
|
||||
return (JSAtom *)JSID_TO_STRING(id);
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE Value
|
||||
IdToValue(jsid id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
return StringValue(JSID_TO_STRING(id));
|
||||
if (JS_LIKELY(JSID_IS_INT(id)))
|
||||
return Int32Value(JSID_TO_INT(id));
|
||||
if (JS_LIKELY(JSID_IS_OBJECT(id)))
|
||||
return ObjectValue(*JSID_TO_OBJECT(id));
|
||||
JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id) || JSID_IS_VOID(id));
|
||||
return UndefinedValue();
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE jsval
|
||||
IdToJsval(jsid id)
|
||||
{
|
||||
return IdToValue(id);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* jsfriendapi_h___ */
|
||||
|
|
|
@ -43,6 +43,10 @@ class GCHelperThread;
|
|||
struct Shape;
|
||||
struct SliceBudget;
|
||||
|
||||
namespace ion {
|
||||
class IonCode;
|
||||
}
|
||||
|
||||
namespace gc {
|
||||
|
||||
enum State {
|
||||
|
@ -111,6 +115,7 @@ MapAllocToTraceKind(AllocKind thingKind)
|
|||
JSTRACE_STRING, /* FINALIZE_SHORT_STRING */
|
||||
JSTRACE_STRING, /* FINALIZE_STRING */
|
||||
JSTRACE_STRING, /* FINALIZE_EXTERNAL_STRING */
|
||||
JSTRACE_IONCODE, /* FINALIZE_IONCODE */
|
||||
};
|
||||
return map[thingKind];
|
||||
}
|
||||
|
@ -419,6 +424,7 @@ struct ArenaLists {
|
|||
void queueStringsForSweep(FreeOp *fop);
|
||||
void queueShapesForSweep(FreeOp *fop);
|
||||
void queueScriptsForSweep(FreeOp *fop);
|
||||
void queueIonCodeForSweep(FreeOp *fop);
|
||||
|
||||
bool foregroundFinalize(FreeOp *fop, AllocKind thingKind, SliceBudget &sliceBudget);
|
||||
static void backgroundFinalize(FreeOp *fop, ArenaHeader *listHead, bool onBackgroundThread);
|
||||
|
@ -633,8 +639,8 @@ class GCHelperThread {
|
|||
static void freeElementsAndArray(void **array, void **end) {
|
||||
JS_ASSERT(array <= end);
|
||||
for (void **p = array; p != end; ++p)
|
||||
js::Foreground::free_(*p);
|
||||
js::Foreground::free_(array);
|
||||
js_free(*p);
|
||||
js_free(array);
|
||||
}
|
||||
|
||||
static void threadMain(void* arg);
|
||||
|
@ -762,7 +768,7 @@ struct MarkStack {
|
|||
if (ballastcap == 0)
|
||||
return true;
|
||||
|
||||
ballast = (T *)js_malloc(sizeof(T) * ballastcap);
|
||||
ballast = js_pod_malloc<T>(ballastcap);
|
||||
if (!ballast)
|
||||
return false;
|
||||
ballastLimit = ballast + ballastcap;
|
||||
|
@ -843,7 +849,7 @@ struct MarkStack {
|
|||
|
||||
T *newStack;
|
||||
if (stack == ballast) {
|
||||
newStack = (T *)js_malloc(sizeof(T) * newcap);
|
||||
newStack = js_pod_malloc<T>(newcap);
|
||||
if (!newStack)
|
||||
return false;
|
||||
for (T *src = stack, *dst = newStack; src < tos; )
|
||||
|
@ -924,7 +930,8 @@ struct GCMarker : public JSTracer {
|
|||
XmlTag,
|
||||
ArenaTag,
|
||||
SavedValueArrayTag,
|
||||
LastTag = SavedValueArrayTag
|
||||
IonCodeTag,
|
||||
LastTag = IonCodeTag
|
||||
};
|
||||
|
||||
static const uintptr_t StackTagMask = 7;
|
||||
|
@ -961,8 +968,13 @@ struct GCMarker : public JSTracer {
|
|||
void pushXML(JSXML *xml) {
|
||||
pushTaggedPtr(XmlTag, xml);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void pushIonCode(ion::IonCode *code) {
|
||||
pushTaggedPtr(IonCodeTag, code);
|
||||
}
|
||||
|
||||
uint32_t getMarkColor() const {
|
||||
return color;
|
||||
}
|
||||
|
@ -1198,7 +1210,20 @@ MaybeVerifyBarriers(JSContext *cx, bool always = false)
|
|||
} /* namespace gc */
|
||||
|
||||
static inline JSCompartment *
|
||||
GetObjectCompartment(JSObject *obj) { return reinterpret_cast<js::gc::Cell *>(obj)->compartment(); }
|
||||
GetGCThingCompartment(void *thing)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
return reinterpret_cast<gc::Cell *>(thing)->compartment();
|
||||
}
|
||||
|
||||
static inline JSCompartment *
|
||||
GetObjectCompartment(JSObject *obj)
|
||||
{
|
||||
return GetGCThingCompartment(obj);
|
||||
}
|
||||
|
||||
void
|
||||
PurgeJITCaches(JSCompartment *c);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
# define JS_ATOMIC_ADD(p,v) PR_ATOMIC_ADD((int32_t *)(p), (int32_t)(v))
|
||||
# define JS_ATOMIC_SET(p,v) PR_ATOMIC_SET((int32_t *)(p), (int32_t)(v))
|
||||
|
||||
namespace js {
|
||||
unsigned GetCPUCount();
|
||||
}
|
||||
|
||||
#else /* JS_THREADSAFE */
|
||||
|
||||
typedef struct PRThread PRThread;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define JSON_PARSER_BUFSIZE 1024
|
||||
|
||||
extern JSObject *
|
||||
js_InitJSONClass(JSContext *cx, JSObject *obj);
|
||||
js_InitJSONClass(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
extern JSBool
|
||||
js_Stringify(JSContext *cx, js::MutableHandleValue vp,
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set sw=4 ts=8 et tw=80 ft=c:
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
#include "jsversion.h"
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
# define XML_INIT js_InitXMLClass
|
||||
# define NAMESPACE_INIT js_InitNamespaceClass
|
||||
# define QNAME_INIT js_InitQNameClass
|
||||
# define XMLFILTER_INIT js_InitXMLFilterClass
|
||||
#else
|
||||
# define XML_INIT js_InitNullClass
|
||||
# define NAMESPACE_INIT js_InitNullClass
|
||||
# define QNAME_INIT js_InitNullClass
|
||||
# define XMLFILTER_INIT js_InitNullClass
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerator codes in the second column must not change -- they are part of
|
||||
* the JS XDR API. Client modules including jsproto.tbl should consider
|
||||
* wrapping the inclusion with JS_BEGIN_EXTERN_C and JS_END_EXTERN_C.
|
||||
*/
|
||||
JS_PROTO(Null, 0, js_InitNullClass)
|
||||
JS_PROTO(Object, 1, js_InitObjectClass)
|
||||
JS_PROTO(Function, 2, js_InitFunctionClass)
|
||||
JS_PROTO(Array, 3, js_InitArrayClass)
|
||||
JS_PROTO(Boolean, 4, js_InitBooleanClass)
|
||||
JS_PROTO(JSON, 5, js_InitJSONClass)
|
||||
JS_PROTO(Date, 6, js_InitDateClass)
|
||||
JS_PROTO(Math, 7, js_InitMathClass)
|
||||
JS_PROTO(Number, 8, js_InitNumberClass)
|
||||
JS_PROTO(String, 9, js_InitStringClass)
|
||||
JS_PROTO(RegExp, 10, js_InitRegExpClass)
|
||||
JS_PROTO(XML, 11, XML_INIT)
|
||||
JS_PROTO(Namespace, 12, NAMESPACE_INIT)
|
||||
JS_PROTO(QName, 13, QNAME_INIT)
|
||||
JS_PROTO(Error, 14, js_InitExceptionClasses)
|
||||
JS_PROTO(InternalError, 15, js_InitExceptionClasses)
|
||||
JS_PROTO(EvalError, 16, js_InitExceptionClasses)
|
||||
JS_PROTO(RangeError, 17, js_InitExceptionClasses)
|
||||
JS_PROTO(ReferenceError, 18, js_InitExceptionClasses)
|
||||
JS_PROTO(SyntaxError, 19, js_InitExceptionClasses)
|
||||
JS_PROTO(TypeError, 20, js_InitExceptionClasses)
|
||||
JS_PROTO(URIError, 21, js_InitExceptionClasses)
|
||||
JS_PROTO(Iterator, 22, js_InitIteratorClasses)
|
||||
JS_PROTO(StopIteration, 23, js_InitIteratorClasses)
|
||||
JS_PROTO(ArrayBuffer, 24, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Int8Array, 25, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint8Array, 26, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Int16Array, 27, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint16Array, 28, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Int32Array, 29, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint32Array, 30, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Float32Array, 31, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Float64Array, 32, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint8ClampedArray, 33, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Proxy, 34, js_InitProxyClass)
|
||||
JS_PROTO(AnyName, 35, js_InitNullClass)
|
||||
JS_PROTO(WeakMap, 36, js_InitWeakMapClass)
|
||||
JS_PROTO(Map, 37, js_InitMapClass)
|
||||
JS_PROTO(Set, 38, js_InitSetClass)
|
||||
JS_PROTO(DataView, 39, js_InitTypedArrayClasses)
|
||||
JS_PROTO(ParallelArray, 40, js_InitParallelArrayClass)
|
||||
|
||||
#undef XML_INIT
|
||||
#undef NAMESPACE_INIT
|
||||
#undef QNAME_INIT
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* 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 higher-order macro for enumerating all JSProtoKey values. */
|
||||
|
||||
#ifndef jsprototypes_h___
|
||||
#define jsprototypes_h___
|
||||
|
||||
#include "jsversion.h"
|
||||
|
||||
/*
|
||||
* Enumerator codes in the second column must not change -- they are part of
|
||||
* the JS XDR API. Also note the symbols in the third column are extern "C";
|
||||
* clients should use extern "C" {} as appropriate when using this macro.
|
||||
*/
|
||||
|
||||
#define JS_FOR_EACH_PROTOTYPE(macro) \
|
||||
macro(Null, 0, js_InitNullClass) \
|
||||
macro(Object, 1, js_InitObjectClass) \
|
||||
macro(Function, 2, js_InitFunctionClass) \
|
||||
macro(Array, 3, js_InitArrayClass) \
|
||||
macro(Boolean, 4, js_InitBooleanClass) \
|
||||
macro(JSON, 5, js_InitJSONClass) \
|
||||
macro(Date, 6, js_InitDateClass) \
|
||||
macro(Math, 7, js_InitMathClass) \
|
||||
macro(Number, 8, js_InitNumberClass) \
|
||||
macro(String, 9, js_InitStringClass) \
|
||||
macro(RegExp, 10, js_InitRegExpClass) \
|
||||
macro(XML, 11, js_InitXMLClass) \
|
||||
macro(Namespace, 12, js_InitNamespaceClass) \
|
||||
macro(QName, 13, js_InitQNameClass) \
|
||||
macro(Error, 14, js_InitExceptionClasses) \
|
||||
macro(InternalError, 15, js_InitExceptionClasses) \
|
||||
macro(EvalError, 16, js_InitExceptionClasses) \
|
||||
macro(RangeError, 17, js_InitExceptionClasses) \
|
||||
macro(ReferenceError, 18, js_InitExceptionClasses) \
|
||||
macro(SyntaxError, 19, js_InitExceptionClasses) \
|
||||
macro(TypeError, 20, js_InitExceptionClasses) \
|
||||
macro(URIError, 21, js_InitExceptionClasses) \
|
||||
macro(Iterator, 22, js_InitIteratorClasses) \
|
||||
macro(StopIteration, 23, js_InitIteratorClasses) \
|
||||
macro(ArrayBuffer, 24, js_InitTypedArrayClasses) \
|
||||
macro(Int8Array, 25, js_InitTypedArrayClasses) \
|
||||
macro(Uint8Array, 26, js_InitTypedArrayClasses) \
|
||||
macro(Int16Array, 27, js_InitTypedArrayClasses) \
|
||||
macro(Uint16Array, 28, js_InitTypedArrayClasses) \
|
||||
macro(Int32Array, 29, js_InitTypedArrayClasses) \
|
||||
macro(Uint32Array, 30, js_InitTypedArrayClasses) \
|
||||
macro(Float32Array, 31, js_InitTypedArrayClasses) \
|
||||
macro(Float64Array, 32, js_InitTypedArrayClasses) \
|
||||
macro(Uint8ClampedArray, 33, js_InitTypedArrayClasses) \
|
||||
macro(Proxy, 34, js_InitProxyClass) \
|
||||
macro(AnyName, 35, js_InitNullClass) \
|
||||
macro(WeakMap, 36, js_InitWeakMapClass) \
|
||||
macro(Map, 37, js_InitMapClass) \
|
||||
macro(Set, 38, js_InitSetClass) \
|
||||
macro(DataView, 39, js_InitTypedArrayClasses) \
|
||||
macro(ParallelArray, 40, js_InitParallelArrayClass) \
|
||||
|
||||
#endif /* jsprototypes_h___ */
|
|
@ -51,7 +51,7 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||
bool mHasPrototype;
|
||||
protected:
|
||||
// Subclasses may set this in their constructor.
|
||||
void setHasPrototype(bool hasPrototype) { mHasPrototype = hasPrototype; };
|
||||
void setHasPrototype(bool hasPrototype) { mHasPrototype = hasPrototype; }
|
||||
|
||||
public:
|
||||
explicit BaseProxyHandler(void *family);
|
||||
|
@ -112,7 +112,7 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||
virtual bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp);
|
||||
virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
|
||||
virtual JSType typeOf(JSContext *cx, JSObject *proxy);
|
||||
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *proxy);
|
||||
|
@ -123,7 +123,7 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||
virtual void finalize(JSFreeOp *fop, JSObject *proxy);
|
||||
virtual bool getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver,
|
||||
uint32_t index, Value *vp, bool *present);
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **proto);
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
/* See comment for weakmapKeyDelegateOp in jsclass.h. */
|
||||
virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
|
||||
|
@ -165,7 +165,7 @@ class JS_PUBLIC_API(IndirectProxyHandler) : public BaseProxyHandler {
|
|||
Value *argv, Value *rval) MOZ_OVERRIDE;
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp,
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool *bp) MOZ_OVERRIDE;
|
||||
virtual JSType typeOf(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE;
|
||||
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue,
|
||||
|
@ -241,7 +241,7 @@ class Proxy {
|
|||
static bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp);
|
||||
static bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
|
||||
static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
|
||||
static bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
|
||||
static bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
|
||||
static JSType typeOf(JSContext *cx, JSObject *proxy);
|
||||
static bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
|
||||
static JSString *obj_toString(JSContext *cx, JSObject *proxy);
|
||||
|
@ -249,6 +249,9 @@ class Proxy {
|
|||
static bool regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g);
|
||||
static bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
|
||||
static bool iteratorNext(JSContext *cx, JSObject *proxy, Value *vp);
|
||||
static bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
static JSObject * const LazyProto;
|
||||
};
|
||||
|
||||
inline bool IsObjectProxyClass(const Class *clasp)
|
||||
|
@ -352,7 +355,7 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv,
|
|||
JS_BEGIN_EXTERN_C
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
js_InitProxyClass(JSContext *cx, JSObject *obj);
|
||||
js_InitProxyClass(JSContext *cx, JSHandleObject obj);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -47,11 +47,9 @@ typedef uint8_t jssrcnote;
|
|||
typedef uintptr_t jsatomid;
|
||||
|
||||
/* Struct typedefs. */
|
||||
typedef struct JSArgumentFormatMap JSArgumentFormatMap;
|
||||
typedef struct JSGCThing JSGCThing;
|
||||
typedef struct JSGenerator JSGenerator;
|
||||
typedef struct JSNativeEnumerator JSNativeEnumerator;
|
||||
typedef struct JSSharpObjectMap JSSharpObjectMap;
|
||||
typedef struct JSTryNote JSTryNote;
|
||||
|
||||
/* Friend "Advanced API" typedefs. */
|
||||
|
@ -81,7 +79,6 @@ class JSDependentString;
|
|||
class JSExtensibleString;
|
||||
class JSExternalString;
|
||||
class JSLinearString;
|
||||
class JSFixedString;
|
||||
class JSRope;
|
||||
class JSAtom;
|
||||
class JSWrapper;
|
||||
|
@ -179,8 +176,8 @@ namespace frontend {
|
|||
|
||||
struct BytecodeEmitter;
|
||||
struct Definition;
|
||||
struct FunctionBox;
|
||||
struct ObjectBox;
|
||||
class FunctionBox;
|
||||
class ObjectBox;
|
||||
struct Token;
|
||||
struct TokenPos;
|
||||
struct TokenPtr;
|
||||
|
@ -218,12 +215,15 @@ typedef JS::Handle<JSAtom*> HandleAtom;
|
|||
typedef JS::Handle<PropertyName*> HandlePropertyName;
|
||||
|
||||
typedef JS::MutableHandle<Shape*> MutableHandleShape;
|
||||
typedef JS::MutableHandle<JSAtom*> MutableHandleAtom;
|
||||
|
||||
typedef JS::Rooted<Shape*> RootedShape;
|
||||
typedef JS::Rooted<BaseShape*> RootedBaseShape;
|
||||
typedef JS::Rooted<types::TypeObject*> RootedTypeObject;
|
||||
typedef JS::Rooted<JSAtom*> RootedAtom;
|
||||
typedef JS::Rooted<PropertyName*> RootedPropertyName;
|
||||
typedef JSAtom * RawAtom;
|
||||
|
||||
typedef js::Rooted<Shape*> RootedShape;
|
||||
typedef js::Rooted<BaseShape*> RootedBaseShape;
|
||||
typedef js::Rooted<types::TypeObject*> RootedTypeObject;
|
||||
typedef js::Rooted<JSAtom*> RootedAtom;
|
||||
typedef js::Rooted<PropertyName*> RootedPropertyName;
|
||||
|
||||
enum XDRMode {
|
||||
XDR_ENCODE,
|
||||
|
@ -298,7 +298,7 @@ typedef void
|
|||
/* called just before script destruction */
|
||||
typedef void
|
||||
(* JSDestroyScriptHook)(JSFreeOp *fop,
|
||||
JSScript *script,
|
||||
JSRawScript script,
|
||||
void *callerdata);
|
||||
|
||||
typedef void
|
||||
|
@ -370,7 +370,7 @@ typedef JSObject *
|
|||
|
||||
/* Signature for class initialization ops. */
|
||||
typedef JSObject *
|
||||
(* JSClassInitializerOp)(JSContext *cx, JSObject *obj);
|
||||
(* JSClassInitializerOp)(JSContext *cx, JSHandleObject obj);
|
||||
|
||||
/*
|
||||
* Hook that creates an iterator object for a given object. Returns the
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
/*
|
||||
* JS public API typedefs.
|
||||
*/
|
||||
|
||||
#include "jsprototypes.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
/*
|
||||
|
@ -106,8 +108,8 @@ typedef enum JSType {
|
|||
|
||||
/* Dense index into cached prototypes and class atoms for standard objects. */
|
||||
typedef enum JSProtoKey {
|
||||
#define JS_PROTO(name,code,init) JSProto_##name = code,
|
||||
#include "jsproto.tbl"
|
||||
#define PROTOKEY_AND_INITIALIZER(name,code,init) JSProto_##name = code,
|
||||
JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER)
|
||||
#undef JS_PROTO
|
||||
JSProto_LIMIT
|
||||
} JSProtoKey;
|
||||
|
@ -162,6 +164,7 @@ typedef enum {
|
|||
* Trace kinds internal to the engine. The embedding can only them if it
|
||||
* implements JSTraceCallback.
|
||||
*/
|
||||
JSTRACE_IONCODE,
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
JSTRACE_XML,
|
||||
#endif
|
||||
|
@ -200,6 +203,7 @@ typedef struct JSTracer JSTracer;
|
|||
|
||||
#ifdef __cplusplus
|
||||
class JSFlatString;
|
||||
class JSStableString; // long story
|
||||
class JSString;
|
||||
#else
|
||||
typedef struct JSFlatString JSFlatString;
|
||||
|
@ -217,7 +221,7 @@ JS_END_EXTERN_C
|
|||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace JS {
|
||||
namespace js {
|
||||
|
||||
template <typename T>
|
||||
class Rooted;
|
||||
|
@ -237,6 +241,7 @@ enum ThingRootKind
|
|||
THING_ROOT_PROPERTY_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_TYPE,
|
||||
THING_ROOT_BINDINGS,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
||||
|
@ -248,12 +253,18 @@ struct RootKind;
|
|||
* JSAPI users may use JSRooted... types without having the class definition
|
||||
* available.
|
||||
*/
|
||||
template <> struct RootKind<JSObject *> { static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }; };
|
||||
template <> struct RootKind<JSFunction *> { static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }; };
|
||||
template <> struct RootKind<JSString *> { static ThingRootKind rootKind() { return THING_ROOT_STRING; }; };
|
||||
template <> struct RootKind<JSScript *> { static ThingRootKind rootKind() { return THING_ROOT_SCRIPT; }; };
|
||||
template <> struct RootKind<jsid> { static ThingRootKind rootKind() { return THING_ROOT_ID; }; };
|
||||
template <> struct RootKind<Value> { static ThingRootKind rootKind() { return THING_ROOT_VALUE; }; };
|
||||
template<typename T, ThingRootKind Kind>
|
||||
struct SpecificRootKind
|
||||
{
|
||||
static ThingRootKind rootKind() { return Kind; }
|
||||
};
|
||||
|
||||
template <> struct RootKind<JSObject *> : SpecificRootKind<JSObject *, THING_ROOT_OBJECT> {};
|
||||
template <> struct RootKind<JSFunction *> : SpecificRootKind<JSFunction *, THING_ROOT_OBJECT> {};
|
||||
template <> struct RootKind<JSString *> : SpecificRootKind<JSString *, THING_ROOT_STRING> {};
|
||||
template <> struct RootKind<JSScript *> : SpecificRootKind<JSScript *, THING_ROOT_SCRIPT> {};
|
||||
template <> struct RootKind<jsid> : SpecificRootKind<jsid, THING_ROOT_ID> {};
|
||||
template <> struct RootKind<JS::Value> : SpecificRootKind<JS::Value, THING_ROOT_VALUE> {};
|
||||
|
||||
struct ContextFriendFields {
|
||||
JSRuntime *const runtime;
|
||||
|
@ -290,7 +301,34 @@ struct ContextFriendFields {
|
|||
#endif
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
struct RuntimeFriendFields {
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
* as possible.
|
||||
*/
|
||||
volatile int32_t interrupt;
|
||||
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit;
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
/*
|
||||
* Stack allocated GC roots for stack GC heap pointers, which may be
|
||||
* overwritten if moved during a GC.
|
||||
*/
|
||||
Rooted<void*> *thingGCRooters[THING_ROOT_LIMIT];
|
||||
#endif
|
||||
|
||||
RuntimeFriendFields()
|
||||
: interrupt(0),
|
||||
nativeStackLimit(0) { }
|
||||
|
||||
static const RuntimeFriendFields *get(const JSRuntime *rt) {
|
||||
return reinterpret_cast<const RuntimeFriendFields *>(rt);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -264,6 +264,28 @@ Swap(T &t, T &u)
|
|||
u = Move(tmp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool
|
||||
IsPowerOfTwo(T t)
|
||||
{
|
||||
return t && !(t & (t - 1));
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static inline U
|
||||
ComputeByteAlignment(T bytes, U alignment)
|
||||
{
|
||||
JS_ASSERT(IsPowerOfTwo(alignment));
|
||||
return (alignment - (bytes % alignment)) % alignment;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static inline T
|
||||
AlignBytes(T bytes, U alignment)
|
||||
{
|
||||
return bytes + ComputeByteAlignment(bytes, alignment);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE static size_t
|
||||
UnsignedPtrDiff(const void *bigger, const void *smaller)
|
||||
{
|
||||
|
@ -433,8 +455,9 @@ typedef size_t jsbitmap;
|
|||
# define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \
|
||||
JS_BEGIN_MACRO \
|
||||
_Pragma("clang diagnostic push") \
|
||||
/* If these _Pragmas cause warnings for you, try disabling ccache. */ \
|
||||
_Pragma("clang diagnostic ignored \"-Wunused-value\"") \
|
||||
expr; \
|
||||
{ expr; } \
|
||||
_Pragma("clang diagnostic pop") \
|
||||
JS_END_MACRO
|
||||
#elif (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
|
|
|
@ -193,6 +193,11 @@ typedef uint64_t JSValueShiftedTag;
|
|||
#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type)))
|
||||
#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT)
|
||||
|
||||
#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL
|
||||
#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT
|
||||
#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32
|
||||
#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING
|
||||
|
||||
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL
|
||||
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT
|
||||
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED
|
||||
|
@ -219,6 +224,8 @@ typedef enum JSWhyMagic
|
|||
JS_FORWARD_TO_CALL_OBJECT, /* args object element stored in call object */
|
||||
JS_BLOCK_NEEDS_CLONE, /* value of static block object slot */
|
||||
JS_HASH_KEY_EMPTY, /* see class js::HashableValue */
|
||||
JS_ION_ERROR, /* error while running Ion code */
|
||||
JS_ION_BAILOUT, /* status code to signal EnterIon will OSR into Interpret */
|
||||
JS_GENERIC_MAGIC /* for local use */
|
||||
} JSWhyMagic;
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* License, v. 2.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___
|
||||
|
||||
/*
|
||||
* JS configuration macros.
|
||||
*/
|
||||
|
@ -166,3 +169,5 @@
|
|||
# define NEW_OBJECT_REPRESENTATION_ONLY() \
|
||||
MOZ_NOT_REACHED("don't call this! to be used in the new object representation")
|
||||
#endif
|
||||
|
||||
#endif /* jsversion_h___ */
|
||||
|
|
|
@ -208,7 +208,7 @@ class JS_FRIEND_API(DirectWrapper) : public Wrapper, public DirectProxyHandler
|
|||
virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE;
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp) MOZ_OVERRIDE;
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE;
|
||||
virtual bool defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint,
|
||||
|
@ -253,12 +253,13 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public DirectWrapper
|
|||
virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE;
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp) MOZ_OVERRIDE;
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE;
|
||||
virtual bool regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g) MOZ_OVERRIDE;
|
||||
virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp) MOZ_OVERRIDE;
|
||||
virtual bool iteratorNext(JSContext *cx, JSObject *wrapper, Value *vp);
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
static CrossCompartmentWrapper singleton;
|
||||
static CrossCompartmentWrapper singletonWithPrototype;
|
||||
|
@ -311,7 +312,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
|||
virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
|
||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
|
||||
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
|
||||
virtual JSString *obj_toString(JSContext *cx, JSObject *proxy);
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, unsigned indent);
|
||||
|
@ -320,7 +321,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
|||
virtual bool iteratorNext(JSContext *cx, JSObject *proxy, Value *vp);
|
||||
virtual bool getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver,
|
||||
uint32_t index, Value *vp, bool *present);
|
||||
|
||||
virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
|
||||
|
||||
static DeadObjectProxy singleton;
|
||||
};
|
||||
|
@ -351,12 +352,12 @@ UnwrapObject(JSObject *obj, bool stopAtOuter = true, unsigned *flagsp = NULL);
|
|||
// code should never be unwrapping outer window wrappers, we always stop at
|
||||
// outer windows.
|
||||
JS_FRIEND_API(JSObject *)
|
||||
UnwrapObjectChecked(JSContext *cx, JSObject *obj);
|
||||
UnwrapObjectChecked(JSContext *cx, RawObject obj);
|
||||
|
||||
// Unwrap only the outermost security wrapper, with the same semantics as
|
||||
// above. This is the checked version of Wrapper::wrappedObject.
|
||||
JS_FRIEND_API(JSObject *)
|
||||
UnwrapOneChecked(JSContext *cx, JSObject *obj);
|
||||
UnwrapOneChecked(JSContext *cx, HandleObject obj);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsCrossCompartmentWrapper(RawObject obj);
|
||||
|
@ -365,7 +366,7 @@ JSObject *
|
|||
NewDeadProxyObject(JSContext *cx, JSObject *parent);
|
||||
|
||||
void
|
||||
NukeCrossCompartmentWrapper(JSObject *wrapper);
|
||||
NukeCrossCompartmentWrapper(JSContext *cx, JSObject *wrapper);
|
||||
|
||||
bool
|
||||
RemapWrapper(JSContext *cx, JSObject *wobj, JSObject *newTarget);
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#define mozilla_Likely_h_
|
||||
|
||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 2))
|
||||
# define MOZ_LIKELY(x) (__builtin_expect((x), 1))
|
||||
# define MOZ_UNLIKELY(x) (__builtin_expect((x), 0))
|
||||
# define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1))
|
||||
# define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0))
|
||||
#else
|
||||
# define MOZ_LIKELY(x) (x)
|
||||
# define MOZ_UNLIKELY(x) (x)
|
||||
# define MOZ_LIKELY(x) (!!(x))
|
||||
# define MOZ_UNLIKELY(x) (!!(x))
|
||||
#endif
|
||||
|
||||
#endif /* mozilla_Likely_h_ */
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#define mozilla_SHA1_h_
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
class SHA1Sum {
|
||||
union {
|
||||
|
@ -37,9 +39,9 @@ class SHA1Sum {
|
|||
|
||||
public:
|
||||
static const unsigned int HashSize = 20;
|
||||
SHA1Sum();
|
||||
void update(const uint8_t *dataIn, uint32_t len);
|
||||
void finish(uint8_t hashout[20]);
|
||||
MFBT_API() SHA1Sum();
|
||||
MFBT_API(void) update(const void* dataIn, uint32_t len);
|
||||
MFBT_API(void) finish(uint8_t hashout[20]);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,11 @@
|
|||
*
|
||||
* Extension:
|
||||
*
|
||||
* In addition, this header provides class |Scoped| and macro |SCOPED_TEMPLATE|
|
||||
* to simplify the definition of RAII classes for other scenarios. These macros
|
||||
* have been used to automatically close file descriptors/file handles when
|
||||
* reaching the end of the scope, graphics contexts, etc.
|
||||
* In addition, this header provides class |Scoped| and macros |SCOPED_TEMPLATE|
|
||||
* and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE| to simplify the definition
|
||||
* of RAII classes for other scenarios. These macros have been used to
|
||||
* automatically close file descriptors/file handles when reaching the end of
|
||||
* the scope, graphics contexts, etc.
|
||||
*/
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
@ -223,6 +224,48 @@ struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
|
|||
};
|
||||
SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
||||
|
||||
/*
|
||||
* MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE makes it easy to create scoped
|
||||
* pointers for types with custom deleters; just overload
|
||||
* TypeSpecificDelete(T*) in the same namespace as T to call the deleter for
|
||||
* type T.
|
||||
*
|
||||
* @param name The name of the class to define.
|
||||
* @param Type A struct implementing clean-up. See the implementations
|
||||
* for more details.
|
||||
* *param Deleter The function that is used to delete/destroy/free a
|
||||
* non-null value of Type*.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, \
|
||||
* PR_Close)
|
||||
* ...
|
||||
* {
|
||||
* ScopedPRFileDesc file(PR_OpenFile(...));
|
||||
* ...
|
||||
* } // file is closed with PR_Close here
|
||||
*/
|
||||
#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \
|
||||
template <> inline void TypeSpecificDelete(Type * value) { Deleter(value); } \
|
||||
typedef ::mozilla::TypeSpecificScopedPointer<Type> name;
|
||||
|
||||
template <typename T> void TypeSpecificDelete(T * value);
|
||||
|
||||
template <typename T>
|
||||
struct TypeSpecificScopedPointerTraits
|
||||
{
|
||||
typedef T* type;
|
||||
const static type empty() { return NULL; }
|
||||
const static void release(type value)
|
||||
{
|
||||
if (value)
|
||||
TypeSpecificDelete(value);
|
||||
}
|
||||
};
|
||||
|
||||
SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits)
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif // mozilla_Scoped_h_
|
||||
|
|
|
@ -1 +1 @@
|
|||
d30d9e3b35aaae6a2483f9dfbf3318b0650548f3
|
||||
5c425151bd8cd8a816c40f6d414564d333843e2c
|
|
@ -11,6 +11,7 @@
|
|||
#include "jsapi.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Root.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
/*
|
||||
|
@ -172,7 +173,7 @@ class EncapsulatedPtr
|
|||
operator T*() const { return value; }
|
||||
|
||||
protected:
|
||||
void pre() { T::writeBarrierPre(value); }
|
||||
void pre();
|
||||
};
|
||||
|
||||
template <class T, class Unioned = uintptr_t>
|
||||
|
@ -217,6 +218,36 @@ class HeapPtr : public EncapsulatedPtr<T, Unioned>
|
|||
HeapPtr<T2> &v2, T2 *val2);
|
||||
};
|
||||
|
||||
/*
|
||||
* FixedHeapPtr is designed for one very narrow case: replacing immutable raw
|
||||
* pointers to GC-managed things, implicitly converting to a handle type for
|
||||
* ease of use. Pointers encapsulated by this type must:
|
||||
*
|
||||
* be immutable (no incremental write barriers),
|
||||
* never point into the nursery (no generational write barriers), and
|
||||
* be traced via MarkRuntime (we use fromMarkedLocation).
|
||||
*
|
||||
* In short: you *really* need to know what you're doing before you use this
|
||||
* class!
|
||||
*/
|
||||
template <class T>
|
||||
class FixedHeapPtr
|
||||
{
|
||||
T *value;
|
||||
|
||||
public:
|
||||
operator T*() const { return value; }
|
||||
T * operator->() const { return value; }
|
||||
|
||||
operator Handle<T*>() const {
|
||||
return Handle<T*>::fromMarkedLocation(&value);
|
||||
}
|
||||
|
||||
void init(T *ptr) {
|
||||
value = ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
{
|
||||
|
|
|
@ -66,7 +66,8 @@ enum AllocKind {
|
|||
FINALIZE_SHORT_STRING,
|
||||
FINALIZE_STRING,
|
||||
FINALIZE_EXTERNAL_STRING,
|
||||
FINALIZE_LAST = FINALIZE_EXTERNAL_STRING
|
||||
FINALIZE_IONCODE,
|
||||
FINALIZE_LAST = FINALIZE_IONCODE
|
||||
};
|
||||
|
||||
static const unsigned FINALIZE_LIMIT = FINALIZE_LAST + 1;
|
||||
|
@ -103,26 +104,32 @@ struct Cell
|
|||
};
|
||||
|
||||
/*
|
||||
* Page size is 4096 by default, except for SPARC, where it is 8192.
|
||||
* 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.
|
||||
* Bug 692267: Move page size definition to gc/Memory.h and include it
|
||||
* directly once jsgc.h is no longer an installed header.
|
||||
*/
|
||||
#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
|
||||
#if (defined(SOLARIS) || defined(__FreeBSD__)) && \
|
||||
(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;
|
||||
|
||||
const size_t ChunkShift = 20;
|
||||
const size_t ChunkSize = size_t(1) << ChunkShift;
|
||||
const size_t ChunkMask = ChunkSize - 1;
|
||||
|
||||
const size_t ArenaShift = PageShift;
|
||||
const size_t ArenaSize = PageSize;
|
||||
const size_t ArenaMask = ArenaSize - 1;
|
||||
|
||||
/*
|
||||
* This is the maximum number of arenas we allow in the FreeCommitted state
|
||||
* before we trigger a GC_SHRINK to release free arenas to the OS.
|
||||
|
|
|
@ -11,13 +11,11 @@
|
|||
#ifdef __cplusplus
|
||||
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
namespace JS {
|
||||
#include "jspubtd.h"
|
||||
|
||||
/*
|
||||
* Moving GC Stack Rooting
|
||||
|
@ -62,11 +60,24 @@ namespace JS {
|
|||
* separate rooting analysis.
|
||||
*/
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
namespace js {
|
||||
|
||||
template <typename T> class Rooted;
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods { };
|
||||
struct RootMethods {};
|
||||
|
||||
template <typename T>
|
||||
class HandleBase {};
|
||||
|
||||
template <typename T>
|
||||
class MutableHandleBase {};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
|
||||
/*
|
||||
* Handle provides an implicit constructor for NullPtr so that, given:
|
||||
|
@ -83,9 +94,6 @@ struct NullPtr
|
|||
template <typename T>
|
||||
class MutableHandle;
|
||||
|
||||
template <typename T>
|
||||
class HandleBase {};
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -95,7 +103,7 @@ class HandleBase {};
|
|||
* specialization, define a HandleBase<T> specialization containing them.
|
||||
*/
|
||||
template <typename T>
|
||||
class Handle : public HandleBase<T>
|
||||
class Handle : public js::HandleBase<T>
|
||||
{
|
||||
public:
|
||||
/* Creates a handle from a handle of a type convertible to T. */
|
||||
|
@ -136,7 +144,7 @@ class Handle : public HandleBase<T>
|
|||
*/
|
||||
template <typename S>
|
||||
inline
|
||||
Handle(Rooted<S> &root,
|
||||
Handle(js::Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
/* Construct a read only handle from a mutable handle. */
|
||||
|
@ -167,9 +175,6 @@ typedef Handle<JSString*> HandleString;
|
|||
typedef Handle<jsid> HandleId;
|
||||
typedef Handle<Value> HandleValue;
|
||||
|
||||
template <typename T>
|
||||
class MutableHandleBase {};
|
||||
|
||||
/*
|
||||
* Similar to a handle, but the underlying storage can be changed. This is
|
||||
* useful for outparams.
|
||||
|
@ -179,7 +184,7 @@ class MutableHandleBase {};
|
|||
* them.
|
||||
*/
|
||||
template <typename T>
|
||||
class MutableHandle : public MutableHandleBase<T>
|
||||
class MutableHandle : public js::MutableHandleBase<T>
|
||||
{
|
||||
public:
|
||||
template <typename S>
|
||||
|
@ -191,12 +196,12 @@ class MutableHandle : public MutableHandleBase<T>
|
|||
|
||||
template <typename S>
|
||||
inline
|
||||
MutableHandle(Rooted<S> *root,
|
||||
MutableHandle(js::Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
void set(T v)
|
||||
{
|
||||
JS_ASSERT(!RootMethods<T>::poisoned(v));
|
||||
JS_ASSERT(!js::RootMethods<T>::poisoned(v));
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
|
@ -228,14 +233,88 @@ class MutableHandle : public MutableHandleBase<T>
|
|||
void operator =(S v) MOZ_DELETE;
|
||||
};
|
||||
|
||||
typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<JSFunction*> MutableHandleFunction;
|
||||
typedef MutableHandle<JSScript*> MutableHandleScript;
|
||||
typedef MutableHandle<JSString*> MutableHandleString;
|
||||
typedef MutableHandle<jsid> MutableHandleId;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
|
||||
/*
|
||||
* Raw pointer used as documentation that a parameter does not need to be
|
||||
* rooted.
|
||||
*/
|
||||
typedef JSObject * RawObject;
|
||||
typedef JSFunction * RawFunction;
|
||||
typedef JSScript * RawScript;
|
||||
typedef JSString * RawString;
|
||||
typedef jsid RawId;
|
||||
typedef Value RawValue;
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* InternalHandle is a handle to an internal pointer into a gcthing. Use
|
||||
* InternalHandle when you have a pointer to a direct field of a gcthing, or
|
||||
* when you need a parameter type for something that *may* be a pointer to a
|
||||
* direct field of a gcthing.
|
||||
*/
|
||||
template <typename T>
|
||||
class InternalHandle { };
|
||||
|
||||
template <typename T>
|
||||
class InternalHandle<T*>
|
||||
{
|
||||
void * const *holder;
|
||||
size_t offset;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Create an InternalHandle using a Handle to the gcthing containing the
|
||||
* field in question, and a pointer to the field.
|
||||
*/
|
||||
template<typename H>
|
||||
InternalHandle(const JS::Handle<H> &handle, T *field)
|
||||
: holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get()))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an InternalHandle to a field within a Rooted<>.
|
||||
*/
|
||||
template<typename R>
|
||||
InternalHandle(const Rooted<R> &root, T *field)
|
||||
: holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
|
||||
{
|
||||
}
|
||||
|
||||
T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
|
||||
|
||||
const T& operator *() const { return *get(); }
|
||||
T* operator ->() const { return get(); }
|
||||
|
||||
static InternalHandle<T*> fromMarkedLocation(T *fieldPtr) {
|
||||
return InternalHandle(fieldPtr);
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* Create an InternalHandle to something that is not a pointer to a
|
||||
* gcthing, and so does not need to be rooted in the first place. Use these
|
||||
* InternalHandles to pass pointers into functions that also need to accept
|
||||
* regular InternalHandles to gcthing fields.
|
||||
*
|
||||
* Make this private to prevent accidental misuse; this is only for
|
||||
* fromMarkedLocation().
|
||||
*/
|
||||
InternalHandle(T *field)
|
||||
: holder(reinterpret_cast<void * const *>(&NullPtr::constNullValue)),
|
||||
offset(uintptr_t(field))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* By default, pointers should use the inheritance hierarchy to find their
|
||||
|
@ -243,7 +322,7 @@ typedef JSObject * RawObject;
|
|||
* Rooted<T> may be used without the class definition being available.
|
||||
*/
|
||||
template <typename T>
|
||||
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); }; };
|
||||
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); } };
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods<T *>
|
||||
|
@ -253,6 +332,12 @@ struct RootMethods<T *>
|
|||
static bool poisoned(T *v) { return IsPoisonedPtr(v); }
|
||||
};
|
||||
|
||||
#if !(defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING))
|
||||
// Defined in vm/String.h.
|
||||
template <>
|
||||
class Rooted<JSStableString *>;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
class RootedBase {};
|
||||
|
||||
|
@ -267,10 +352,10 @@ class RootedBase {};
|
|||
template <typename T>
|
||||
class Rooted : public RootedBase<T>
|
||||
{
|
||||
void init(JSContext *cx_)
|
||||
void init(JSContext *cxArg)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cx_);
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cxArg);
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Rooted<T>**>(&cx->thingGCRooters[kind]);
|
||||
|
@ -281,9 +366,52 @@ class Rooted : public RootedBase<T>
|
|||
#endif
|
||||
}
|
||||
|
||||
void init(JSRuntime *rtArg)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
RuntimeFriendFields *rt = const_cast<RuntimeFriendFields *>(RuntimeFriendFields::get(rtArg));
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Rooted<T>**>(&rt->thingGCRooters[kind]);
|
||||
this->prev = *stack;
|
||||
*stack = this;
|
||||
|
||||
JS_ASSERT(!RootMethods<T>::poisoned(ptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
Rooted(JSContext *cx) : ptr(RootMethods<T>::initial()) { init(cx); }
|
||||
Rooted(JSContext *cx, T initial) : ptr(initial) { init(cx); }
|
||||
Rooted(JSRuntime *rt
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(RootMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(rt);
|
||||
}
|
||||
|
||||
Rooted(JSRuntime *rt, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(rt);
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(RootMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
~Rooted()
|
||||
{
|
||||
|
@ -318,40 +446,15 @@ class Rooted : public RootedBase<T>
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
Rooted<T> **stack, *prev;
|
||||
#endif
|
||||
T ptr;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
Rooted() MOZ_DELETE;
|
||||
Rooted(const Rooted &) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
|
@ -367,7 +470,7 @@ typedef Rooted<Value> RootedValue;
|
|||
*/
|
||||
class SkipRoot
|
||||
{
|
||||
#if defined(DEBUG) && defined(JSGC_ROOT_ANALYSIS)
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
|
||||
SkipRoot **stack, *prev;
|
||||
const uint8_t *start;
|
||||
|
@ -419,64 +522,123 @@ class SkipRoot
|
|||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(js::Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(js::Rooted<S> *root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void) EnterAssertNoGCScope();
|
||||
JS_FRIEND_API(void) LeaveAssertNoGCScope();
|
||||
JS_FRIEND_API(bool) InNoGCScope();
|
||||
|
||||
/*
|
||||
* This typedef is to annotate parameters that we have manually verified do not
|
||||
* need rooting, as opposed to parameters that have not yet been considered.
|
||||
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
|
||||
* attempted while the guard object is live. If you have a GC-unsafe operation
|
||||
* to perform, use this guard object to protect your operation.
|
||||
*/
|
||||
typedef JSObject *RawObject;
|
||||
class AutoAssertNoGC
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_FRIEND_API(bool) IsRootingUnnecessaryForContext(JSContext *cx);
|
||||
JS_FRIEND_API(void) SetRootingUnnecessaryForContext(JSContext *cx, bool value);
|
||||
JS_FRIEND_API(bool) RelaxRootChecksForContext(JSContext *cx);
|
||||
#endif
|
||||
|
||||
class AssertRootingUnnecessary {
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
#ifdef DEBUG
|
||||
JSContext *cx;
|
||||
bool prev;
|
||||
#endif
|
||||
public:
|
||||
AssertRootingUnnecessary(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
AutoAssertNoGC(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
#ifdef DEBUG
|
||||
this->cx = cx;
|
||||
prev = IsRootingUnnecessaryForContext(cx);
|
||||
SetRootingUnnecessaryForContext(cx, true);
|
||||
EnterAssertNoGCScope();
|
||||
#endif
|
||||
}
|
||||
|
||||
~AssertRootingUnnecessary() {
|
||||
~AutoAssertNoGC() {
|
||||
#ifdef DEBUG
|
||||
SetRootingUnnecessaryForContext(cx, prev);
|
||||
LeaveAssertNoGCScope();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* AssertCanGC will assert if it is called inside of an AutoAssertNoGC region.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
JS_ALWAYS_INLINE void
|
||||
AssertCanGC()
|
||||
{
|
||||
JS_ASSERT(!InNoGCScope());
|
||||
}
|
||||
#else
|
||||
# define AssertCanGC()
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
extern void
|
||||
CheckStackRoots(JSContext *cx);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(bool) NeedRelaxedRootChecks();
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Hook for dynamic root analysis. Checks the native stack and poisons
|
||||
* references to GC things which have not been rooted.
|
||||
*/
|
||||
inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!IsRootingUnnecessaryForContext(cx));
|
||||
# if defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
if (relax && RelaxRootChecksForContext(cx))
|
||||
AssertCanGC();
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
if (relax && NeedRelaxedRootChecks())
|
||||
return;
|
||||
CheckStackRoots(cx);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
namespace gc {
|
||||
struct Cell;
|
||||
} /* namespace gc */
|
||||
|
||||
/* Base class for automatic read-only object rooting during compilation. */
|
||||
class CompilerRootNode
|
||||
{
|
||||
protected:
|
||||
CompilerRootNode(js::gc::Cell *ptr)
|
||||
: next(NULL), ptr(ptr)
|
||||
{ }
|
||||
|
||||
public:
|
||||
void **address() { return (void **)&ptr; }
|
||||
|
||||
public:
|
||||
CompilerRootNode *next;
|
||||
|
||||
protected:
|
||||
js::gc::Cell *ptr;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue