Merge remote branch 'upstream/gles20' into gles20

This commit is contained in:
johnangel 2013-01-11 21:48:47 +01:00
commit a1155f52e6
172 changed files with 5161 additions and 5057 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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;
};

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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)

View File

@ -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__ */

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -52,5 +52,6 @@
#include "physics_nodes/CCPhysicsSprite.h"
#endif
#endif /* __COCOS2D_EXT_H__ */

View File

@ -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" />

View File

@ -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
external/sqlite3/Android.mk vendored Normal file
View File

View File

@ -0,0 +1 @@
d5fbb9a1bda9fdaefc9ff04c2c63ab8b02c93709

447
external/sqlite3/include/sqlite3ext.h vendored Normal file
View File

@ -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_ */

View File

@ -0,0 +1 @@
b5bf8f14c59b82e556d56af620a029dba2d0be3b

View File

@ -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();

View File

@ -1 +1 @@
4e53e096b4a054e3817b30692cff2b40dafce521
3d27ac9829ac45f2433d903b6b4f359a8e20636f

View File

@ -1 +1 @@
8c25f4e08196498edb3752dc9672b14525454fd7
1f510de34b422f771994acc6642ef828eb42340a

View File

@ -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>

View File

@ -1 +1 @@
9d5b1248e92a3f45928c60181236b6a3c3e7617f
2e242c0171e848d248e90070640ddf579e07ec13

View File

@ -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

View File

@ -1 +1 @@
55b8526c01c19734df75118031b5655cc1744422
71b990c76b9563a422db95317ef07720122f9617

View File

@ -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>

View File

@ -0,0 +1 @@
256ff6e456360f571ae24d610f20eaf087c174b9

View File

@ -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>

View File

@ -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_);

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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">

View File

@ -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>
{

View File

@ -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.

View File

@ -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 */

View File

@ -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,

View File

@ -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}")

View File

@ -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 */

View File

@ -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);

View File

@ -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,

View File

@ -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 */

View File

@ -1 +1 @@
8a03481ec145a3a0e532637dd52bf80605b7a713
4f78a759104eea6e7790c03ce0130299eeaa3968

View File

@ -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___ */

View File

@ -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")

View File

@ -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 */

View File

@ -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);

View File

@ -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___ */

View File

@ -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 */

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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___ */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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___ */

View File

@ -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);

View File

@ -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_ */

View File

@ -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]);
};
}

View File

@ -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_

View File

@ -1 +1 @@
22a636cde41437897d9f7dbccdbcb871065f48ec
a0001da73e82abc77d183d416ca2b4b97e9e9ee1

View File

@ -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>
{

View File

@ -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.

View File

@ -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 */

View File

@ -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,

View File

@ -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}")

View File

@ -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 */

View File

@ -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);

View File

@ -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,

View File

@ -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 */

View File

@ -1 +1 @@
8a03481ec145a3a0e532637dd52bf80605b7a713
4f78a759104eea6e7790c03ce0130299eeaa3968

View File

@ -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___ */

View File

@ -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")

View File

@ -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 */

View File

@ -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);

View File

@ -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___ */

View File

@ -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 */

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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___ */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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___ */

View File

@ -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);

View File

@ -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_ */

View File

@ -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]);
};
}

View File

@ -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_

View File

@ -1 +1 @@
d30d9e3b35aaae6a2483f9dfbf3318b0650548f3
5c425151bd8cd8a816c40f6d414564d333843e2c

View File

View File

@ -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>
{

View File

@ -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.

322
scripting/javascript/spidermonkey-win32/include/gc/Root.h Executable file → Normal file
View File

@ -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