Merge the last PGO green changeset of mozilla-inbound into mozilla-central

This commit is contained in:
Ehsan Akhgari 2012-05-07 19:02:53 -04:00
commit 70b3320cf1
85 changed files with 1291 additions and 973 deletions

View File

@ -49,7 +49,6 @@
#include "nsIDOMWindow.h"
#include "nsIFrame.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIPresShell.h"
@ -168,23 +167,6 @@ void nsAccessNode::InitXPAccessibility()
if (prefBranch) {
prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
}
NotifyA11yInitOrShutdown(true);
}
// nsAccessNode protected static
void nsAccessNode::NotifyA11yInitOrShutdown(bool aIsInit)
{
nsCOMPtr<nsIObserverService> obsService =
mozilla::services::GetObserverService();
NS_ASSERTION(obsService, "No observer service to notify of a11y init/shutdown");
if (!obsService)
return;
static const PRUnichar kInitIndicator[] = { '1', 0 };
static const PRUnichar kShutdownIndicator[] = { '0', 0 };
obsService->NotifyObservers(nsnull, "a11y-init-or-shutdown",
aIsInit ? kInitIndicator : kShutdownIndicator);
}
void nsAccessNode::ShutdownXPAccessibility()
@ -202,8 +184,6 @@ void nsAccessNode::ShutdownXPAccessibility()
gApplicationAccessible->Shutdown();
NS_RELEASE(gApplicationAccessible);
}
NotifyA11yInitOrShutdown(false);
}
RootAccessible*

View File

@ -164,11 +164,6 @@ protected:
nsCOMPtr<nsIContent> mContent;
nsDocAccessible* mDoc;
/**
* Notify global nsIObserver's that a11y is getting init'd or shutdown.
*/
static void NotifyA11yInitOrShutdown(bool aIsInit);
// Static data, we do our own refcounting for our static data.
static nsIStringBundle* gStringBundle;

View File

@ -1271,6 +1271,9 @@ nsAccessibilityService::Init()
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
static const PRUnichar kInitIndicator[] = { '1', 0 };
observerService->NotifyObservers(nsnull, "a11y-init-or-shutdown", kInitIndicator);
// Initialize accessibility.
nsAccessNodeWrap::InitAccessibility();
@ -1284,9 +1287,13 @@ nsAccessibilityService::Shutdown()
// Remove observers.
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService)
if (observerService) {
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
static const PRUnichar kShutdownIndicator[] = { '0', 0 };
observerService->NotifyObservers(nsnull, "a11y-init-or-shutdown", kShutdownIndicator);
}
// Stop accessible document loader.
nsAccDocManager::Shutdown();

View File

@ -4617,7 +4617,7 @@ GetFloat32Array(JSContext* aCx, const JS::Value& aValue)
return ErrorInvalidOperation("%s: This uniform location is obsolete since the program has been relinked", info); \
GLint location = location_object->Location();
#define SIMPLE_ARRAY_METHOD_UNIFORM(name, cnt, arrayType, ptrType) \
#define SIMPLE_ARRAY_METHOD_UNIFORM(name, expectedElemSize, arrayType, ptrType) \
NS_IMETHODIMP \
WebGLContext::name(nsIWebGLUniformLocation *aLocation, const JS::Value& aValue, \
JSContext* aCx) \
@ -4638,38 +4638,36 @@ WebGLContext::name##_base(WebGLUniformLocation *location_object,
} \
\
OBTAIN_UNIFORM_LOCATION(#name ": location") \
int elementSize = location_object->ElementSize(); \
if (cnt != elementSize) { \
int uniformElemSize = location_object->ElementSize(); \
if (expectedElemSize != uniformElemSize) { \
return ErrorInvalidOperation( \
#name ": this function expected a uniform of element size %d," \
" got a uniform of element size %d", \
cnt, \
elementSize); \
expectedElemSize, \
uniformElemSize); \
} \
const WebGLUniformInfo& info = location_object->Info(); \
PRUint32 expectedArrayLength = cnt * info.arraySize; \
if (arrayLength < expectedArrayLength || \
(arrayLength % cnt)) \
if (arrayLength == 0 || \
arrayLength % expectedElemSize) \
{ \
return ErrorInvalidValue("%s: expected an array of length a multiple of" \
" %d and at least %d, got an array of length %d", \
" %d, got an array of length %d", \
#name, \
cnt, \
expectedArrayLength, \
expectedElemSize, \
arrayLength); \
} \
if (!info.isArray && \
arrayLength > expectedArrayLength) { \
arrayLength != expectedElemSize) { \
return ErrorInvalidOperation("%s: expected an array of length exactly %d" \
" (since this uniform is not an array uniform)," \
" got an array of length %d", \
" got an array of length %d", \
#name, \
expectedArrayLength, \
expectedElemSize, \
arrayLength); \
} \
\
MakeContextCurrent(); \
gl->f##name(location, info.arraySize, data); \
PRUint32 numElementsToUpload = NS_MIN(info.arraySize, arrayLength/expectedElemSize); \
gl->f##name(location, numElementsToUpload, data); \
}
#define SIMPLE_MATRIX_METHOD_UNIFORM(name, dim) \
@ -4690,38 +4688,37 @@ WebGLContext::name##_base(WebGLUniformLocation* location_object,
WebGLboolean aTranspose, uint32_t arrayLength, \
float* data) \
{ \
PRUint32 expectedElemSize = (dim)*(dim); \
if (!IsContextStable()) { \
return; \
} \
\
OBTAIN_UNIFORM_LOCATION(#name ": location") \
int elementSize = location_object->ElementSize(); \
if (dim*dim != elementSize) { \
PRUint32 uniformElemSize = location_object->ElementSize(); \
if (expectedElemSize != uniformElemSize) { \
return ErrorInvalidOperation( \
#name ": this function expected a uniform of element size %d," \
" got a uniform of element size %d", \
dim*dim, \
elementSize); \
expectedElemSize, \
uniformElemSize); \
} \
const WebGLUniformInfo& info = location_object->Info(); \
PRUint32 expectedArrayLength = dim * dim * info.arraySize; \
if (arrayLength < expectedArrayLength || \
(arrayLength % (dim*dim))) \
if (arrayLength == 0 || \
arrayLength % expectedElemSize) \
{ \
return ErrorInvalidValue("%s: expected an array of length a multiple of" \
" %d and at least %d, got an array of length %d", \
" %d, got an array of length %d", \
#name, \
dim*dim, \
expectedArrayLength, \
expectedElemSize, \
arrayLength); \
} \
if (!info.isArray && \
arrayLength > expectedArrayLength) { \
if (!info.isArray && \
arrayLength != expectedElemSize) { \
return ErrorInvalidOperation("%s: expected an array of length exactly %d" \
" (since this uniform is not an array uniform)," \
" got an array of length %d", \
#name, \
expectedArrayLength, \
expectedElemSize, \
arrayLength); \
} \
if (aTranspose) { \
@ -4730,7 +4727,8 @@ WebGLContext::name##_base(WebGLUniformLocation* location_object,
} \
\
MakeContextCurrent(); \
gl->f##name(location, info.arraySize, false, data); \
PRUint32 numElementsToUpload = NS_MIN(info.arraySize, arrayLength/(expectedElemSize)); \
gl->f##name(location, numElementsToUpload, false, data); \
}
#define SIMPLE_METHOD_UNIFORM_1(glname, name, t1) \

View File

@ -766,55 +766,38 @@ MediaStreamGraphImpl::GetAudioPosition(MediaStream* aStream)
if (!aStream->mAudioOutput) {
return mCurrentTime;
}
PRInt64 positionInFrames = aStream->mAudioOutput->GetPositionInFrames();
if (positionInFrames < 0) {
return mCurrentTime;
}
return aStream->mAudioPlaybackStartTime +
TicksToTimeRoundDown(aStream->mAudioOutput->GetRate(),
aStream->mAudioOutput->GetPositionInFrames());
positionInFrames);
}
void
MediaStreamGraphImpl::UpdateCurrentTime()
{
GraphTime prevCurrentTime = mCurrentTime;
TimeStamp now = TimeStamp::Now();
// The earliest buffer end time for streams that haven't finished. We can't
// advance the current time past this point.
GraphTime minBufferEndTime = GRAPH_TIME_MAX;
for (PRUint32 i = 0; i < mStreams.Length(); ++i) {
MediaStream* stream = mStreams[i];
GraphTime blockedBufferEndTime =
StreamTimeToGraphTime(stream, stream->GetBufferEnd(), INCLUDE_TRAILING_BLOCKED_INTERVAL);
if (stream->mAudioOutput &&
(!stream->mFinished || mBlockingDecisionsMadeUntilTime <= blockedBufferEndTime)) {
// XXX We should take audio positions into account when determining how
// far to advance the current time. Basically the current time should
// track the average or minimum of the audio positions. We don't do this
// currently since the audio positions aren't accurate enough. This
// logging code is helpful to track the accuracy of audio positions.
GraphTime audioPosition = GetAudioPosition(stream);
LOG(PR_LOG_DEBUG, ("Audio position for stream %p is %f", stream,
MediaTimeToSeconds(audioPosition)));
}
if (!stream->mFinished) {
minBufferEndTime = NS_MIN(minBufferEndTime, blockedBufferEndTime);
}
}
NS_ASSERTION(mCurrentTime <= minBufferEndTime,
"We shouldn't have already advanced beyond buffer end!");
GraphTime nextCurrentTime =
SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds()) + mCurrentTime;
if (minBufferEndTime < nextCurrentTime) {
LOG(PR_LOG_WARNING, ("Reducing current time to minimum buffer end"));
nextCurrentTime = minBufferEndTime;
if (mBlockingDecisionsMadeUntilTime < nextCurrentTime) {
LOG(PR_LOG_WARNING, ("Media graph global underrun detected"));
LOG(PR_LOG_DEBUG, ("Advancing mBlockingDecisionsMadeUntilTime from %f to %f",
MediaTimeToSeconds(mBlockingDecisionsMadeUntilTime),
MediaTimeToSeconds(nextCurrentTime)));
// Advance mBlockingDecisionsMadeUntilTime to nextCurrentTime by
// adding blocked time to all streams starting at mBlockingDecisionsMadeUntilTime
for (PRUint32 i = 0; i < mStreams.Length(); ++i) {
mStreams[i]->mBlocked.SetAtAndAfter(mBlockingDecisionsMadeUntilTime, true);
}
mBlockingDecisionsMadeUntilTime = nextCurrentTime;
}
mCurrentTimeStamp = now;
mBlockingDecisionsMadeUntilTime =
NS_MAX(nextCurrentTime, mBlockingDecisionsMadeUntilTime);
LOG(PR_LOG_DEBUG, ("Updating current time to %f (minBufferEndTime %f, real %f, mBlockingDecisionsMadeUntilTime %f)",
LOG(PR_LOG_DEBUG, ("Updating current time to %f (real %f, mBlockingDecisionsMadeUntilTime %f)",
MediaTimeToSeconds(nextCurrentTime),
MediaTimeToSeconds(minBufferEndTime),
(now - mInitialTimeStamp).ToSeconds(),
MediaTimeToSeconds(mBlockingDecisionsMadeUntilTime)));

View File

@ -315,11 +315,16 @@ class AudioShutdownEvent : public nsRunnable
#define PREF_VOLUME_SCALE "media.volume_scale"
#define PREF_USE_CUBEB "media.use_cubeb"
#define PREF_CUBEB_LATENCY "media.cubeb_latency_ms"
static mozilla::Mutex* gAudioPrefsLock = nsnull;
static double gVolumeScale = 1.0;
static bool gUseCubeb = false;
// Arbitrary default stream latency. The higher this value, the longer stream
// volume changes will take to become audible.
static PRUint32 gCubebLatency = 100;
static int PrefChanged(const char* aPref, void* aClosure)
{
if (strcmp(aPref, PREF_VOLUME_SCALE) == 0) {
@ -335,6 +340,10 @@ static int PrefChanged(const char* aPref, void* aClosure)
bool value = Preferences::GetBool(aPref, true);
mozilla::MutexAutoLock lock(*gAudioPrefsLock);
gUseCubeb = value;
} else if (strcmp(aPref, PREF_CUBEB_LATENCY) == 0) {
PRUint32 value = Preferences::GetUint(aPref);
mozilla::MutexAutoLock lock(*gAudioPrefsLock);
gCubebLatency = NS_MIN<PRUint32>(NS_MAX<PRUint32>(value, 20), 1000);
}
return 0;
}
@ -364,6 +373,12 @@ static cubeb* GetCubebContext()
NS_WARNING("cubeb_init failed");
return nsnull;
}
static PRUint32 GetCubebLatency()
{
mozilla::MutexAutoLock lock(*gAudioPrefsLock);
return gCubebLatency;
}
#endif
void nsAudioStream::InitLibrary()
@ -805,6 +820,71 @@ public:
static void Release(cubeb_stream* aStream) { cubeb_stream_destroy(aStream); }
};
class nsCircularByteBuffer
{
public:
nsCircularByteBuffer()
: mBuffer(nsnull), mCapacity(0), mStart(0), mCount(0)
{}
// Set the capacity of the buffer in bytes. Must be called before any
// call to append or pop elements.
void SetCapacity(PRUint32 aCapacity) {
NS_ABORT_IF_FALSE(!mBuffer, "Buffer allocated.");
mCapacity = aCapacity;
mBuffer = new PRUint8[mCapacity];
}
PRUint32 Length() {
return mCount;
}
PRUint32 Capacity() {
return mCapacity;
}
PRUint32 Available() {
return Capacity() - Length();
}
// Append aLength bytes from aSrc to the buffer. Caller must check that
// sufficient space is available.
void AppendElements(const PRUint8* aSrc, PRUint32 aLength) {
NS_ABORT_IF_FALSE(mBuffer && mCapacity, "Buffer not initialized.");
NS_ABORT_IF_FALSE(aLength <= Available(), "Buffer full.");
PRUint32 end = (mStart + mCount) % mCapacity;
PRUint32 toCopy = NS_MIN(mCapacity - end, aLength);
memcpy(&mBuffer[end], aSrc, toCopy);
memcpy(&mBuffer[0], aSrc + toCopy, aLength - toCopy);
mCount += aLength;
}
// Remove aSize bytes from the buffer. Caller must check returned size in
// aSize{1,2} before using the pointer returned in aData{1,2}. Caller
// must not specify an aSize larger than Length().
void PopElements(PRUint32 aSize, void** aData1, PRUint32* aSize1,
void** aData2, PRUint32* aSize2) {
NS_ABORT_IF_FALSE(mBuffer && mCapacity, "Buffer not initialized.");
NS_ABORT_IF_FALSE(aSize <= Length(), "Request too large.");
*aData1 = &mBuffer[mStart];
*aSize1 = NS_MIN(mCapacity - mStart, aSize);
*aData2 = &mBuffer[0];
*aSize2 = aSize - *aSize1;
mCount -= *aSize1 + *aSize2;
mStart += *aSize1 + *aSize2;
mStart %= mCapacity;
}
private:
nsAutoArrayPtr<PRUint8> mBuffer;
PRUint32 mCapacity;
PRUint32 mStart;
PRUint32 mCount;
};
class nsBufferedAudioStream : public nsAudioStream
{
public:
@ -855,11 +935,10 @@ private:
PRUint64 mLostFrames;
// Temporary audio buffer. Filled by Write() and consumed by
// DataCallback(). Once mBufferLimit is reached, Write() blocks until
// sufficient space becomes available in mBuffer. The buffer and buffer
// limit deal in bytes, not frames.
nsTArray<PRUint8> mBuffer;
PRUint32 mBufferLimit;
// DataCallback(). Once mBuffer is full, Write() blocks until sufficient
// space becomes available in mBuffer. mBuffer is sized in bytes, not
// frames.
nsCircularByteBuffer mBuffer;
// Software volume level. Applied during the servicing of DataCallback().
double mVolume;
@ -883,10 +962,6 @@ private:
};
StreamState mState;
// Arbitrary default stream latency. The higher this value, the longer stream
// volume changes will take to become audible.
static const unsigned int DEFAULT_LATENCY_MS = 100;
};
#endif
@ -951,7 +1026,7 @@ nsBufferedAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aF
{
cubeb_stream* stream;
if (cubeb_stream_init(cubebContext, &stream, "nsBufferedAudioStream", params,
DEFAULT_LATENCY_MS, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
GetCubebLatency(), DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
mCubebStream.own(stream);
}
}
@ -960,16 +1035,12 @@ nsBufferedAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aF
return NS_ERROR_FAILURE;
}
// Limit mBuffer to one second of audio. This value is arbitrary, and was
// Size mBuffer for one second of audio. This value is arbitrary, and was
// selected based on the observed behaviour of the existing nsAudioStream
// implementations.
mBufferLimit = aRate * mBytesPerFrame;
NS_ABORT_IF_FALSE(mBufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
// Pre-allocate the buffer. nsTArray::RemoveElementsAt shrinks the buffer
// only if its length reaches zero, so allocator thrashing should be
// minimal.
mBuffer.SetCapacity(mBufferLimit);
PRUint32 bufferLimit = aRate * mBytesPerFrame;
NS_ABORT_IF_FALSE(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
mBuffer.SetCapacity(bufferLimit);
return NS_OK;
}
@ -996,9 +1067,7 @@ nsBufferedAudioStream::Write(const void* aBuf, PRUint32 aFrames)
PRUint32 bytesToCopy = aFrames * mBytesPerFrame;
while (bytesToCopy > 0) {
NS_ABORT_IF_FALSE(mBuffer.Length() <= mBufferLimit, "Buffer invariant violated.");
PRUint32 available = NS_MIN(bytesToCopy, mBufferLimit - mBuffer.Length());
PRUint32 available = NS_MIN(bytesToCopy, mBuffer.Available());
NS_ABORT_IF_FALSE(available % mBytesPerFrame == 0, "Must copy complete frames.");
mBuffer.AppendElements(src, available);
@ -1025,9 +1094,8 @@ PRUint32
nsBufferedAudioStream::Available()
{
MonitorAutoLock mon(mMonitor);
NS_ABORT_IF_FALSE(mBuffer.Length() <= mBufferLimit, "Buffer invariant violated.");
NS_ABORT_IF_FALSE(mBuffer.Length() % mBytesPerFrame == 0, "Buffer invariant violated.");
return (mBufferLimit - mBuffer.Length()) / mBytesPerFrame;
return mBuffer.Available() / mBytesPerFrame;
}
PRInt32 nsBufferedAudioStream::GetMinWriteSize()
@ -1129,18 +1197,6 @@ nsBufferedAudioStream::IsPaused()
return mState == STOPPED;
}
template<typename T>
void
SampleCopy(void* aDst, const PRUint8* aSrc, PRUint32 aSamples, double aVolume)
{
const T* src = reinterpret_cast<const T*>(aSrc);
double scaled_volume = GetVolumeScale() * aVolume;
T* dst = static_cast<T*>(aDst);
for (PRUint32 i = 0; i < aSamples; ++i) {
dst[i] = T(src[i] * scaled_volume);
}
}
long
nsBufferedAudioStream::DataCallback(void* aBuffer, long aFrames)
{
@ -1151,30 +1207,61 @@ nsBufferedAudioStream::DataCallback(void* aBuffer, long aFrames)
PRUint32 available = NS_MIN(bytesWanted, mBuffer.Length());
NS_ABORT_IF_FALSE(available % mBytesPerFrame == 0, "Must copy complete frames");
// Copy each sample from mBuffer to aBuffer, adjusting the volume during the copy.
PRUint32 samplesToCopy = available / mBytesPerFrame * mChannels;
switch (mFormat) {
case FORMAT_S16_LE:
SampleCopy<PRInt16>(aBuffer, mBuffer.Elements(), samplesToCopy, mVolume);
break;
case FORMAT_FLOAT32:
SampleCopy<float>(aBuffer, mBuffer.Elements(), samplesToCopy, mVolume);
break;
default:
return -1;
if (available > 0) {
// Copy each sample from mBuffer to aBuffer, adjusting the volume during the copy.
double scaled_volume = GetVolumeScale() * mVolume;
// Fetch input pointers from the ring buffer.
void* input[2];
PRUint32 input_size[2];
mBuffer.PopElements(available, &input[0], &input_size[0], &input[1], &input_size[1]);
PRUint8* output = reinterpret_cast<PRUint8*>(aBuffer);
for (int i = 0; i < 2; ++i) {
// Fast path for unity volume case.
if (scaled_volume == 1.0) {
memcpy(output, input[i], input_size[i]);
output += input_size[i];
} else {
// Adjust volume as each sample is copied out.
switch (mFormat) {
case FORMAT_S16_LE: {
PRInt32 volume = PRInt32(1 << 16) * scaled_volume;
const short* src = static_cast<const short*>(input[i]);
short* dst = reinterpret_cast<short*>(output);
for (PRUint32 j = 0; j < input_size[i] / (mBytesPerFrame / mChannels); ++j) {
dst[j] = short((PRInt32(src[j]) * volume) >> 16);
}
output += input_size[i];
break;
}
case FORMAT_FLOAT32: {
const float* src = static_cast<const float*>(input[i]);
float* dst = reinterpret_cast<float*>(output);
for (PRUint32 j = 0; j < input_size[i] / (mBytesPerFrame / mChannels); ++j) {
dst[j] = src[j] * scaled_volume;
}
output += input_size[i];
break;
}
default:
return -1;
}
}
}
NS_ABORT_IF_FALSE(mBuffer.Length() % mBytesPerFrame == 0, "Must copy complete frames");
// Notify any blocked Write() call that more space is available in mBuffer.
mon.NotifyAll();
// Calculate remaining bytes requested by caller. If the stream is not
// draining an underrun has occurred, so fill the remaining buffer with
// silence.
bytesWanted -= available;
}
// Remove copied data from the temporary audio buffer.
mBuffer.RemoveElementsAt(0, available);
NS_ABORT_IF_FALSE(mBuffer.Length() % mBytesPerFrame == 0, "Must copy complete frames");
// Notify any blocked Write() call that more space is available in mBuffer.
mon.NotifyAll();
// Calculate remaining bytes requested by caller. If the stream is not
// draining an underrun has occurred, so fill the remaining buffer with
// silence.
bytesWanted -= available;
if (mState != DRAINING) {
memset(static_cast<PRUint8*>(aBuffer) + available, 0, bytesWanted);
mLostFrames += bytesWanted / mBytesPerFrame;

View File

@ -246,6 +246,7 @@ nsresult nsBuiltinDecoder::Load(MediaResource* aResource,
mDecoderStateMachine->SetSeekable(mSeekable);
mDecoderStateMachine->SetDuration(mDuration);
mDecoderStateMachine->SetVolume(mInitialVolume);
mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
if (mFrameBufferLength > 0) {
// The valid mFrameBufferLength value was specified earlier

View File

@ -1146,50 +1146,56 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
mAudioEndTime = playedUsecs.value();
}
}
if (mReader->mAudioQueue.AtEndOfStream() &&
mState != DECODER_STATE_SHUTDOWN &&
!mStopAudioThread)
{
// Last frame pushed to audio hardware, wait for the audio to finish,
// before the audio thread terminates.
bool seeking = false;
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (mReader->mAudioQueue.AtEndOfStream() &&
mState != DECODER_STATE_SHUTDOWN &&
!mStopAudioThread)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
PRInt64 unplayedFrames = audioDuration % minWriteFrames;
if (minWriteFrames > 1 && unplayedFrames > 0) {
// Sound is written by libsydneyaudio to the hardware in blocks of
// frames of size minWriteFrames. So if the number of frames we've
// written isn't an exact multiple of minWriteFrames, we'll have
// left over audio data which hasn't yet been written to the hardware,
// and so that audio will not start playing. Write silence to ensure
// the last block gets pushed to hardware, so that playback starts.
PRInt64 framesToWrite = minWriteFrames - unplayedFrames;
if (framesToWrite < PR_UINT32_MAX / channels) {
// Write silence manually rather than using PlaySilence(), so that
// the AudioAPI doesn't get a copy of the audio frames.
WriteSilence(mAudioStream, framesToWrite);
}
}
PRInt64 oldPosition = -1;
PRInt64 position = GetMediaTime();
while (oldPosition != position &&
mAudioEndTime - position > 0 &&
mState != DECODER_STATE_SEEKING &&
mState != DECODER_STATE_SHUTDOWN)
// Last frame pushed to audio hardware, wait for the audio to finish,
// before the audio thread terminates.
bool seeking = false;
{
const PRInt64 DRAIN_BLOCK_USECS = 100000;
Wait(NS_MIN(mAudioEndTime - position, DRAIN_BLOCK_USECS));
oldPosition = position;
position = GetMediaTime();
}
seeking = mState == DECODER_STATE_SEEKING;
}
PRInt64 unplayedFrames = audioDuration % minWriteFrames;
if (minWriteFrames > 1 && unplayedFrames > 0) {
// Sound is written by libsydneyaudio to the hardware in blocks of
// frames of size minWriteFrames. So if the number of frames we've
// written isn't an exact multiple of minWriteFrames, we'll have
// left over audio data which hasn't yet been written to the hardware,
// and so that audio will not start playing. Write silence to ensure
// the last block gets pushed to hardware, so that playback starts.
PRInt64 framesToWrite = minWriteFrames - unplayedFrames;
if (framesToWrite < PR_UINT32_MAX / channels) {
// Write silence manually rather than using PlaySilence(), so that
// the AudioAPI doesn't get a copy of the audio frames.
ReentrantMonitorAutoExit exit(mDecoder->GetReentrantMonitor());
WriteSilence(mAudioStream, framesToWrite);
}
}
if (!seeking && !mAudioStream->IsPaused()) {
mAudioStream->Drain();
// Fire one last event for any extra frames that didn't fill a framebuffer.
mEventManager.Drain(mAudioEndTime);
PRInt64 oldPosition = -1;
PRInt64 position = GetMediaTime();
while (oldPosition != position &&
mAudioEndTime - position > 0 &&
mState != DECODER_STATE_SEEKING &&
mState != DECODER_STATE_SHUTDOWN)
{
const PRInt64 DRAIN_BLOCK_USECS = 100000;
Wait(NS_MIN(mAudioEndTime - position, DRAIN_BLOCK_USECS));
oldPosition = position;
position = GetMediaTime();
}
seeking = mState == DECODER_STATE_SEEKING;
}
if (!seeking && !mAudioStream->IsPaused()) {
{
ReentrantMonitorAutoExit exit(mDecoder->GetReentrantMonitor());
mAudioStream->Drain();
}
// Fire one last event for any extra frames that didn't fill a framebuffer.
mEventManager.Drain(mAudioEndTime);
}
}
}
LOG(PR_LOG_DEBUG, ("%p Reached audio stream end.", mDecoder.get()));

View File

@ -750,9 +750,6 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs
}
uint32_t flags = 0;
if (mozilla::Preferences::GetBool("plugin.allow.asyncdrawing", false)) {
flags |= kAllowAsyncDrawing;
}
if (!CallNP_Initialize(flags, error)) {
return NS_ERROR_FAILURE;
@ -779,9 +776,9 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
}
uint32_t flags = 0;
if (mozilla::Preferences::GetBool("plugin.allow.asyncdrawing", false)) {
flags |= kAllowAsyncDrawing;
}
#ifdef XP_WIN
flags |= kAllowAsyncDrawing;
#endif
if (!CallNP_Initialize(flags, error))
return NS_ERROR_FAILURE;

View File

@ -72,12 +72,14 @@ static void getVariableInfo(ShShaderInfo varType,
int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
name[activeUniformAndAttribLength - 1] = 0;
if (mappedName) {
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
mappedName[maxMappedNameLength - 1] = 0;
}
}

View File

@ -266,8 +266,9 @@ void
ImageContainer::SetRemoteImageData(RemoteImageData *aData, CrossProcessMutex *aMutex)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(!mActiveImage, "No active image expected when SetRemoteImageData is called.");
NS_ASSERTION(!mRemoteData, "No remote data expected when SetRemoteImageData is called.");
NS_ASSERTION(!mActiveImage || !aData, "No active image expected when SetRemoteImageData is called with non-NULL aData.");
NS_ASSERTION(!mRemoteData || !aData, "No remote data expected when SetRemoteImageData is called with non-NULL aData.");
mRemoteData = aData;

View File

@ -65,6 +65,7 @@ CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
NS_RUNTIMEABORT("Attempt to construct a mutex from an invalid handle!");
}
mMutex = aHandle;
MOZ_COUNT_CTOR(CrossProcessMutex);
}
CrossProcessMutex::~CrossProcessMutex()

View File

@ -57,7 +57,7 @@ class RegExpMatchBuilder
RootedVarObject array;
bool setProperty(JSAtom *name, Value v) {
return !!js_DefineProperty(cx, array, ATOM_TO_JSID(name), &v,
return !!js_DefineProperty(cx, array, AtomToId(name), &v,
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
}
@ -500,7 +500,7 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
return NULL;
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, regexp_construct, CLASS_ATOM(cx, RegExp), 2);
ctor = global->createConstructor(cx, regexp_construct, CLASS_NAME(cx, RegExp), 2);
if (!ctor)
return NULL;

View File

@ -4180,7 +4180,8 @@ ArrayType::Getter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
size_t index;
size_t length = GetLength(typeObj);
bool ok = jsidToSize(cx, idval, true, &index);
if (!ok && JSID_IS_STRING(idval)) {
int32_t dummy;
if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) {
// String either isn't a number, or doesn't fit in size_t.
// Chances are it's a regular property lookup, so return.
return JS_TRUE;
@ -4215,7 +4216,8 @@ ArrayType::Setter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict, jsval
size_t index;
size_t length = GetLength(typeObj);
bool ok = jsidToSize(cx, idval, true, &index);
if (!ok && JSID_IS_STRING(idval)) {
int32_t dummy;
if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) {
// String either isn't a number, or doesn't fit in size_t.
// Chances are it's a regular property lookup, so return.
return JS_TRUE;

View File

@ -67,7 +67,7 @@ DefineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript* script)
if (!def.atom)
continue;
jsid id = ATOM_TO_JSID(def.atom);
jsid id = AtomToId(def.atom);
Value rval;
if (def.funbox) {

View File

@ -768,7 +768,7 @@ frontend::LexicalLookup(TreeContext *tc, JSAtom *atom, int *slotp, StmtInfo *stm
continue;
StaticBlockObject &blockObj = *stmt->blockObj;
const Shape *shape = blockObj.nativeLookup(tc->parser->context, ATOM_TO_JSID(atom));
const Shape *shape = blockObj.nativeLookup(tc->parser->context, AtomToId(atom));
if (shape) {
JS_ASSERT(shape->hasShortID());
@ -823,7 +823,7 @@ LookupCompileTimeConstant(JSContext *cx, BytecodeEmitter *bce, JSAtom *atom, Val
JS_ASSERT(bce->compileAndGo());
JSObject *obj = bce->scopeChain();
const Shape *shape = obj->nativeLookup(cx, ATOM_TO_JSID(atom));
const Shape *shape = obj->nativeLookup(cx, AtomToId(atom));
if (shape) {
/*
* We're compiling code that will be executed immediately,
@ -3975,14 +3975,14 @@ ParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
jsid id;
if (idvalue.isInt32() && INT_FITS_IN_JSID(idvalue.toInt32()))
id = INT_TO_JSID(idvalue.toInt32());
else if (!js_InternNonIntElementId(cx, obj, idvalue, &id))
else if (!InternNonIntElementId(cx, obj, idvalue, &id))
return false;
if (!obj->defineGeneric(cx, id, value, NULL, NULL, JSPROP_ENUMERATE))
return false;
} else {
JS_ASSERT(pnid->isKind(PNK_NAME) || pnid->isKind(PNK_STRING));
JS_ASSERT(pnid->pn_atom != cx->runtime->atomState.protoAtom);
jsid id = ATOM_TO_JSID(pnid->pn_atom);
jsid id = AtomToId(pnid->pn_atom);
if (!DefineNativeProperty(cx, obj, id, value, NULL, NULL,
JSPROP_ENUMERATE, 0, 0)) {
return false;
@ -5979,7 +5979,7 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (obj) {
JS_ASSERT(!obj->inDictionaryMode());
if (!DefineNativeProperty(cx, obj, ATOM_TO_JSID(pn3->pn_atom),
if (!DefineNativeProperty(cx, obj, AtomToId(pn3->pn_atom),
UndefinedValue(), NULL, NULL,
JSPROP_ENUMERATE, 0, 0))
{

View File

@ -426,6 +426,8 @@ struct TreeContext { /* tree context for semantic checks */
};
bool init(JSContext *cx, InitBehavior ib = USED_AS_TREE_CONTEXT) {
if (cx->hasRunOption(JSOPTION_STRICT_MODE))
flags |= TCF_STRICT_MODE_CODE;
if (ib == USED_AS_CODE_GENERATOR)
return true;
return decls.init() && lexdeps.ensureMap(cx);

View File

@ -144,6 +144,8 @@ Parser::init(const jschar *base, size_t length, const char *filename, unsigned l
cx->tempLifoAlloc().release(tempPoolMark);
return false;
}
if (context->hasRunOption(JSOPTION_STRICT_MODE))
tokenStream.setStrictMode();
return true;
}
@ -2006,7 +2008,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, TreeContext *tc)
* slot indexed by blockCount off the class-reserved slot base.
*/
bool redeclared;
jsid id = ATOM_TO_JSID(atom);
jsid id = AtomToId(atom);
const Shape *shape = blockObj->addVar(cx, id, blockCount, &redeclared);
if (!shape) {
if (redeclared)

View File

@ -275,7 +275,7 @@ MarkIdInternal(JSTracer *trc, jsid *id)
if (JSID_IS_STRING(*id)) {
JSString *str = JSID_TO_STRING(*id);
MarkInternal(trc, &str);
*id = ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
*id = NON_INTEGER_ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
} else if (JS_UNLIKELY(JSID_IS_OBJECT(*id))) {
JSObject *obj = JSID_TO_OBJECT(*id);
MarkInternal(trc, &obj);

View File

@ -1742,10 +1742,10 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
#define CLASP(name) (&name##Class)
#define TYPED_ARRAY_CLASP(type) (&TypedArray::classes[TypedArray::type])
#define EAGER_ATOM(name) ATOM_OFFSET(name), NULL
#define EAGER_CLASS_ATOM(name) CLASS_ATOM_OFFSET(name), NULL
#define EAGER_ATOM(name) NAME_OFFSET(name), NULL
#define EAGER_CLASS_ATOM(name) CLASS_NAME_OFFSET(name), NULL
#define EAGER_ATOM_AND_CLASP(name) EAGER_CLASS_ATOM(name), CLASP(name)
#define LAZY_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_str
#define LAZY_ATOM(name) NAME_OFFSET(lazy.name), js_##name##_str
typedef struct JSStdName {
JSObjectOp init;
@ -1754,20 +1754,20 @@ typedef struct JSStdName {
Class *clasp;
} JSStdName;
static JSAtom *
StdNameToAtom(JSContext *cx, JSStdName *stdn)
static PropertyName *
StdNameToPropertyName(JSContext *cx, JSStdName *stdn)
{
size_t offset;
JSAtom *atom;
PropertyName *atom;
const char *name;
offset = stdn->atomOffset;
atom = OFFSET_TO_ATOM(cx->runtime, offset);
atom = OFFSET_TO_NAME(cx->runtime, offset);
if (!atom) {
name = stdn->name;
if (name) {
atom = js_Atomize(cx, name, strlen(name), InternAtom);
OFFSET_TO_ATOM(cx->runtime, offset) = atom;
atom = js_Atomize(cx, name, strlen(name), InternAtom)->asPropertyName();
OFFSET_TO_NAME(cx->runtime, offset) = atom;
}
}
return atom;
@ -1931,7 +1931,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
stdnm = NULL;
for (i = 0; standard_class_atoms[i].init; i++) {
JS_ASSERT(standard_class_atoms[i].clasp);
atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
atom = OFFSET_TO_NAME(rt, standard_class_atoms[i].atomOffset);
if (idstr == atom) {
stdnm = &standard_class_atoms[i];
break;
@ -1942,7 +1942,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
/* Try less frequently used top-level functions and constants. */
for (i = 0; standard_class_names[i].init; i++) {
JS_ASSERT(standard_class_names[i].clasp);
atom = StdNameToAtom(cx, &standard_class_names[i]);
atom = StdNameToPropertyName(cx, &standard_class_names[i]);
if (!atom)
return JS_FALSE;
if (idstr == atom) {
@ -1959,7 +1959,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
*/
for (i = 0; object_prototype_names[i].init; i++) {
JS_ASSERT(object_prototype_names[i].clasp);
atom = StdNameToAtom(cx, &object_prototype_names[i]);
atom = StdNameToPropertyName(cx, &object_prototype_names[i]);
if (!atom)
return JS_FALSE;
if (idstr == atom) {
@ -2007,7 +2007,7 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj_)
* Since ES5 15.1.1.3 undefined can't be deleted.
*/
PropertyName *name = rt->atomState.typeAtoms[JSTYPE_VOID];
if (!obj->nativeContains(cx, ATOM_TO_JSID(name)) &&
if (!obj->nativeContains(cx, NameToId(name)) &&
!obj->defineProperty(cx, name, UndefinedValue(),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY)) {
@ -2058,7 +2058,7 @@ SetIdArrayLength(JSContext *cx, JSIdArray *ida, int length)
}
static JSIdArray *
AddAtomToArray(JSContext *cx, JSAtom *atom, JSIdArray *ida, int *ip)
AddNameToArray(JSContext *cx, PropertyName *name, JSIdArray *ida, int *ip)
{
int i = *ip;
int length = ida->length;
@ -2068,18 +2068,18 @@ AddAtomToArray(JSContext *cx, JSAtom *atom, JSIdArray *ida, int *ip)
return NULL;
JS_ASSERT(i < ida->length);
}
ida->vector[i].init(ATOM_TO_JSID(atom));
ida->vector[i].init(NameToId(name));
*ip = i + 1;
return ida;
}
static JSIdArray *
EnumerateIfResolved(JSContext *cx, JSObject *obj, JSAtom *atom, JSIdArray *ida,
EnumerateIfResolved(JSContext *cx, JSObject *obj, PropertyName *name, JSIdArray *ida,
int *ip, JSBool *foundp)
{
*foundp = obj->nativeContains(cx, ATOM_TO_JSID(atom));
*foundp = obj->nativeContains(cx, NameToId(name));
if (*foundp)
ida = AddAtomToArray(cx, atom, ida, ip);
ida = AddNameToArray(cx, name, ida, ip);
return ida;
}
@ -2088,7 +2088,7 @@ JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, JSIdArray *ida
{
JSRuntime *rt;
int i, j, k;
JSAtom *atom;
PropertyName *name;
JSBool found;
JSObjectOp init;
@ -2106,15 +2106,15 @@ JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, JSIdArray *ida
}
/* Check whether 'undefined' has been resolved and enumerate it if so. */
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
name = rt->atomState.typeAtoms[JSTYPE_VOID];
ida = EnumerateIfResolved(cx, obj, name, ida, &i, &found);
if (!ida)
return NULL;
/* Enumerate only classes that *have* been resolved. */
for (j = 0; standard_class_atoms[j].init; j++) {
atom = OFFSET_TO_ATOM(rt, standard_class_atoms[j].atomOffset);
ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
name = OFFSET_TO_NAME(rt, standard_class_atoms[j].atomOffset);
ida = EnumerateIfResolved(cx, obj, name, ida, &i, &found);
if (!ida)
return NULL;
@ -2123,8 +2123,8 @@ JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, JSIdArray *ida
for (k = 0; standard_class_names[k].init; k++) {
if (standard_class_names[k].init == init) {
atom = StdNameToAtom(cx, &standard_class_names[k]);
ida = AddAtomToArray(cx, atom, ida, &i);
name = StdNameToPropertyName(cx, &standard_class_names[k]);
ida = AddNameToArray(cx, name, ida, &i);
if (!ida)
return NULL;
}
@ -2132,8 +2132,8 @@ JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, JSIdArray *ida
if (init == js_InitObjectClass) {
for (k = 0; object_prototype_names[k].init; k++) {
atom = StdNameToAtom(cx, &object_prototype_names[k]);
ida = AddAtomToArray(cx, atom, ida, &i);
name = StdNameToPropertyName(cx, &object_prototype_names[k]);
ida = AddNameToArray(cx, name, ida, &i);
if (!ida)
return NULL;
}
@ -3455,7 +3455,6 @@ LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
assertSameCompartment(cx, obj, id);
JSAutoResolveFlags rf(cx, flags);
id = js_CheckForStringIndex(id);
return obj->lookupGeneric(cx, id, objp, propp);
}
@ -3521,14 +3520,14 @@ JS_PUBLIC_API(JSBool)
JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
return atom && JS_LookupPropertyById(cx, obj, AtomToId(atom), vp);
}
JS_PUBLIC_API(JSBool)
JS_LookupUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
return atom && JS_LookupPropertyById(cx, obj, AtomToId(atom), vp);
}
JS_PUBLIC_API(JSBool)
@ -3552,7 +3551,7 @@ JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, unsig
{
JSObject *obj2;
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_LookupPropertyWithFlagsById(cx, obj, ATOM_TO_JSID(atom), flags, &obj2, vp);
return atom && JS_LookupPropertyWithFlagsById(cx, obj, AtomToId(atom), flags, &obj2, vp);
}
JS_PUBLIC_API(JSBool)
@ -3581,14 +3580,14 @@ JS_PUBLIC_API(JSBool)
JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp);
}
JS_PUBLIC_API(JSBool)
JS_HasUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JSBool *foundp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp);
}
JS_PUBLIC_API(JSBool)
@ -3629,7 +3628,7 @@ JS_PUBLIC_API(JSBool)
JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp);
}
JS_PUBLIC_API(JSBool)
@ -3637,7 +3636,7 @@ JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, siz
JSBool *foundp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp);
}
static JSBool
@ -3741,7 +3740,7 @@ DefineProperty(JSContext *cx, JSObject *obj_, const char *name, const Value &val
JSAtom *atom = js_Atomize(cx, name, strlen(name));
if (!atom)
return JS_FALSE;
id = ATOM_TO_JSID(atom);
id = AtomToId(atom);
}
return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags, tinyid);
@ -3772,7 +3771,7 @@ DefineUCProperty(JSContext *cx, JSObject *obj_, const jschar *name, size_t namel
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
if (!atom)
return false;
RootedVarId id(cx, ATOM_TO_JSID(atom));
RootedVarId id(cx, AtomToId(atom));
return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags, tinyid);
}
@ -3938,7 +3937,7 @@ JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
unsigned *attrsp, JSBool *foundp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
attrsp, foundp, NULL, NULL);
}
@ -3947,7 +3946,7 @@ JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, siz
unsigned *attrsp, JSBool *foundp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
attrsp, foundp, NULL, NULL);
}
@ -3957,7 +3956,7 @@ JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, const char *nam
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
attrsp, foundp, getterp, setterp);
}
@ -3968,7 +3967,7 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
attrsp, foundp, getterp, setterp);
}
@ -4006,7 +4005,7 @@ JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
unsigned attrs, JSBool *foundp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
return atom && SetPropertyAttributesById(cx, obj, AtomToId(atom), attrs, foundp);
}
JS_PUBLIC_API(JSBool)
@ -4014,7 +4013,7 @@ JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, siz
unsigned attrs, JSBool *foundp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
return atom && SetPropertyAttributesById(cx, obj, AtomToId(atom), attrs, foundp);
}
JS_PUBLIC_API(JSBool)
@ -4075,7 +4074,7 @@ JS_GetProperty(JSContext *cx, JSObject *obj_, const char *name, jsval *vp)
{
RootedVarObject obj(cx, obj_);
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
return atom && JS_GetPropertyById(cx, obj, AtomToId(atom), vp);
}
JS_PUBLIC_API(JSBool)
@ -4083,7 +4082,7 @@ JS_GetPropertyDefault(JSContext *cx, JSObject *obj_, const char *name, jsval def
{
RootedVarObject obj(cx, obj_);
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_GetPropertyByIdDefault(cx, obj, ATOM_TO_JSID(atom), def, vp);
return atom && JS_GetPropertyByIdDefault(cx, obj, AtomToId(atom), def, vp);
}
JS_PUBLIC_API(JSBool)
@ -4091,7 +4090,7 @@ JS_GetUCProperty(JSContext *cx, JSObject *obj_, const jschar *name, size_t namel
{
RootedVarObject obj(cx, obj_);
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
return atom && JS_GetPropertyById(cx, obj, AtomToId(atom), vp);
}
JS_PUBLIC_API(JSBool)
@ -4111,7 +4110,7 @@ JS_PUBLIC_API(JSBool)
JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, jsval *vp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), objp, vp);
return atom && JS_GetMethodById(cx, obj, AtomToId(atom), objp, vp);
}
JS_PUBLIC_API(JSBool)
@ -4142,14 +4141,14 @@ JS_SetProperty(JSContext *cx, JSObject *obj_, const char *name, jsval *vp)
RootedVarObject obj(cx, obj_);
RootValue vpRoot(cx, vp);
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
return atom && JS_SetPropertyById(cx, obj, AtomToId(atom), vp);
}
JS_PUBLIC_API(JSBool)
JS_SetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
return atom && JS_SetPropertyById(cx, obj, AtomToId(atom), vp);
}
JS_PUBLIC_API(JSBool)
@ -4257,8 +4256,6 @@ JS_Enumerate(JSContext *cx, JSObject *obj)
JSIdArray *ida;
if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &props) || !VectorToIdArray(cx, props, &ida))
return NULL;
for (size_t n = 0; n < size_t(ida->length); ++n)
JS_ASSERT(js_CheckForStringIndex(ida->vector[n]) == ida->vector[n]);
return ida;
}
@ -4709,7 +4706,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
}
flags &= ~JSFUN_GENERIC_NATIVE;
fun = js_DefineFunction(cx, ctor, ATOM_TO_JSID(atom),
fun = js_DefineFunction(cx, ctor, AtomToId(atom),
js_generic_native_method_dispatcher,
fs->nargs + 1,
flags,
@ -4725,7 +4722,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
}
fun = js_DefineFunction(cx, objRoot,
ATOM_TO_JSID(atom), fs->call, fs->nargs, flags);
AtomToId(atom), fs->call, fs->nargs, flags);
if (!fun)
return JS_FALSE;
}
@ -4745,7 +4742,7 @@ JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
JSAtom *atom = js_Atomize(cx, name, strlen(name));
if (!atom)
return NULL;
return js_DefineFunction(cx, objRoot, ATOM_TO_JSID(atom), call, nargs, attrs);
return js_DefineFunction(cx, objRoot, AtomToId(atom), call, nargs, attrs);
}
JS_PUBLIC_API(JSFunction *)
@ -4762,7 +4759,7 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj,
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
if (!atom)
return NULL;
return js_DefineFunction(cx, objRoot, ATOM_TO_JSID(atom), call, nargs, attrs);
return js_DefineFunction(cx, objRoot, AtomToId(atom), call, nargs, attrs);
}
extern JS_PUBLIC_API(JSFunction *)
@ -5129,7 +5126,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
}
if (obj && funAtom &&
!obj->defineGeneric(cx, ATOM_TO_JSID(funAtom), ObjectValue(*fun), NULL, NULL,
!obj->defineGeneric(cx, AtomToId(funAtom), ObjectValue(*fun), NULL, NULL,
JSPROP_ENUMERATE))
{
return NULL;
@ -5431,7 +5428,7 @@ JS_CallFunctionName(JSContext *cx, JSObject *obj_, const char *name, unsigned ar
Value v;
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom &&
js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, &v) &&
js_GetMethod(cx, obj, AtomToId(atom), 0, &v) &&
Invoke(cx, ObjectOrNullValue(obj), v, argc, argv, rval);
}
@ -5603,6 +5600,15 @@ JS_StringHasBeenInterned(JSContext *cx, JSString *str)
return AtomIsInterned(cx, &str->asAtom());
}
JS_PUBLIC_API(jsid)
INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str)
{
JS_ASSERT(str);
JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
JS_ASSERT_IF(cx, JS_StringHasBeenInterned(cx, str));
return AtomToId(&str->asAtom());
}
JS_PUBLIC_API(JSString *)
JS_InternJSString(JSContext *cx, JSString *str)
{

View File

@ -1982,20 +1982,8 @@ JS_StringHasBeenInterned(JSContext *cx, JSString *str);
* N.B. if a jsid is backed by a string which has not been interned, that
* string must be appropriately rooted to avoid being collected by the GC.
*/
static JS_ALWAYS_INLINE jsid
INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str)
{
jsid id;
JS_ASSERT(str);
JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
#ifdef DEBUG
JS_ASSERT(JS_StringHasBeenInterned(cx, str));
#else
(void)cx;
#endif
JSID_BITS(id) = (size_t)str;
return id;
}
JS_PUBLIC_API(jsid)
INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str);
static JS_ALWAYS_INLINE JSBool
JSID_IS_INT(jsid id)
@ -2007,21 +1995,16 @@ static JS_ALWAYS_INLINE int32_t
JSID_TO_INT(jsid id)
{
JS_ASSERT(JSID_IS_INT(id));
return ((int32_t)JSID_BITS(id)) >> 1;
return ((uint32_t)JSID_BITS(id)) >> 1;
}
/*
* Note: when changing these values, verify that their use in
* js_CheckForStringIndex is still valid.
*/
#define JSID_INT_MIN (-(1 << 30))
#define JSID_INT_MAX ((1 << 30) - 1)
#define JSID_INT_MIN 0
#define JSID_INT_MAX INT32_MAX
static JS_ALWAYS_INLINE JSBool
INT_FITS_IN_JSID(int32_t i)
{
return ((uint32_t)(i) - (uint32_t)JSID_INT_MIN <=
(uint32_t)(JSID_INT_MAX - JSID_INT_MIN));
return i >= 0;
}
static JS_ALWAYS_INLINE jsid
@ -2768,11 +2751,15 @@ JS_StringToVersion(const char *string);
#define JSOPTION_PCCOUNT JS_BIT(17) /* Collect per-op execution counts */
#define JSOPTION_TYPE_INFERENCE JS_BIT(18) /* Perform type inference. */
#define JSOPTION_STRICT_MODE JS_BIT(19) /* Provides a way to force
strict mode for all code
without requiring
"use strict" annotations. */
/* Options which reflect compile-time properties of scripts. */
#define JSCOMPILEOPTION_MASK (JSOPTION_XML)
#define JSRUNOPTION_MASK (JS_BITMASK(19) & ~JSCOMPILEOPTION_MASK)
#define JSRUNOPTION_MASK (JS_BITMASK(20) & ~JSCOMPILEOPTION_MASK)
#define JSALLOPTION_MASK (JSCOMPILEOPTION_MASK | JSRUNOPTION_MASK)
extern JS_PUBLIC_API(uint32_t)

View File

@ -274,7 +274,7 @@ BigIndexToId(JSContext *cx, JSObject *obj, uint32_t index, JSBool createAtom,
return JS_FALSE;
}
*idp = ATOM_TO_JSID(atom);
*idp = NON_INTEGER_ATOM_TO_JSID(atom);
return JS_TRUE;
}
@ -310,7 +310,7 @@ JSObject::willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElements
static bool
ReallyBigIndexToId(JSContext* cx, double index, jsid* idp)
{
return js_ValueToStringId(cx, DoubleValue(index), idp);
return ValueToId(cx, DoubleValue(index), idp);
}
static bool
@ -749,7 +749,7 @@ static JSBool
array_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
JSProperty **propp)
{
return array_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
return array_lookupGeneric(cx, obj, NameToId(name), objp, propp);
}
static JSBool
@ -813,7 +813,7 @@ array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName
return js_GetProperty(cx,
RootedVarObject(cx, obj),
RootedVarObject(cx, receiver),
ATOM_TO_JSID(name),
NameToId(name),
vp);
}
@ -956,7 +956,7 @@ array_setGeneric(JSContext *cx, JSObject *obj_, jsid id_, Value *vp, JSBool stri
static JSBool
array_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
{
return array_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
return array_setGeneric(cx, obj, NameToId(name), vp, strict);
}
static JSBool
@ -1069,7 +1069,7 @@ static JSBool
array_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *value,
JSPropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
return array_defineGeneric(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs);
return array_defineGeneric(cx, obj, NameToId(name), value, getter, setter, attrs);
}
namespace js {
@ -1349,7 +1349,7 @@ AddLengthProperty(JSContext *cx, JSObject *obj)
* as accesses to 'length' will use the elements header.
*/
const jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
const jsid lengthId = NameToId(cx->runtime->atomState.lengthAtom);
JS_ASSERT(!obj->nativeLookup(cx, lengthId));
if (!obj->allocateSlowArrayElements(cx))
@ -1685,7 +1685,7 @@ array_toString_sub(JSContext *cx, HandleObject obj, JSBool locale,
JSObject *robj = ToObject(cx, &elt);
if (!robj)
return false;
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toLocaleStringAtom);
jsid id = NameToId(cx->runtime->atomState.toLocaleStringAtom);
if (!robj->callMethod(cx, id, 0, NULL, &elt))
return false;
}
@ -1847,7 +1847,7 @@ InitArrayElements(JSContext *cx, HandleObject obj, uint32_t start, uint32_t coun
Value idval = DoubleValue(MAX_ARRAY_INDEX + 1);
do {
value = *vector++;
if (!js_ValueToStringId(cx, idval, id.address()) ||
if (!ValueToId(cx, idval, id.address()) ||
!obj->setGeneric(cx, id, value.address(), true)) {
return false;
}
@ -3729,7 +3729,7 @@ js_InitArrayClass(JSContext *cx, JSObject *obj)
arrayProto->setArrayLength(cx, 0);
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, js_Array, CLASS_ATOM(cx, Array), 1);
ctor = global->createConstructor(cx, js_Array, CLASS_NAME(cx, Array), 1);
if (!ctor)
return NULL;

View File

@ -540,125 +540,48 @@ IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
if (!atom)
return false;
*idp = ATOM_TO_JSID(atom);
JS_ASSERT(js_CheckForStringIndex(*idp) == *idp);
*idp = JSID_FROM_BITS((size_t)atom);
return true;
}
bool
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp, Value *vp)
{
#if JS_HAS_XML_SUPPORT
if (idval.isObject()) {
JSObject *idobj = &idval.toObject();
if (obj && obj->isXML()) {
*idp = OBJECT_TO_JSID(idobj);
*vp = idval;
return true;
}
if (js_GetLocalNameFromFunctionQName(idobj, idp, cx)) {
*vp = IdToValue(*idp);
return true;
}
if (!obj && idobj->isXMLId()) {
*idp = OBJECT_TO_JSID(idobj);
*vp = idval;
return JS_TRUE;
}
}
#endif
JSAtom *atom;
if (!js_ValueToAtom(cx, idval, &atom))
return false;
*idp = AtomToId(atom);
vp->setString(atom);
return true;
}
} /* namespace js */
/* JSBOXEDWORD_INT_MAX as a string */
#define JSBOXEDWORD_INT_MAX_STRING "1073741823"
/*
* Convert string indexes that convert to int jsvals as ints to save memory.
* Care must be taken to use this macro every time a property name is used, or
* else double-sets, incorrect property cache misses, or other mistakes could
* occur.
*/
jsid
js_CheckForStringIndex(jsid id)
{
if (!JSID_IS_ATOM(id))
return id;
JSAtom *atom = JSID_TO_ATOM(id);
const jschar *s = atom->chars();
jschar ch = *s;
JSBool negative = (ch == '-');
if (negative)
ch = *++s;
if (!JS7_ISDEC(ch))
return id;
size_t n = atom->length() - negative;
if (n > sizeof(JSBOXEDWORD_INT_MAX_STRING) - 1)
return id;
const jschar *cp = s;
const jschar *end = s + n;
uint32_t index = JS7_UNDEC(*cp++);
uint32_t oldIndex = 0;
uint32_t c = 0;
if (index != 0) {
while (JS7_ISDEC(*cp)) {
oldIndex = index;
c = JS7_UNDEC(*cp);
index = 10 * index + c;
cp++;
}
}
/*
* Non-integer indexes can't be represented as integers. Also, distinguish
* index "-0" from "0", because JSBOXEDWORD_INT cannot.
*/
if (cp != end || (negative && index == 0))
return id;
if (negative) {
if (oldIndex < -(JSID_INT_MIN / 10) ||
(oldIndex == -(JSID_INT_MIN / 10) && c <= (-JSID_INT_MIN % 10)))
{
id = INT_TO_JSID(-int32_t(index));
}
} else {
if (oldIndex < JSID_INT_MAX / 10 ||
(oldIndex == JSID_INT_MAX / 10 && c <= (JSID_INT_MAX % 10)))
{
id = INT_TO_JSID(int32_t(index));
}
}
return id;
}
#if JS_HAS_XML_SUPPORT
bool
js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp)
{
JS_ASSERT(idval.isObject());
if (obj->isXML()) {
*idp = OBJECT_TO_JSID(&idval.toObject());
return true;
}
if (js_GetLocalNameFromFunctionQName(&idval.toObject(), idp, cx))
return true;
return js_ValueToStringId(cx, idval, idp);
}
bool
js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp, Value *vp)
{
JS_ASSERT(idval.isObject());
if (obj->isXML()) {
JSObject &idobj = idval.toObject();
*idp = OBJECT_TO_JSID(&idobj);
vp->setObject(idobj);
return true;
}
if (js_GetLocalNameFromFunctionQName(&idval.toObject(), idp, cx)) {
*vp = IdToValue(*idp);
return true;
}
if (js_ValueToStringId(cx, idval, idp)) {
vp->setString(JSID_TO_STRING(*idp));
return true;
}
return false;
}
#endif
template<XDRMode mode>
bool
js::XDRAtom(XDRState<mode> *xdr, JSAtom **atomp)

View File

@ -67,14 +67,37 @@ JSID_FROM_BITS(size_t 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
ATOM_TO_JSID(JSAtom *atom)
NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
{
JS_ASSERT(((size_t)atom & 0x7) == 0);
return JSID_FROM_BITS((size_t)atom);
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. */
/* All strings stored in jsids are atomized, but are not necessarily property names. */
static JS_ALWAYS_INLINE JSBool
JSID_IS_ATOM(jsid id)
{
@ -84,7 +107,7 @@ JSID_IS_ATOM(jsid id)
static JS_ALWAYS_INLINE JSBool
JSID_IS_ATOM(jsid id, JSAtom *atom)
{
return JSID_BITS(id) == JSID_BITS(ATOM_TO_JSID(atom));
return id == JSID_FROM_BITS((size_t)atom);
}
static JS_ALWAYS_INLINE JSAtom *
@ -93,9 +116,6 @@ JSID_TO_ATOM(jsid id)
return (JSAtom *)JSID_TO_STRING(id);
}
extern jsid
js_CheckForStringIndex(jsid id);
JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
@ -104,7 +124,6 @@ namespace js {
static JS_ALWAYS_INLINE JSHashNumber
HashId(jsid id)
{
JS_ASSERT(js_CheckForStringIndex(id) == id);
JSHashNumber n =
#if JS_BYTES_PER_WORD == 4
JSHashNumber(JSID_BITS(id));
@ -140,11 +159,9 @@ struct DefaultHasher<jsid>
{
typedef jsid Lookup;
static HashNumber hash(const Lookup &l) {
JS_ASSERT(l == js_CheckForStringIndex(l));
return HashNumber(JSID_BITS(l));
}
static bool match(const jsid &id, const Lookup &l) {
JS_ASSERT(l == js_CheckForStringIndex(l));
return id == l;
}
};
@ -349,10 +366,10 @@ AtomIsInterned(JSContext *cx, JSAtom *atom);
((offsetof(JSAtomState, typeAtoms[type]) - JSAtomState::commonAtomsOffset)\
/ sizeof(JSAtom*))
#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)
#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))
#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name])
#define CLASS_ATOM(cx,name) ((cx)->runtime->atomState.classAtoms[JSProto_##name])
#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;
@ -460,18 +477,19 @@ js_DumpAtoms(JSContext *cx, FILE *fp);
inline bool
js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp);
inline bool
js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp);
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp);
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp, js::Value *vp);
namespace js {
bool
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp, Value *vp);
inline bool
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp)
{
Value dummy;
return InternNonIntElementId(cx, obj, idval, idp, &dummy);
}
/*
* For all unmapped atoms recorded in al, add a mapping from the atom's index
* to its address. map->length must already be set to the number of atoms in

View File

@ -79,73 +79,26 @@ js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
return !!*atomp;
}
inline bool
js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp)
{
JSAtom *atom;
if (js_ValueToAtom(cx, v, &atom)) {
*idp = ATOM_TO_JSID(atom);
return true;
}
return false;
}
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp)
{
JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
#if JS_HAS_XML_SUPPORT
extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
const js::Value &, jsid *);
if (idval.isObject())
return js_InternNonIntElementIdSlow(cx, obj, idval, idp);
#endif
return js_ValueToStringId(cx, idval, idp);
}
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp, js::Value *vp)
{
JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
#if JS_HAS_XML_SUPPORT
extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
const js::Value &,
jsid *, js::Value *);
if (idval.isObject())
return js_InternNonIntElementIdSlow(cx, obj, idval, idp, vp);
#endif
JSAtom *atom;
if (js_ValueToAtom(cx, idval, &atom)) {
*idp = ATOM_TO_JSID(atom);
vp->setString(atom);
return true;
}
return false;
}
inline bool
js_Int32ToId(JSContext* cx, int32_t index, jsid* id)
{
if (INT_FITS_IN_JSID(index)) {
*id = INT_TO_JSID(index);
return true;
}
JSString* str = js_NumberToString(cx, index);
if (!str)
return false;
return js_ValueToStringId(cx, js::StringValue(str), id);
}
namespace js {
inline bool
ValueToId(JSContext* cx, JSObject *obj, const Value &v, jsid *idp)
{
int32_t i;
if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
*idp = INT_TO_JSID(i);
return true;
}
return InternNonIntElementId(cx, obj, v, idp);
}
inline bool
ValueToId(JSContext* cx, const Value &v, jsid *idp)
{
return ValueToId(cx, NULL, v, idp);
}
/*
* Write out character representing |index| to the memory just before |end|.
* Thus |*end| is not touched, but |end[-1]| and earlier are modified as
@ -189,6 +142,18 @@ IndexToId(JSContext *cx, uint32_t index, jsid *idp)
return IndexToIdSlow(cx, index, idp);
}
inline jsid
AtomToId(JSAtom *atom)
{
JS_STATIC_ASSERT(JSID_INT_MIN == 0);
uint32_t index;
if (atom->isIndex(&index) && index <= JSID_INT_MAX)
return INT_TO_JSID((int32_t) index);
return JSID_FROM_BITS((size_t)atom);
}
static JS_ALWAYS_INLINE JSFlatString *
IdToString(JSContext *cx, jsid id)
{

View File

@ -167,7 +167,7 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj)
booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, Boolean, CLASS_ATOM(cx, Boolean), 1);
ctor = global->createConstructor(cx, Boolean, CLASS_NAME(cx, Boolean), 1);
if (!ctor)
return NULL;

View File

@ -944,7 +944,7 @@ JSStructuredCloneReader::readId(jsid *idp)
JSAtom *atom = js_AtomizeString(context(), str);
if (!atom)
return false;
*idp = ATOM_TO_JSID(atom);
*idp = NON_INTEGER_ATOM_TO_JSID(atom);
return true;
}
if (tag == SCTAG_NULL) {

View File

@ -526,8 +526,8 @@ void
ReportUsageError(JSContext *cx, JSObject *callee, const char *msg)
{
const char *usageStr = "usage";
JSAtom *usageAtom = js_Atomize(cx, usageStr, strlen(usageStr));
DebugOnly<const Shape *> shape = callee->nativeLookup(cx, ATOM_TO_JSID(usageAtom));
PropertyName *usageAtom = js_Atomize(cx, usageStr, strlen(usageStr))->asPropertyName();
DebugOnly<const Shape *> shape = callee->nativeLookup(cx, NameToId(usageAtom));
JS_ASSERT(!shape->configurable());
JS_ASSERT(!shape->writable());
JS_ASSERT(shape->hasDefaultGetter());

View File

@ -2675,7 +2675,7 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
SetDateToNaN(cx, dateProto);
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, js_Date, CLASS_ATOM(cx, Date), MAXARGS);
ctor = global->createConstructor(cx, js_Date, CLASS_NAME(cx, Date), MAXARGS);
if (!ctor)
return NULL;
@ -2693,8 +2693,8 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
if (!JS_DefineFunctions(cx, dateProto, date_methods))
return NULL;
Value toUTCStringFun;
jsid toUTCStringId = ATOM_TO_JSID(cx->runtime->atomState.toUTCStringAtom);
jsid toGMTStringId = ATOM_TO_JSID(cx->runtime->atomState.toGMTStringAtom);
jsid toUTCStringId = NameToId(cx->runtime->atomState.toUTCStringAtom);
jsid toGMTStringId = NameToId(cx->runtime->atomState.toGMTStringAtom);
if (!js_GetProperty(cx, dateProto, toUTCStringId, &toUTCStringFun) ||
!js_DefineProperty(cx, dateProto, toGMTStringId, &toUTCStringFun,
JS_PropertyStub, JS_StrictPropertyStub, 0))

View File

@ -263,7 +263,6 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id,
JSWatchPointHandler handler, JSObject *closure_)
{
assertSameCompartment(cx, obj_);
id = js_CheckForStringIndex(id);
RootedVarObject obj(cx, obj_), closure(cx, closure_);
@ -284,9 +283,8 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id,
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH_PROP);
return false;
} else {
if (!js_ValueToStringId(cx, IdToValue(id), propid.address()))
if (!ValueToId(cx, IdToValue(id), propid.address()))
return false;
propid = js_CheckForStringIndex(propid);
}
/*
@ -322,7 +320,6 @@ JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
{
assertSameCompartment(cx, obj, id);
id = js_CheckForStringIndex(id);
if (WatchpointMap *wpmap = cx->compartment->watchpointMap)
wpmap->unwatch(obj, id, handlerp, closurep);
return true;

View File

@ -301,7 +301,7 @@ InitExnPrivate(JSContext *cx, HandleObject exnObject, HandleString message,
*/
if (checkAccess && i.isNonEvalFunctionFrame()) {
Value v = NullValue();
jsid callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
jsid callerid = NameToId(cx->runtime->atomState.callerAtom);
if (!checkAccess(cx, i.callee(), callerid, JSACC_READ, &v))
break;
}
@ -715,7 +715,7 @@ exn_toString(JSContext *cx, unsigned argc, Value *vp)
/* Step 4. */
RootedVarString name(cx);
if (nameVal.isUndefined()) {
name = CLASS_ATOM(cx, Error);
name = CLASS_NAME(cx, Error);
} else {
name = ToString(cx, nameVal);
if (!name)
@ -739,7 +739,7 @@ exn_toString(JSContext *cx, unsigned argc, Value *vp)
/* Step 7. */
if (name->empty() && message->empty()) {
args.rval().setString(CLASS_ATOM(cx, Error));
args.rval().setString(CLASS_NAME(cx, Error));
return true;
}
@ -875,10 +875,10 @@ InitErrorClass(JSContext *cx, Handle<GlobalObject*> global, int type, HandleObje
return NULL;
RootedVarValue empty(cx, StringValue(cx->runtime->emptyString));
RootedVarId nameId(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom));
RootedVarId messageId(cx, ATOM_TO_JSID(cx->runtime->atomState.messageAtom));
RootedVarId fileNameId(cx, ATOM_TO_JSID(cx->runtime->atomState.fileNameAtom));
RootedVarId lineNumberId(cx, ATOM_TO_JSID(cx->runtime->atomState.lineNumberAtom));
RootedVarId nameId(cx, NameToId(cx->runtime->atomState.nameAtom));
RootedVarId messageId(cx, NameToId(cx->runtime->atomState.messageAtom));
RootedVarId fileNameId(cx, NameToId(cx->runtime->atomState.fileNameAtom));
RootedVarId lineNumberId(cx, NameToId(cx->runtime->atomState.lineNumberAtom));
if (!DefineNativeProperty(cx, errorProto, nameId, StringValue(name),
JS_PropertyStub, JS_StrictPropertyStub, 0, 0, 0) ||
!DefineNativeProperty(cx, errorProto, messageId, empty,

View File

@ -224,8 +224,8 @@ JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWit
return false;
RootedVarFunction fun(cx);
fun = js_DefineFunction(cx, objRoot,
ATOM_TO_JSID(atom), fs->call, fs->nargs, fs->flags);
fun = js_DefineFunction(cx, objRoot, AtomToId(atom),
fs->call, fs->nargs, fs->flags);
if (!fun)
return false;
@ -325,7 +325,8 @@ js::DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, J
JSAtom *atom = js_Atomize(cx, name, strlen(name));
if (!atom)
return NULL;
return js_DefineFunction(cx, objRoot, ATOM_TO_JSID(atom), call, nargs, attrs,
return js_DefineFunction(cx, objRoot, AtomToId(atom),
call, nargs, attrs,
JSFunction::ExtendedFinalizeKind);
}
@ -784,6 +785,14 @@ IncrementalReferenceBarrier(void *ptr)
JSObject::writeBarrierPre((JSObject *) ptr);
else if (kind == JSTRACE_STRING)
JSString::writeBarrierPre((JSString *) ptr);
else if (kind == JSTRACE_SCRIPT)
JSScript::writeBarrierPre((JSScript *) ptr);
else if (kind == JSTRACE_SHAPE)
Shape::writeBarrierPre((Shape *) ptr);
else if (kind == JSTRACE_BASE_SHAPE)
BaseShape::writeBarrierPre((BaseShape *) ptr);
else if (kind == JSTRACE_TYPE_OBJECT)
types::TypeObject::writeBarrierPre((types::TypeObject *) ptr);
else
JS_NOT_REACHED("invalid trace kind");
}

View File

@ -204,8 +204,8 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
/* NB: no sentinels at ends -- use ArrayLength to bound loops.
* Properties censored into [[ThrowTypeError]] in strict mode. */
static const uint16_t poisonPillProps[] = {
ATOM_OFFSET(arguments),
ATOM_OFFSET(caller),
NAME_OFFSET(arguments),
NAME_OFFSET(caller),
};
static JSBool
@ -219,22 +219,22 @@ fun_enumerate(JSContext *cx, JSObject *obj)
bool found;
if (!obj->isBoundFunction()) {
id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
id = NameToId(cx->runtime->atomState.classPrototypeAtom);
if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
return false;
}
id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
id = NameToId(cx->runtime->atomState.lengthAtom);
if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
return false;
id = ATOM_TO_JSID(cx->runtime->atomState.nameAtom);
id = NameToId(cx->runtime->atomState.nameAtom);
if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
return false;
for (unsigned i = 0; i < ArrayLength(poisonPillProps); i++) {
const uint16_t offset = poisonPillProps[i];
id = ATOM_TO_JSID(OFFSET_TO_ATOM(cx->runtime, offset));
id = NameToId(OFFSET_TO_NAME(cx->runtime, offset));
if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
return false;
}
@ -341,7 +341,7 @@ fun_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
for (unsigned i = 0; i < ArrayLength(poisonPillProps); i++) {
const uint16_t offset = poisonPillProps[i];
if (JSID_IS_ATOM(id, OFFSET_TO_ATOM(cx->runtime, offset))) {
if (JSID_IS_ATOM(id, OFFSET_TO_NAME(cx->runtime, offset))) {
JS_ASSERT(!IsInternalFunctionObject(fun));
PropertyOp getter;
@ -1212,12 +1212,12 @@ LookupInterpretedFunctionPrototype(JSContext *cx, RootedVarObject funobj)
JS_ASSERT(!funobj->isBoundFunction());
#endif
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
jsid id = NameToId(cx->runtime->atomState.classPrototypeAtom);
RootedVar<const Shape*> shape(cx, funobj->nativeLookup(cx, id));
if (!shape) {
if (!ResolveInterpretedFunctionPrototype(cx, funobj))
return NULL;
id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
id = NameToId(cx->runtime->atomState.classPrototypeAtom);
shape = funobj->nativeLookup(cx, id);
}
JS_ASSERT(!shape->configurable());

View File

@ -3688,10 +3688,8 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget,
callback(rt, JSGC_BEGIN);
}
{
rt->gcPoke = false;
GCCycle(rt, incremental, budget, gckind);
}
rt->gcPoke = false;
GCCycle(rt, incremental, budget, gckind);
if (rt->gcIncrementalState == NO_INCREMENTAL) {
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_GC_END);
@ -3699,6 +3697,10 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget,
callback(rt, JSGC_END);
}
/* Need to re-schedule all compartments for GC. */
if (!rt->hasContexts() && rt->gcPoke)
PrepareForFullGC(rt);
/*
* On shutdown, iterate until finalizers or the JSGC_END callback
* stop creating garbage.

View File

@ -84,44 +84,44 @@ using namespace js::analyze;
static inline jsid
id_prototype(JSContext *cx) {
return ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
return NameToId(cx->runtime->atomState.classPrototypeAtom);
}
static inline jsid
id_arguments(JSContext *cx) {
return ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom);
return NameToId(cx->runtime->atomState.argumentsAtom);
}
static inline jsid
id_length(JSContext *cx) {
return ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
return NameToId(cx->runtime->atomState.lengthAtom);
}
static inline jsid
id___proto__(JSContext *cx) {
return ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
return NameToId(cx->runtime->atomState.protoAtom);
}
static inline jsid
id_constructor(JSContext *cx) {
return ATOM_TO_JSID(cx->runtime->atomState.constructorAtom);
return NameToId(cx->runtime->atomState.constructorAtom);
}
static inline jsid
id_caller(JSContext *cx) {
return ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
return NameToId(cx->runtime->atomState.callerAtom);
}
static inline jsid
id_toString(JSContext *cx)
{
return ATOM_TO_JSID(cx->runtime->atomState.toStringAtom);
return NameToId(cx->runtime->atomState.toStringAtom);
}
static inline jsid
id_toSource(JSContext *cx)
{
return ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
return NameToId(cx->runtime->atomState.toSourceAtom);
}
#ifdef DEBUG
@ -1978,8 +1978,8 @@ TypeCompartment::newAllocationSiteTypeObject(JSContext *cx, const AllocationSite
static inline jsid
GetAtomId(JSContext *cx, JSScript *script, const jsbytecode *pc, unsigned offset)
{
JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc + offset));
return MakeTypeId(cx, ATOM_TO_JSID(atom));
PropertyName *name = script->getName(GET_UINT32_INDEX(pc + offset));
return MakeTypeId(cx, NameToId(name));
}
bool
@ -2902,7 +2902,7 @@ TypeObject::addPropertyType(JSContext *cx, const char *name, Type type)
cx->compartment->types.setPendingNukeTypes(cx);
return;
}
id = ATOM_TO_JSID(atom);
id = AtomToId(atom);
}
InlineAddTypeProperty(cx, this, id, type);
}
@ -3520,11 +3520,11 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
* the types of global properties the script can access. In a few cases
* the method JIT will bypass this, and we need to add the types direclty.
*/
if (id == ATOM_TO_JSID(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]))
if (id == NameToId(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]))
seen->addType(cx, Type::UndefinedType());
if (id == ATOM_TO_JSID(cx->runtime->atomState.NaNAtom))
if (id == NameToId(cx->runtime->atomState.NaNAtom))
seen->addType(cx, Type::DoubleType());
if (id == ATOM_TO_JSID(cx->runtime->atomState.InfinityAtom))
if (id == NameToId(cx->runtime->atomState.InfinityAtom))
seen->addType(cx, Type::DoubleType());
/* Handle as a property access. */
@ -4392,7 +4392,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
* integer properties and bail out. We can't mark the aggregate
* JSID_VOID type property as being in a definite slot.
*/
jsid id = ATOM_TO_JSID(script->getAtom(GET_UINT32_INDEX(pc)));
jsid id = NameToId(script->getName(GET_UINT32_INDEX(pc)));
if (MakeTypeId(cx, id) != id)
return false;
if (id == id_prototype(cx) || id == id___proto__(cx) || id == id_constructor(cx))

View File

@ -375,7 +375,7 @@ js::OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval_, Value *vp)
{
RootedVarValue idval(cx, idval_);
jsid id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
jsid id = NameToId(cx->runtime->atomState.noSuchMethodAtom);
RootedVarValue value(cx);
if (!js_GetMethod(cx, obj, id, 0, value.address()))
return false;
@ -898,28 +898,6 @@ js::TypeOfValue(JSContext *cx, const Value &vref)
return JSTYPE_BOOLEAN;
}
bool
js::ValueToId(JSContext *cx, const Value &v, jsid *idp)
{
int32_t i;
if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
*idp = INT_TO_JSID(i);
return true;
}
#if JS_HAS_XML_SUPPORT
if (v.isObject()) {
JSObject *obj = &v.toObject();
if (obj->isXMLId()) {
*idp = OBJECT_TO_JSID(obj);
return JS_TRUE;
}
}
#endif
return js_ValueToStringId(cx, v, idp);
}
/*
* Enter the new with scope using an object at sp[-1] and associate the depth
* of the with block with sp + stackIndex.
@ -2023,13 +2001,8 @@ END_CASE(JSOP_AND)
#define FETCH_ELEMENT_ID(obj, n, id) \
JS_BEGIN_MACRO \
const Value &idval_ = regs.sp[n]; \
int32_t i_; \
if (ValueFitsInInt32(idval_, &i_) && INT_FITS_IN_JSID(i_)) { \
id = INT_TO_JSID(i_); \
} else { \
if (!js_InternNonIntElementId(cx, obj, idval_, &id, &regs.sp[n])) \
goto error; \
} \
if (!ValueToId(cx, obj, idval_, &id)) \
goto error; \
JS_END_MACRO
#define TRY_BRANCH_AFTER_COND(cond,spdec) \
@ -3328,7 +3301,7 @@ BEGIN_CASE(JSOP_SETTER)
{
PropertyName *name;
LOAD_NAME(0, name);
id = ATOM_TO_JSID(name);
id = NameToId(name);
rval = regs.sp[-1];
i = -1;
goto gs_pop_lval;
@ -3348,7 +3321,7 @@ BEGIN_CASE(JSOP_SETTER)
i = -1;
PropertyName *name;
LOAD_NAME(0, name);
id = ATOM_TO_JSID(name);
id = NameToId(name);
goto gs_get_lval;
}
default:
@ -3482,11 +3455,11 @@ BEGIN_CASE(JSOP_INITPROP)
obj = &regs.sp[-2].toObject();
JS_ASSERT(obj->isObject());
JSAtom *atom;
LOAD_ATOM(0, atom);
jsid id = ATOM_TO_JSID(atom);
PropertyName *name;
LOAD_NAME(0, name);
jsid id = NameToId(name);
if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
? !js_SetPropertyHelper(cx, obj, id, 0, &rval, script->strictModeCode)
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, 0)) {

View File

@ -260,9 +260,6 @@ TypeOfValue(JSContext *cx, const Value &v);
extern JSBool
HasInstance(JSContext *cx, JSObject *obj, const js::Value *v, JSBool *bp);
extern bool
ValueToId(JSContext *cx, const Value &v, jsid *idp);
/*
* A linked list of the |FrameRegs regs;| variables belonging to all
* js::Interpret C++ frames on this thread's stack.

View File

@ -255,7 +255,7 @@ GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp
}
RootObject objRoot(cx, &obj);
RootedVarId id(cx, ATOM_TO_JSID(name));
RootedVarId id(cx, NameToId(name));
if (obj->getOps()->getProperty) {
if (!GetPropertyGenericMaybeCallXML(cx, op, objRoot, id, vp))
@ -339,7 +339,7 @@ SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Val
RootObject objRoot(cx, &obj);
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
if (JS_LIKELY(!obj->getOps()->setProperty)) {
unsigned defineHow = (op == JSOP_SETNAME)
? DNP_CACHE_RESULT | DNP_UNQUALIFIED
@ -382,7 +382,7 @@ NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
return true;
}
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
RootPropertyName nameRoot(cx, &name);
RootObject objRoot(cx, &obj);
@ -675,7 +675,7 @@ FetchElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid &id, Value
id = INT_TO_JSID(i_);
return true;
}
return !!js_InternNonIntElementId(cx, obj, idval, &id, vp);
return !!InternNonIntElementId(cx, obj, idval, &id, vp);
}
static JS_ALWAYS_INLINE bool
@ -691,7 +691,7 @@ ToIdOperation(JSContext *cx, const Value &objval, const Value &idval, Value *res
return false;
jsid dummy;
if (!js_InternNonIntElementId(cx, obj, idval, &dummy, res))
if (!InternNonIntElementId(cx, obj, idval, &dummy, res))
return false;
if (!res->isInt32())

View File

@ -264,7 +264,7 @@ static bool
EnumerateDenseArrayProperties(JSContext *cx, JSObject *obj, JSObject *pobj, unsigned flags,
IdSet &ht, AutoIdVector *props)
{
if (!Enumerate(cx, obj, pobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), false,
if (!Enumerate(cx, obj, pobj, NameToId(cx->runtime->atomState.lengthAtom), false,
flags, ht, props)) {
return false;
}
@ -458,8 +458,8 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
}
/* Check whether we have a valid __iterator__ method. */
JSAtom *atom = cx->runtime->atomState.iteratorAtom;
if (!js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, vp))
PropertyName *name = cx->runtime->atomState.iteratorAtom;
if (!js_GetMethod(cx, obj, NameToId(name), 0, vp))
return false;
/* If there is no custom __iterator__ method, we are done here. */
@ -481,7 +481,7 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
* trace, so the object we are iterating over is on top of the stack (-1).
*/
JSAutoByteString bytes;
if (!js_AtomToPrintableString(cx, atom, &bytes))
if (!js_AtomToPrintableString(cx, name, &bytes))
return false;
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
-1, ObjectValue(*obj), NULL, bytes.ptr());
@ -1016,7 +1016,6 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p
jsid id;
if (!ValueToId(cx, StringValue(*idp), &id))
return false;
id = js_CheckForStringIndex(id);
if (!proto->lookupGeneric(cx, id, &obj2, &prop))
return false;
if (prop) {
@ -1217,7 +1216,6 @@ js_IteratorMore(JSContext *cx, HandleObject iterobj, Value *rval)
jsid id;
if (!ValueToId(cx, StringValue(*ni->current()), &id))
return false;
id = js_CheckForStringIndex(id);
ni->incCursor();
if (!ni->obj->getGeneric(cx, id, rval))
return false;
@ -1244,7 +1242,7 @@ js_IteratorMore(JSContext *cx, HandleObject iterobj, Value *rval)
}
} else {
/* Call the iterator object's .next method. */
jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom);
jsid id = NameToId(cx->runtime->atomState.nextAtom);
if (!js_GetMethod(cx, iterobj, id, 0, rval))
return false;
if (!Invoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) {
@ -1745,7 +1743,7 @@ InitIteratorClass(JSContext *cx, Handle<GlobalObject*> global)
iteratorProto->setNativeIterator(ni);
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, Iterator, CLASS_ATOM(cx, Iterator), 2);
ctor = global->createConstructor(cx, Iterator, CLASS_NAME(cx, Iterator), 2);
if (!ctor)
return false;

View File

@ -653,7 +653,7 @@ math_tan(JSContext *cx, unsigned argc, Value *vp)
static JSBool
math_toSource(JSContext *cx, unsigned argc, Value *vp)
{
vp->setString(CLASS_ATOM(cx, Math));
vp->setString(CLASS_NAME(cx, Math));
return JS_TRUE;
}
#endif

View File

@ -1026,7 +1026,7 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
numberProto->asNumber().setPrimitiveValue(0);
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, Number, CLASS_ATOM(cx, Number), 1);
ctor = global->createConstructor(cx, Number, CLASS_NAME(cx, Number), 1);
if (!ctor)
return NULL;
@ -1044,10 +1044,10 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
return NULL;
/* ES5 15.1.1.1, 15.1.1.2 */
if (!DefineNativeProperty(cx, global, ATOM_TO_JSID(cx->runtime->atomState.NaNAtom),
if (!DefineNativeProperty(cx, global, NameToId(cx->runtime->atomState.NaNAtom),
cx->runtime->NaNValue, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0) ||
!DefineNativeProperty(cx, global, ATOM_TO_JSID(cx->runtime->atomState.InfinityAtom),
!DefineNativeProperty(cx, global, NameToId(cx->runtime->atomState.InfinityAtom),
cx->runtime->positiveInfinityValue,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0))

View File

@ -151,7 +151,7 @@ obj_getProto(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
/* Let CheckAccess get the slot's value, based on the access mode. */
unsigned attrs;
id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
id = NameToId(cx->runtime->atomState.protoAtom);
return CheckAccess(cx, obj, id, JSACC_PROTO, vp, &attrs);
}
@ -176,7 +176,7 @@ obj_setProto(JSContext *cx, JSObject *obj_, jsid id, JSBool strict, Value *vp)
RootedVarObject pobj(cx, vp->toObjectOrNull());
unsigned attrs;
id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
id = NameToId(cx->runtime->atomState.protoAtom);
if (!CheckAccess(cx, obj, id, JSAccessMode(JSACC_PROTO|JSACC_WRITE), vp, &attrs))
return false;
@ -715,7 +715,7 @@ obj_toLocaleString(JSContext *cx, unsigned argc, Value *vp)
return false;
/* Steps 2-4. */
return obj->callMethod(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), 0, NULL, vp);
return obj->callMethod(cx, NameToId(cx->runtime->atomState.toStringAtom), 0, NULL, vp);
}
static JSBool
@ -1527,7 +1527,7 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
JSObject *obj = &vp[2].toObject();
unsigned attrs;
return CheckAccess(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.protoAtom),
return CheckAccess(cx, obj, NameToId(cx->runtime->atomState.protoAtom),
JSACC_PROTO, vp, &attrs);
}
@ -1786,7 +1786,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
#ifdef __GNUC__ /* quell GCC overwarning */
found = false;
#endif
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.enumerableAtom), &v, &found))
if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.enumerableAtom), &v, &found))
return false;
if (found) {
hasEnumerable_ = true;
@ -1795,7 +1795,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
}
/* 8.10.5 step 4 */
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.configurableAtom), &v, &found))
if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.configurableAtom), &v, &found))
return false;
if (found) {
hasConfigurable_ = true;
@ -1804,7 +1804,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
}
/* 8.10.5 step 5 */
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.valueAtom), &v, &found))
if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.valueAtom), &v, &found))
return false;
if (found) {
hasValue_ = true;
@ -1812,7 +1812,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
}
/* 8.10.6 step 6 */
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.writableAtom), &v, &found))
if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.writableAtom), &v, &found))
return false;
if (found) {
hasWritable_ = true;
@ -1821,7 +1821,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
}
/* 8.10.7 step 7 */
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.getAtom), &v, &found))
if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.getAtom), &v, &found))
return false;
if (found) {
hasGet_ = true;
@ -1833,7 +1833,7 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
}
/* 8.10.7 step 8 */
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.setAtom), &v, &found))
if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.setAtom), &v, &found))
return false;
if (found) {
hasSet_ = true;
@ -3106,8 +3106,6 @@ JSObject::nonNativeSetProperty(JSContext *cx, jsid id, js::Value *vp, JSBool str
{
JSObject *self = this;
if (JS_UNLIKELY(watched())) {
id = js_CheckForStringIndex(id);
RootObject selfRoot(cx, &self);
RootId idRoot(cx, &id);
@ -3128,7 +3126,6 @@ JSObject::nonNativeSetElement(JSContext *cx, uint32_t index, js::Value *vp, JSBo
jsid id;
if (!IndexToId(cx, index, &id))
return false;
JS_ASSERT(id == js_CheckForStringIndex(id));
RootId idRoot(cx, &id);
@ -3570,7 +3567,7 @@ static bool
DefineStandardSlot(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom,
const Value &v, uint32_t attrs, bool &named)
{
jsid id = ATOM_TO_JSID(atom);
jsid id = AtomToId(atom);
if (key != JSProto_Null) {
/*
@ -4244,7 +4241,7 @@ js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
return true;
}
AutoResolving resolving(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]));
AutoResolving resolving(cx, obj, NameToId(cx->runtime->atomState.classAtoms[key]));
if (resolving.alreadyStarted()) {
/* Already caching id in obj -- suppress recursion. */
*objp = NULL;
@ -4293,12 +4290,12 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
vp->setObject(*cobj);
return JS_TRUE;
}
id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[protoKey]);
id = NameToId(cx->runtime->atomState.classAtoms[protoKey]);
} else {
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name));
if (!atom)
return false;
id = ATOM_TO_JSID(atom);
id = AtomToId(atom);
}
JS_ASSERT(obj->isNative());
@ -4443,9 +4440,6 @@ js_AddNativeProperty(JSContext *cx, HandleObject obj, jsid id_,
{
RootedVarId id(cx, id_);
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
/*
* Purge the property cache of now-shadowed id in obj's scope chain. Do
* this optimistically (assuming no failure below) before locking obj, so
@ -4525,9 +4519,6 @@ DefineNativeProperty(JSContext *cx, HandleObject obj, jsid id, const Value &valu
RootedVarValue value(cx);
value = value_;
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
/*
* If defining a getter or setter, we must check for its counterpart and
* update the attributes and property ops. A getter or setter is really
@ -4708,9 +4699,6 @@ LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj_, jsid id_, unsigned
RootedVarObject obj(cx, obj_);
RootedVarId id(cx, id_);
/* We should not get string indices which aren't already integers here. */
JS_ASSERT(id.raw() == js_CheckForStringIndex(id));
/* Search scopes starting with obj and following the prototype link. */
RootedVarObject start(cx, obj);
while (true) {
@ -4773,9 +4761,6 @@ JS_FRIEND_API(JSBool)
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
JSProperty **propp)
{
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
return LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp);
}
@ -4793,9 +4778,6 @@ bool
js::LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
JSObject **objp, JSProperty **propp)
{
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
return LookupPropertyWithFlagsInline(cx, obj, id, flags, objp, propp);
}
@ -4804,7 +4786,7 @@ js::FindPropertyHelper(JSContext *cx,
HandlePropertyName name, bool cacheResult, HandleObject scopeChain,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
{
RootedVarId id(cx, ATOM_TO_JSID(name));
RootedVarId id(cx, NameToId(name));
JSObject *pobj;
int scopeIndex;
@ -5064,9 +5046,6 @@ js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receive
RootedVarId id(cx, id_);
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
/* This call site is hot -- use the always-inlined variant of LookupPropertyWithFlags(). */
RootedVarObject obj2(cx);
if (!LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, obj2.address(), &prop))
@ -5281,9 +5260,6 @@ js_SetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, unsigned defineHo
JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
RootId idRoot(cx, &id);
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
if (JS_UNLIKELY(obj->watched())) {
/* Fire watchpoints, if any. */
WatchpointMap *wpmap = cx->compartment->watchpointMap;
@ -5538,9 +5514,6 @@ js_DeleteGeneric(JSContext *cx, JSObject *obj_, jsid id_, Value *rval, JSBool st
RootedVarObject obj(cx, obj_);
RootedVarId id(cx, id_);
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
if (!js_LookupProperty(cx, obj, id, &proto, &prop))
return false;
if (!prop || proto != obj) {
@ -5564,7 +5537,11 @@ js_DeleteGeneric(JSContext *cx, JSObject *obj_, jsid id_, Value *rval, JSBool st
GCPoke(cx->runtime, v);
}
if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, shape->getUserId(), rval))
jsid userid;
if (!shape->getUserId(cx, &userid))
return false;
if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, userid, rval))
return false;
if (rval->isFalse())
return true;
@ -5575,7 +5552,7 @@ js_DeleteGeneric(JSContext *cx, JSObject *obj_, jsid id_, Value *rval, JSBool st
JSBool
js_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
{
return js_DeleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
return js_DeleteGeneric(cx, obj, NameToId(name), rval, strict);
}
JSBool
@ -5600,7 +5577,6 @@ namespace js {
bool
HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp)
{
JS_ASSERT(id == js_CheckForStringIndex(id));
if (const Shape *shape = obj->nativeLookup(cx, id)) {
if (shape->hasDefaultGetter() && shape->hasSlot()) {
*vp = obj->nativeGetSlot(shape->slot());
@ -5643,18 +5619,18 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp)
if (clasp == &StringClass &&
ClassMethodIsNative(cx, obj,
&StringClass,
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom)),
RootedVarId(cx, NameToId(cx->runtime->atomState.toStringAtom)),
js_str_toString)) {
*vp = StringValue(obj->asString().unbox());
return true;
}
if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), vp))
if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.toStringAtom), vp))
return false;
if (vp->isPrimitive())
return true;
if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom), vp))
if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.valueOfAtom), vp))
return false;
if (vp->isPrimitive())
return true;
@ -5662,11 +5638,11 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp)
/* Optimize (new String(...)).valueOf(). */
if ((clasp == &StringClass &&
ClassMethodIsNative(cx, obj, &StringClass,
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom)),
RootedVarId(cx, NameToId(cx->runtime->atomState.valueOfAtom)),
js_str_toString)) ||
(clasp == &NumberClass &&
ClassMethodIsNative(cx, obj, &NumberClass,
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom)),
RootedVarId(cx, NameToId(cx->runtime->atomState.valueOfAtom)),
js_num_valueOf))) {
*vp = obj->isString()
? StringValue(obj->asString().unbox())
@ -5674,12 +5650,12 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp)
return true;
}
if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom), vp))
if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.valueOfAtom), vp))
return false;
if (vp->isPrimitive())
return true;
if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), vp))
if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.toStringAtom), vp))
return false;
if (vp->isPrimitive())
return true;

View File

@ -134,7 +134,7 @@ inline bool
LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
JSObject **objp, JSProperty **propp)
{
return js_LookupProperty(cx, obj, ATOM_TO_JSID(name), objp, propp);
return js_LookupProperty(cx, obj, NameToId(name), objp, propp);
}
}
@ -186,7 +186,7 @@ inline bool
SetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, unsigned defineHow,
Value *vp, JSBool strict)
{
return !!js_SetPropertyHelper(cx, obj, ATOM_TO_JSID(name), defineHow, vp, strict);
return !!js_SetPropertyHelper(cx, obj, NameToId(name), defineHow, vp, strict);
}
} /* namespace js */
@ -797,7 +797,7 @@ struct JSObject : public js::ObjectImpl
putProperty(JSContext *cx, js::PropertyName *name,
JSPropertyOp getter, JSStrictPropertyOp setter,
uint32_t slot, unsigned attrs, unsigned flags, int shortid) {
return putProperty(cx, js_CheckForStringIndex(ATOM_TO_JSID(name)), getter, setter, slot, attrs, flags, shortid);
return putProperty(cx, js::NameToId(name), getter, setter, slot, attrs, flags, shortid);
}
/* Change the given property into a sibling with the same id in this scope. */
@ -1132,9 +1132,6 @@ js_CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
extern JSObject *
js_CreateThis(JSContext *cx, js::Class *clasp, JSObject *callee);
extern jsid
js_CheckForStringIndex(jsid id);
/*
* Find or create a property named by id in obj's scope, with the given getter
* and setter, slot, attributes, and other members.
@ -1173,7 +1170,7 @@ DefineNativeProperty(JSContext *cx, HandleObject obj, PropertyName *name, const
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
unsigned flags, int shortid, unsigned defineHow = 0)
{
return DefineNativeProperty(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs, flags,
return DefineNativeProperty(cx, obj, NameToId(name), value, getter, setter, attrs, flags,
shortid, defineHow);
}
@ -1188,7 +1185,7 @@ inline bool
LookupPropertyWithFlags(JSContext *cx, JSObject *obj, PropertyName *name, unsigned flags,
JSObject **objp, JSProperty **propp)
{
return LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(name), flags, objp, propp);
return LookupPropertyWithFlags(cx, obj, NameToId(name), flags, objp, propp);
}
/*
@ -1267,7 +1264,7 @@ GetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, uint32_t getHow, Val
inline bool
GetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, uint32_t getHow, Value *vp)
{
return GetPropertyHelper(cx, obj, ATOM_TO_JSID(name), getHow, vp);
return GetPropertyHelper(cx, obj, NameToId(name), getHow, vp);
}
bool
@ -1289,7 +1286,7 @@ namespace js {
inline bool
GetMethod(JSContext *cx, HandleObject obj, PropertyName *name, unsigned getHow, Value *vp)
{
return js_GetMethod(cx, obj, ATOM_TO_JSID(name), getHow, vp);
return js_GetMethod(cx, obj, NameToId(name), getHow, vp);
}
} /* namespace js */
@ -1298,16 +1295,15 @@ namespace js {
/*
* If obj has an already-resolved data property for id, return true and
* store the property value in *vp. This helper assumes the caller has already
* called js_CheckForStringIndex.
* store the property value in *vp.
*/
extern bool
HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp);
inline bool
HasDataProperty(JSContext *cx, HandleObject obj, JSAtom *atom, Value *vp)
HasDataProperty(JSContext *cx, HandleObject obj, PropertyName *name, Value *vp)
{
return HasDataProperty(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(atom)), vp);
return HasDataProperty(cx, obj, NameToId(name), vp);
}
extern JSBool

View File

@ -131,7 +131,7 @@ JSObject::setGeneric(JSContext *cx, jsid id, js::Value *vp, JSBool strict)
inline JSBool
JSObject::setProperty(JSContext *cx, js::PropertyName *name, js::Value *vp, JSBool strict)
{
return setGeneric(cx, ATOM_TO_JSID(name), vp, strict);
return setGeneric(cx, js::NameToId(name), vp, strict);
}
inline JSBool
@ -159,7 +159,7 @@ JSObject::setGenericAttributes(JSContext *cx, jsid id, unsigned *attrsp)
inline JSBool
JSObject::setPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
{
return setGenericAttributes(cx, ATOM_TO_JSID(name), attrsp);
return setGenericAttributes(cx, js::NameToId(name), attrsp);
}
inline JSBool
@ -198,7 +198,7 @@ JSObject::getGeneric(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp)
inline JSBool
JSObject::getProperty(JSContext *cx, JSObject *receiver, js::PropertyName *name, js::Value *vp)
{
return getGeneric(cx, receiver, ATOM_TO_JSID(name), vp);
return getGeneric(cx, receiver, js::NameToId(name), vp);
}
inline JSBool
@ -210,13 +210,13 @@ JSObject::getGeneric(JSContext *cx, jsid id, js::Value *vp)
inline JSBool
JSObject::getProperty(JSContext *cx, js::PropertyName *name, js::Value *vp)
{
return getGeneric(cx, ATOM_TO_JSID(name), vp);
return getGeneric(cx, js::NameToId(name), vp);
}
inline bool
JSObject::deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, bool strict)
{
jsid id = js_CheckForStringIndex(ATOM_TO_JSID(name));
jsid id = js::NameToId(name);
js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
js::types::MarkTypePropertyConfigured(cx, this, id);
js::DeletePropertyOp op = getOps()->deleteProperty;
@ -398,7 +398,7 @@ JSObject::setArrayLength(JSContext *cx, uint32_t length)
js::types::MarkTypeObjectFlags(cx, this,
js::types::OBJECT_FLAG_NON_PACKED_ARRAY |
js::types::OBJECT_FLAG_NON_DENSE_ARRAY);
jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
jsid lengthId = js::NameToId(cx->runtime->atomState.lengthAtom);
js::types::AddTypePropertyId(cx, this, lengthId,
js::types::Type::DoubleType());
}
@ -1030,7 +1030,7 @@ JSObject::lookupGeneric(JSContext *cx, jsid id, JSObject **objp, JSProperty **pr
inline JSBool
JSObject::lookupProperty(JSContext *cx, js::PropertyName *name, JSObject **objp, JSProperty **propp)
{
return lookupGeneric(cx, ATOM_TO_JSID(name), objp, propp);
return lookupGeneric(cx, js::NameToId(name), objp, propp);
}
inline JSBool
@ -1050,7 +1050,7 @@ JSObject::defineProperty(JSContext *cx, js::PropertyName *name, const js::Value
JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
unsigned attrs /* = JSPROP_ENUMERATE */)
{
return defineGeneric(cx, ATOM_TO_JSID(name), value, getter, setter, attrs);
return defineGeneric(cx, js::NameToId(name), value, getter, setter, attrs);
}
inline JSBool
@ -1157,7 +1157,7 @@ JSObject::getGenericAttributes(JSContext *cx, jsid id, unsigned *attrsp)
inline JSBool
JSObject::getPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
{
return getGenericAttributes(cx, ATOM_TO_JSID(name), attrsp);
return getGenericAttributes(cx, js::NameToId(name), attrsp);
}
inline JSBool
@ -1548,7 +1548,7 @@ DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global,
JS_ASSERT(ctor);
JS_ASSERT(proto);
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]);
jsid id = NameToId(cx->runtime->atomState.classAtoms[key]);
JS_ASSERT(!global->nativeLookupNoAllocation(cx, id));
/* Set these first in case AddTypePropertyId looks for this class. */

View File

@ -313,7 +313,7 @@ PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, Stringi
/* Step 2. */
if (vp->isObject()) {
Value toJSON;
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toJSONAtom);
jsid id = NameToId(cx->runtime->atomState.toJSONAtom);
if (!js_GetMethod(cx, RootedVarObject(cx, &vp->toObject()), id, 0, &toJSON))
return false;
@ -680,9 +680,8 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer_, Value space, StringB
if (v.isNumber() && ValueFitsInInt32(v, &n) && INT_FITS_IN_JSID(n)) {
id = INT_TO_JSID(n);
} else {
if (!js_ValueToStringId(cx, v, &id))
if (!ValueToId(cx, v, &id))
return false;
id = js_CheckForStringIndex(id);
}
} else if (v.isString() ||
(v.isObject() &&
@ -690,9 +689,8 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer_, Value space, StringB
ObjectClassIs(v.toObject(), ESClass_Number, cx))))
{
/* Step 4b(iv)(3), 4b(iv)(5). */
if (!js_ValueToStringId(cx, v, &id))
if (!ValueToId(cx, v, &id))
return false;
id = js_CheckForStringIndex(id);
} else {
continue;
}
@ -755,7 +753,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer_, Value space, StringB
return false;
/* Step 10. */
jsid emptyId = ATOM_TO_JSID(cx->runtime->atomState.emptyAtom);
jsid emptyId = NameToId(cx->runtime->atomState.emptyAtom);
if (!DefineNativeProperty(cx, wrapper, emptyId, *vp, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE, 0, 0))
{
@ -889,7 +887,7 @@ Revive(JSContext *cx, const Value &reviver, Value *vp)
if (!obj->defineProperty(cx, cx->runtime->atomState.emptyAtom, *vp))
return false;
return Walk(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.emptyAtom), reviver, vp);
return Walk(cx, obj, NameToId(cx->runtime->atomState.emptyAtom), reviver, vp);
}
namespace js {
@ -916,7 +914,7 @@ ParseJSONWithReviver(JSContext *cx, const jschar *chars, size_t length, const Va
static JSBool
json_toSource(JSContext *cx, unsigned argc, Value *vp)
{
vp->setString(CLASS_ATOM(cx, JSON));
vp->setString(CLASS_NAME(cx, JSON));
return JS_TRUE;
}
#endif

View File

@ -534,11 +534,7 @@ JSONParser::parse(Value *vp)
switch (state) {
case FinishObjectMember: {
Value v = valueStack.popCopy();
/*
* NB: Relies on js_DefineNativeProperty performing
* js_CheckForStringIndex.
*/
jsid propid = ATOM_TO_JSID(&valueStack.popCopy().toString()->asAtom());
jsid propid = AtomToId(&valueStack.popCopy().toString()->asAtom());
RootedVarObject obj(cx, &valueStack.back().toObject());
if (!DefineNativeProperty(cx, obj, propid, v,
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE,

View File

@ -227,7 +227,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
if (pobj->lastProperty() == entry->pshape) {
#ifdef DEBUG
PropertyName *name = GetNameFromBytecode(cx, pc, op, cs);
JS_ASSERT(pobj->nativeContains(cx, js_CheckForStringIndex(ATOM_TO_JSID(name))));
JS_ASSERT(pobj->nativeContains(cx, NameToId(name)));
#endif
*pobjp = pobj;
return NULL;

View File

@ -396,22 +396,22 @@ ProxyHandler::trace(JSTracer *trc, JSObject *proxy)
}
static bool
GetTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
GetTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
{
JS_CHECK_RECURSION(cx, return false);
return handler->getGeneric(cx, ATOM_TO_JSID(atom), fvalp);
return handler->getGeneric(cx, NameToId(name), fvalp);
}
static bool
GetFundamentalTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
GetFundamentalTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
{
if (!GetTrap(cx, handler, atom, fvalp))
if (!GetTrap(cx, handler, name, fvalp))
return false;
if (!js_IsCallable(*fvalp)) {
JSAutoByteString bytes;
if (js_AtomToPrintableString(cx, atom, &bytes))
if (js_AtomToPrintableString(cx, name, &bytes))
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_FUNCTION, bytes.ptr());
return false;
}
@ -420,16 +420,16 @@ GetFundamentalTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
}
static bool
GetDerivedTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
GetDerivedTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
{
JS_ASSERT(atom == ATOM(has) ||
atom == ATOM(hasOwn) ||
atom == ATOM(get) ||
atom == ATOM(set) ||
atom == ATOM(keys) ||
atom == ATOM(iterate));
JS_ASSERT(name == ATOM(has) ||
name == ATOM(hasOwn) ||
name == ATOM(get) ||
name == ATOM(set) ||
name == ATOM(keys) ||
name == ATOM(iterate));
return GetTrap(cx, handler, atom, fvalp);
return GetTrap(cx, handler, name, fvalp);
}
static bool
@ -513,7 +513,7 @@ ArrayToIdVector(JSContext *cx, const Value &array, AutoIdVector &props)
jsid id;
if (!ValueToId(cx, v, &id))
return false;
if (!props.append(js_CheckForStringIndex(id)))
if (!props.append(id))
return false;
}
@ -1003,8 +1003,6 @@ proxy_LookupGeneric(JSContext *cx, JSObject *obj_, jsid id, JSObject **objp,
{
RootedVarObject obj(cx, obj_);
id = js_CheckForStringIndex(id);
bool found;
if (!Proxy::has(cx, obj, id, &found))
return false;
@ -1023,7 +1021,7 @@ static JSBool
proxy_LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
JSProperty **propp)
{
return proxy_LookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
return proxy_LookupGeneric(cx, obj, NameToId(name), objp, propp);
}
static JSBool
@ -1048,8 +1046,6 @@ static JSBool
proxy_DefineGeneric(JSContext *cx, JSObject *obj, jsid id, const Value *value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
id = js_CheckForStringIndex(id);
AutoPropertyDescriptorRooter desc(cx);
desc.obj = obj;
desc.value = *value;
@ -1064,7 +1060,7 @@ static JSBool
proxy_DefineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
return proxy_DefineGeneric(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs);
return proxy_DefineGeneric(cx, obj, NameToId(name), value, getter, setter, attrs);
}
static JSBool
@ -1089,15 +1085,13 @@ proxy_DefineSpecial(JSContext *cx, JSObject *obj, SpecialId sid, const Value *va
static JSBool
proxy_GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
{
id = js_CheckForStringIndex(id);
return Proxy::get(cx, obj, receiver, id, vp);
}
static JSBool
proxy_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
{
return proxy_GetGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
return proxy_GetGeneric(cx, obj, receiver, NameToId(name), vp);
}
static JSBool
@ -1128,15 +1122,13 @@ proxy_GetSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid
static JSBool
proxy_SetGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
{
id = js_CheckForStringIndex(id);
return Proxy::set(cx, obj, obj, id, strict, vp);
}
static JSBool
proxy_SetProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
{
return proxy_SetGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
return proxy_SetGeneric(cx, obj, NameToId(name), vp, strict);
}
static JSBool
@ -1159,8 +1151,6 @@ proxy_SetSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *vp, JSBool
static JSBool
proxy_GetGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp)
{
id = js_CheckForStringIndex(id);
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getOwnPropertyDescriptor(cx, obj, id, false, &desc))
return false;
@ -1171,7 +1161,7 @@ proxy_GetGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attr
static JSBool
proxy_GetPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
{
return proxy_GetGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
return proxy_GetGenericAttributes(cx, obj, NameToId(name), attrsp);
}
static JSBool
@ -1194,8 +1184,6 @@ proxy_GetSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned
static JSBool
proxy_SetGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp)
{
id = js_CheckForStringIndex(id);
/* Lookup the current property descriptor so we have setter/getter/value. */
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getOwnPropertyDescriptor(cx, obj, id, true, &desc))
@ -1207,7 +1195,7 @@ proxy_SetGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attr
static JSBool
proxy_SetPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
{
return proxy_SetGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
return proxy_SetGenericAttributes(cx, obj, NameToId(name), attrsp);
}
static JSBool
@ -1230,8 +1218,6 @@ proxy_SetSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned
static JSBool
proxy_DeleteGeneric(JSContext *cx, JSObject *obj_, jsid id, Value *rval, JSBool strict)
{
JS_ASSERT(id == js_CheckForStringIndex(id));
RootedVarObject obj(cx, obj_);
// TODO: throwing away strict
@ -1245,7 +1231,7 @@ proxy_DeleteGeneric(JSContext *cx, JSObject *obj_, jsid id, Value *rval, JSBool
static JSBool
proxy_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
{
return proxy_DeleteGeneric(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(name)), rval, strict);
return proxy_DeleteGeneric(cx, obj, NameToId(name), rval, strict);
}
static JSBool

View File

@ -206,7 +206,7 @@ class NodeBuilder
JSAtom *atom = js_Atomize(cx, name, strlen(name));
if (!atom)
return false;
RootedVarId id(cx, ATOM_TO_JSID(atom));
RootedVarId id(cx, AtomToId(atom));
if (!GetPropertyDefault(cx, userobj, id, NullValue(), &funv))
return false;
@ -3135,7 +3135,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
Value prop;
/* config.loc */
RootedVarId locId(cx, ATOM_TO_JSID(cx->runtime->atomState.locAtom));
RootedVarId locId(cx, NameToId(cx->runtime->atomState.locAtom));
if (!GetPropertyDefault(cx, config, locId, BooleanValue(true), &prop))
return JS_FALSE;
@ -3143,7 +3143,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
if (loc) {
/* config.source */
RootedVarId sourceId(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom));
RootedVarId sourceId(cx, NameToId(cx->runtime->atomState.sourceAtom));
if (!GetPropertyDefault(cx, config, sourceId, NullValue(), &prop))
return JS_FALSE;
@ -3164,7 +3164,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
}
/* config.line */
RootedVarId lineId(cx, ATOM_TO_JSID(cx->runtime->atomState.lineAtom));
RootedVarId lineId(cx, NameToId(cx->runtime->atomState.lineAtom));
if (!GetPropertyDefault(cx, config, lineId, Int32Value(1), &prop) ||
!ToUint32(cx, prop, &lineno)) {
return JS_FALSE;
@ -3172,7 +3172,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
}
/* config.builder */
RootedVarId builderId(cx, ATOM_TO_JSID(cx->runtime->atomState.builderAtom));
RootedVarId builderId(cx, NameToId(cx->runtime->atomState.builderAtom));
if (!GetPropertyDefault(cx, config, builderId, NullValue(), &prop))
return JS_FALSE;

View File

@ -763,9 +763,7 @@ struct Shape : public js::gc::Cell
* If SHORTID is set in shape->flags, we use shape->shortid rather
* than id when calling shape's getter or setter.
*/
jsid getUserId() const {
return hasShortID() ? INT_TO_JSID(shortid()) : propid();
}
inline bool getUserId(JSContext *cx, jsid *idp) const;
uint8_t attributes() const { return attrs; }
bool configurable() const { return (attrs & JSPROP_PERMANENT) == 0; }

View File

@ -276,6 +276,27 @@ Shape::matchesParamsAfterId(BaseShape *base, uint32_t aslot,
shortid_ == ashortid;
}
inline bool
Shape::getUserId(JSContext *cx, jsid *idp) const
{
const Shape *self = this;
#ifdef DEBUG
{
SkipRoot skip(cx, &self);
MaybeCheckStackRoots(cx);
}
#endif
if (self->hasShortID()) {
int16_t id = self->shortid();
if (id < 0)
return ValueToId(cx, Int32Value(id), idp);
*idp = INT_TO_JSID(id);
} else {
*idp = propid();
}
return true;
}
inline bool
Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const
{
@ -292,7 +313,12 @@ Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js:
*/
if (obj->isWith())
obj = &obj->asWith().object();
return js::CallJSPropertyOp(cx, getterOp(), receiver, getUserId(), vp);
jsid id;
if (!getUserId(cx, &id))
return false;
return js::CallJSPropertyOp(cx, getterOp(), receiver, id, vp);
}
inline bool
@ -311,7 +337,12 @@ Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const
/* See the comment in js::Shape::get as to why we check for With. */
if (obj->isWith())
obj = &obj->asWith().object();
return js::CallJSPropertyOpSetter(cx, setterOp(), obj, getUserId(), strict, vp);
jsid id;
if (!getUserId(cx, &id))
return false;
return js::CallJSPropertyOpSetter(cx, setterOp(), obj, id, strict, vp);
}
inline void

View File

@ -91,7 +91,7 @@ Bindings::lookup(JSContext *cx, JSAtom *name, unsigned *indexp) const
return NONE;
Shape **spp;
Shape *shape = Shape::search(cx, lastBinding, ATOM_TO_JSID(name), &spp);
Shape *shape = Shape::search(cx, lastBinding, AtomToId(name), &spp);
if (!shape)
return NONE;
@ -152,7 +152,7 @@ Bindings::add(JSContext *cx, HandleAtom name, BindingKind kind)
JS_ASSERT(kind == ARGUMENT); /* destructuring */
id = INT_TO_JSID(nargs);
} else {
id = ATOM_TO_JSID(name);
id = AtomToId(name);
}
StackBaseShape base(&CallClass, NULL, BaseShape::VAROBJ);
@ -1019,19 +1019,20 @@ js::FreeScriptFilenames(JSRuntime *rt)
*
* First are some optional array headers. They are optional because they
* often aren't needed, i.e. the corresponding arrays often have zero elements.
* Each header has an offset in JSScript that indicates its location within
* |data|; that offset is INVALID_OFFSET if the array header is not present.
* Each header also has an accessor function in JSScript.
* Each header has a bit in JSScript::hasArrayBits that indicates if it's
* present within |data|; from this the offset of each present array header
* can be computed. Each header has an accessor function in JSScript that
* encapsulates this offset computation.
*
* Array type Array elements Offset Accessor
* ---------- -------------- ------ --------
* ConstArray Consts constsOffset consts()
* ObjectArray Objects objectsOffset objects()
* ObjectArray Regexps regexpsOffset regexps()
* TryNoteArray Try notes tryNotesOffset trynotes()
* GlobalSlotArray Globals globalsOffset globals()
* ClosedSlotArray ClosedArgs closedArgsOffset closedArgs()
* ClosedSlotArray ClosedVars closedVarsOffset closedVars()
* Array type Array elements Accessor
* ---------- -------------- --------
* ConstArray Consts consts()
* ObjectArray Objects objects()
* ObjectArray Regexps regexps()
* TryNoteArray Try notes trynotes()
* GlobalSlotArray Globals globals()
* ClosedSlotArray ClosedArgs closedArgs()
* ClosedSlotArray ClosedVars closedVars()
*
* Then are the elements of several arrays.
* - Most of these arrays have headers listed above (if present). For each of
@ -1099,21 +1100,6 @@ JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(uint32_t, uint32_t));
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(uint32_t, jsbytecode));
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(jsbytecode, jssrcnote));
/*
* Check that uint8_t offsets is enough to reach any optional array allocated
* within |data|. For that we check that the maximum possible offset for the
* closedVars array -- the last optional array -- still fits in 1 byte and does
* not coincide with INVALID_OFFSET.
*/
JS_STATIC_ASSERT(sizeof(ConstArray) +
sizeof(ObjectArray) +
sizeof(ObjectArray) +
sizeof(TryNoteArray) +
sizeof(GlobalSlotArray) +
sizeof(ClosedSlotArray)
< JSScript::INVALID_OFFSET);
JS_STATIC_ASSERT(JSScript::INVALID_OFFSET <= 255);
static inline size_t
ScriptDataSize(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
uint32_t nobjects, uint32_t nregexps, uint32_t ntrynotes, uint32_t nconsts,
@ -1180,47 +1166,32 @@ JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t
uint8_t *cursor = data;
if (nconsts != 0) {
script->constsOffset = uint8_t(cursor - data);
script->setHasArray(CONSTS);
cursor += sizeof(ConstArray);
} else {
script->constsOffset = JSScript::INVALID_OFFSET;
}
if (nobjects != 0) {
script->objectsOffset = uint8_t(cursor - data);
script->setHasArray(OBJECTS);
cursor += sizeof(ObjectArray);
} else {
script->objectsOffset = JSScript::INVALID_OFFSET;
}
if (nregexps != 0) {
script->regexpsOffset = uint8_t(cursor - data);
script->setHasArray(REGEXPS);
cursor += sizeof(ObjectArray);
} else {
script->regexpsOffset = JSScript::INVALID_OFFSET;
}
if (ntrynotes != 0) {
script->trynotesOffset = uint8_t(cursor - data);
script->setHasArray(TRYNOTES);
cursor += sizeof(TryNoteArray);
} else {
script->trynotesOffset = JSScript::INVALID_OFFSET;
}
if (nglobals != 0) {
script->globalsOffset = uint8_t(cursor - data);
script->setHasArray(GLOBALS);
cursor += sizeof(GlobalSlotArray);
} else {
script->globalsOffset = JSScript::INVALID_OFFSET;
}
if (nClosedArgs != 0) {
script->closedArgsOffset = uint8_t(cursor - data);
script->setHasArray(CLOSED_ARGS);
cursor += sizeof(ClosedSlotArray);
} else {
script->closedArgsOffset = JSScript::INVALID_OFFSET;
}
JS_ASSERT(cursor - data < 0xFF);
if (nClosedVars != 0) {
script->closedVarsOffset = uint8_t(cursor - data);
script->setHasArray(CLOSED_VARS);
cursor += sizeof(ClosedSlotArray);
} else {
script->closedVarsOffset = JSScript::INVALID_OFFSET;
}
if (nconsts != 0) {
@ -1765,13 +1736,13 @@ js::CloneScript(JSContext *cx, JSScript *src)
{
/* NB: Keep this in sync with XDRScript. */
uint32_t nconsts = JSScript::isValidOffset(src->constsOffset) ? src->consts()->length : 0;
uint32_t nobjects = JSScript::isValidOffset(src->objectsOffset) ? src->objects()->length : 0;
uint32_t nregexps = JSScript::isValidOffset(src->regexpsOffset) ? src->regexps()->length : 0;
uint32_t ntrynotes = JSScript::isValidOffset(src->trynotesOffset) ? src->trynotes()->length : 0;
uint32_t nconsts = src->hasConsts() ? src->consts()->length : 0;
uint32_t nobjects = src->hasObjects() ? src->objects()->length : 0;
uint32_t nregexps = src->hasRegexps() ? src->regexps()->length : 0;
uint32_t ntrynotes = src->hasTrynotes() ? src->trynotes()->length : 0;
uint32_t nClosedArgs = src->numClosedArgs();
uint32_t nClosedVars = src->numClosedVars();
JS_ASSERT(!JSScript::isValidOffset(src->globalsOffset));
JS_ASSERT(!src->hasGlobals());
uint32_t nglobals = 0;
/* Script data */
@ -1883,13 +1854,7 @@ js::CloneScript(JSContext *cx, JSScript *src)
if (src->analyzedArgsUsage())
dst->setNeedsArgsObj(src->needsArgsObj());
}
dst->constsOffset = src->constsOffset;
dst->objectsOffset = src->objectsOffset;
dst->regexpsOffset = src->regexpsOffset;
dst->trynotesOffset = src->trynotesOffset;
dst->globalsOffset = src->globalsOffset;
dst->closedArgsOffset = src->closedArgsOffset;
dst->closedVarsOffset = src->closedVarsOffset;
dst->cloneHasArray(src);
dst->noScriptRval = src->noScriptRval;
dst->savedCallerFun = src->savedCallerFun;
dst->strictModeCode = src->strictModeCode;

View File

@ -463,10 +463,6 @@ struct JSScript : public js::gc::Cell
private:
js::HeapPtrFunction function_;
size_t useCount; /* Number of times the script has been called
* or has had backedges taken. Reset if the
* script's JIT code is forcibly discarded. */
// 32-bit fields.
public:
@ -479,6 +475,11 @@ struct JSScript : public js::gc::Cell
uint32_t natoms; /* length of atoms array */
private:
uint32_t useCount; /* Number of times the script has been called
* or has had backedges taken. Reset if the
* script's JIT code is forcibly discarded. */
#ifdef DEBUG
// Unique identifier within the compartment for this script, used for
// printing analysis information.
@ -487,11 +488,6 @@ struct JSScript : public js::gc::Cell
uint32_t idpad;
#endif
#if JS_BITS_PER_WORD == 32
private:
uint32_t pad32;
#endif
// 16-bit fields.
private:
@ -513,18 +509,25 @@ struct JSScript : public js::gc::Cell
// 8-bit fields.
public:
// Offsets to various array structures from the end of this script, or
// JSScript::INVALID_OFFSET if the array has length 0.
uint8_t constsOffset; /* offset to the array of constants */
uint8_t objectsOffset; /* offset to the array of nested function,
block, scope, xml and one-time regexps
objects */
uint8_t regexpsOffset; /* offset to the array of to-be-cloned
regexps */
uint8_t trynotesOffset; /* offset to the array of try notes */
uint8_t globalsOffset; /* offset to the array of global slots */
uint8_t closedArgsOffset; /* offset to the array of closed args */
uint8_t closedVarsOffset; /* offset to the array of closed vars */
// The kinds of the optional arrays.
enum ArrayKind {
CONSTS,
OBJECTS,
REGEXPS,
TRYNOTES,
GLOBALS,
CLOSED_ARGS,
CLOSED_VARS,
LIMIT
};
typedef uint8_t ArrayBitsT;
private:
// The bits in this field indicate the presence/non-presence of several
// optional arrays in |data|. See the comments above NewScript() for
// details.
ArrayBitsT hasArrayBits;
// 1-bit fields.
@ -701,9 +704,9 @@ struct JSScript : public js::gc::Cell
inline void **nativeMap(bool constructing);
inline void *nativeCodeForPC(bool constructing, jsbytecode *pc);
size_t getUseCount() const { return useCount; }
size_t incUseCount() { return ++useCount; }
size_t *addressOfUseCount() { return &useCount; }
uint32_t getUseCount() const { return useCount; }
uint32_t incUseCount() { return ++useCount; }
uint32_t *addressOfUseCount() { return &useCount; }
void resetUseCount() { useCount = 0; }
/*
@ -742,50 +745,61 @@ struct JSScript : public js::gc::Cell
/* Script notes are allocated right after the code. */
jssrcnote *notes() { return (jssrcnote *)(code + length); }
static const uint8_t INVALID_OFFSET = 0xFF;
static bool isValidOffset(uint8_t offset) { return offset != INVALID_OFFSET; }
bool hasArray(ArrayKind kind) { return (hasArrayBits & (1 << kind)); }
void setHasArray(ArrayKind kind) { hasArrayBits |= (1 << kind); }
void cloneHasArray(JSScript *script) { hasArrayBits = script->hasArrayBits; }
bool hasConsts() { return isValidOffset(constsOffset); }
bool hasObjects() { return isValidOffset(objectsOffset); }
bool hasRegexps() { return isValidOffset(regexpsOffset); }
bool hasTrynotes() { return isValidOffset(trynotesOffset); }
bool hasGlobals() { return isValidOffset(globalsOffset); }
bool hasClosedArgs() { return isValidOffset(closedArgsOffset); }
bool hasClosedVars() { return isValidOffset(closedVarsOffset); }
bool hasConsts() { return hasArray(CONSTS); }
bool hasObjects() { return hasArray(OBJECTS); }
bool hasRegexps() { return hasArray(REGEXPS); }
bool hasTrynotes() { return hasArray(TRYNOTES); }
bool hasGlobals() { return hasArray(GLOBALS); }
bool hasClosedArgs() { return hasArray(CLOSED_ARGS); }
bool hasClosedVars() { return hasArray(CLOSED_VARS); }
#define OFF(fooOff, hasFoo, t) (fooOff() + (hasFoo() ? sizeof(t) : 0))
size_t constsOffset() { return 0; }
size_t objectsOffset() { return OFF(constsOffset, hasConsts, js::ConstArray); }
size_t regexpsOffset() { return OFF(objectsOffset, hasObjects, js::ObjectArray); }
size_t trynotesOffset() { return OFF(regexpsOffset, hasRegexps, js::ObjectArray); }
size_t globalsOffset() { return OFF(trynotesOffset, hasTrynotes, js::TryNoteArray); }
size_t closedArgsOffset() { return OFF(globalsOffset, hasGlobals, js::GlobalSlotArray); }
size_t closedVarsOffset() { return OFF(closedArgsOffset, hasClosedArgs, js::ClosedSlotArray); }
js::ConstArray *consts() {
JS_ASSERT(hasConsts());
return reinterpret_cast<js::ConstArray *>(data + constsOffset);
return reinterpret_cast<js::ConstArray *>(data + constsOffset());
}
js::ObjectArray *objects() {
JS_ASSERT(hasObjects());
return reinterpret_cast<js::ObjectArray *>(data + objectsOffset);
return reinterpret_cast<js::ObjectArray *>(data + objectsOffset());
}
js::ObjectArray *regexps() {
JS_ASSERT(hasRegexps());
return reinterpret_cast<js::ObjectArray *>(data + regexpsOffset);
return reinterpret_cast<js::ObjectArray *>(data + regexpsOffset());
}
js::TryNoteArray *trynotes() {
JS_ASSERT(hasTrynotes());
return reinterpret_cast<js::TryNoteArray *>(data + trynotesOffset);
return reinterpret_cast<js::TryNoteArray *>(data + trynotesOffset());
}
js::GlobalSlotArray *globals() {
JS_ASSERT(hasGlobals());
return reinterpret_cast<js::GlobalSlotArray *>(data + globalsOffset);
return reinterpret_cast<js::GlobalSlotArray *>(data + globalsOffset());
}
js::ClosedSlotArray *closedArgs() {
JS_ASSERT(hasClosedArgs());
return reinterpret_cast<js::ClosedSlotArray *>(data + closedArgsOffset);
return reinterpret_cast<js::ClosedSlotArray *>(data + closedArgsOffset());
}
js::ClosedSlotArray *closedVars() {
JS_ASSERT(hasClosedVars());
return reinterpret_cast<js::ClosedSlotArray *>(data + closedVarsOffset);
return reinterpret_cast<js::ClosedSlotArray *>(data + closedVarsOffset());
}
uint32_t numClosedArgs() {
@ -924,6 +938,8 @@ struct JSScript : public js::gc::Cell
void markChildren(JSTracer *trc);
};
JS_STATIC_ASSERT(sizeof(JSScript::ArrayBitsT) * 8 >= JSScript::LIMIT);
/* If this fails, add/remove padding within JSScript. */
JS_STATIC_ASSERT(sizeof(JSScript) % js::gc::Cell::CellSize == 0);

View File

@ -477,7 +477,7 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
if (obj->isString() &&
ClassMethodIsNative(cx, obj,
&StringClass,
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom)),
RootedVarId(cx, NameToId(cx->runtime->atomState.toStringAtom)),
js_str_toString))
{
JSString *str = obj->asString().unbox();
@ -1834,7 +1834,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
}
Value v;
if (HasDataProperty(cx, base, atom, &v) && v.isString()) {
if (HasDataProperty(cx, base, AtomToId(atom), &v) && v.isString()) {
rdata.repstr = v.toString()->ensureLinear(cx);
if (!rdata.repstr)
return false;
@ -3104,7 +3104,7 @@ StringObject::assignInitialShape(JSContext *cx)
{
JS_ASSERT(nativeEmpty());
return addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
return addDataProperty(cx, NameToId(cx->runtime->atomState.lengthAtom),
LENGTH_SLOT, JSPROP_PERMANENT | JSPROP_READONLY);
}
@ -3121,7 +3121,7 @@ js_InitStringClass(JSContext *cx, JSObject *obj)
/* Now create the String function. */
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, js_String, CLASS_ATOM(cx, String), 1);
ctor = global->createConstructor(cx, js_String, CLASS_NAME(cx, String), 1);
if (!ctor)
return NULL;
@ -3335,7 +3335,7 @@ js_ValueToSource(JSContext *cx, const Value &v)
Value rval = NullValue();
Value fval;
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
jsid id = NameToId(cx->runtime->atomState.toSourceAtom);
if (!js_GetMethod(cx, RootedVarObject(cx, &v.toObject()), id, 0, &fval))
return NULL;
if (js_IsCallable(fval)) {

View File

@ -389,7 +389,7 @@ JSBool
ArrayBufferObject::obj_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
JSObject **objp, JSProperty **propp)
{
return obj_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
return obj_lookupGeneric(cx, obj, NameToId(name), objp, propp);
}
JSBool
@ -454,7 +454,7 @@ ArrayBufferObject::obj_defineProperty(JSContext *cx, JSObject *obj,
PropertyName *name, const Value *v,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
return obj_defineGeneric(cx, obj, ATOM_TO_JSID(name), v, getter, setter, attrs);
return obj_defineGeneric(cx, obj, NameToId(name), v, getter, setter, attrs);
}
JSBool
@ -520,7 +520,7 @@ ArrayBufferObject::obj_getProperty(JSContext *cx, JSObject *obj_,
RootedVarObject delegate(cx, DelegateObject(cx, obj));
if (!delegate)
return false;
return js_GetProperty(cx, delegate, receiver, ATOM_TO_JSID(name), vp);
return js_GetProperty(cx, delegate, receiver, NameToId(name), vp);
}
JSBool
@ -616,7 +616,7 @@ JSBool
ArrayBufferObject::obj_setProperty(JSContext *cx, JSObject *obj,
PropertyName *name, Value *vp, JSBool strict)
{
return obj_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
return obj_setGeneric(cx, obj, NameToId(name), vp, strict);
}
JSBool
@ -661,7 +661,7 @@ JSBool
ArrayBufferObject::obj_getPropertyAttributes(JSContext *cx, JSObject *obj,
PropertyName *name, unsigned *attrsp)
{
return obj_getGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
return obj_getGenericAttributes(cx, obj, NameToId(name), attrsp);
}
JSBool
@ -706,7 +706,7 @@ JSBool
ArrayBufferObject::obj_setPropertyAttributes(JSContext *cx, JSObject *obj,
PropertyName *name, unsigned *attrsp)
{
return obj_setGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
return obj_setGenericAttributes(cx, obj, NameToId(name), attrsp);
}
JSBool
@ -907,7 +907,7 @@ JSBool
TypedArray::obj_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
JSObject **objp, JSProperty **propp)
{
return obj_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
return obj_lookupGeneric(cx, obj, NameToId(name), objp, propp);
}
JSBool
@ -1289,7 +1289,7 @@ class TypedArrayTemplate
static JSBool
obj_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
{
return obj_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
return obj_setGeneric(cx, obj, NameToId(name), vp, strict);
}
static JSBool
@ -1332,7 +1332,7 @@ class TypedArrayTemplate
obj_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *v,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
return obj_defineGeneric(cx, obj, ATOM_TO_JSID(name), v, getter, setter, attrs);
return obj_defineGeneric(cx, obj, NameToId(name), v, getter, setter, attrs);
}
static JSBool
@ -1411,7 +1411,7 @@ class TypedArrayTemplate
case JSENUMERATE_NEXT:
if (statep->isTrue()) {
*idp = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
*idp = NameToId(cx->runtime->atomState.lengthAtom);
statep->setInt32(0);
} else {
uint32_t index = statep->toInt32();
@ -3054,7 +3054,7 @@ InitArrayBufferClass(JSContext *cx, Handle<GlobalObject*> global)
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, ArrayBufferObject::class_constructor,
CLASS_ATOM(cx, ArrayBuffer), 1);
CLASS_NAME(cx, ArrayBuffer), 1);
if (!ctor)
return NULL;
@ -3141,7 +3141,7 @@ DataViewObject::initClass(JSContext *cx, GlobalObject *global)
JSFunction *ctor =
global->createConstructor(cx, DataViewObject::class_constructor,
CLASS_ATOM(cx, DataView), 3);
CLASS_NAME(cx, DataView), 3);
if (!ctor)
return NULL;

View File

@ -86,7 +86,6 @@ bool
WatchpointMap::watch(JSContext *cx, HandleObject obj, HandleId id,
JSWatchPointHandler handler, HandleObject closure)
{
JS_ASSERT(id.value() == js_CheckForStringIndex(id));
JS_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id));
if (!obj->setWatched(cx))
@ -107,7 +106,6 @@ void
WatchpointMap::unwatch(JSObject *obj, jsid id,
JSWatchPointHandler *handlerp, JSObject **closurep)
{
JS_ASSERT(id == js_CheckForStringIndex(id));
if (Map::Ptr p = map.lookup(WatchKey(obj, id))) {
if (handlerp)
*handlerp = p->value.handler;
@ -136,7 +134,6 @@ WatchpointMap::clear()
bool
WatchpointMap::triggerWatchpoint(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
{
JS_ASSERT(id.value() == js_CheckForStringIndex(id));
Map::Ptr p = map.lookup(WatchKey(obj, id));
if (!p || p->value.held)
return true;

View File

@ -400,7 +400,7 @@ js_InitWeakMapClass(JSContext *cx, JSObject *obj)
RootedVarFunction ctor(cx);
ctor = global->createConstructor(cx, WeakMap_construct,
CLASS_ATOM(cx, WeakMap), 0);
CLASS_NAME(cx, WeakMap), 0);
if (!ctor)
return NULL;

View File

@ -714,7 +714,6 @@ Reify(JSContext *cx, JSCompartment *origin, Value *vp)
jsid id;
if (!ValueToId(cx, StringValue(ni->begin()[i]), &id))
return false;
id = js_CheckForStringIndex(id);
keys.infallibleAppend(id);
if (!origin->wrapId(cx, &keys[i]))
return false;

View File

@ -2894,7 +2894,7 @@ js_GetLocalNameFromFunctionQName(JSObject *obj, jsid *funidp, JSContext *cx)
return false;
JSAtom *name;
if (GetLocalNameFromFunctionQName(obj, &name, cx)) {
*funidp = ATOM_TO_JSID(name);
*funidp = AtomToId(name);
return true;
}
return false;
@ -2947,7 +2947,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
* If the idea is to reject uint32_t property names, then the check needs to
* be stricter, to exclude hexadecimal and floating point literals.
*/
if (js_IdIsIndex(ATOM_TO_JSID(atomizedName), &index))
if (js_IdIsIndex(AtomToId(atomizedName), &index))
goto bad;
if (*atomizedName->chars() == '@') {
@ -2967,7 +2967,7 @@ construct:
out:
JSAtom *localName;
*funidp = GetLocalNameFromFunctionQName(obj, &localName, cx)
? ATOM_TO_JSID(localName)
? AtomToId(localName)
: JSID_VOID;
return obj;
@ -4214,7 +4214,7 @@ PutProperty(JSContext *cx, JSObject *obj_, jsid id_, JSBool strict, jsval *vp)
kidobj = js_GetXMLObject(cx, kid);
if (!kidobj)
goto bad;
id = ATOM_TO_JSID(cx->runtime->atomState.starAtom);
id = NameToId(cx->runtime->atomState.starAtom);
ok = PutProperty(cx, kidobj, id, strict, vp);
if (!ok)
goto out;
@ -4788,7 +4788,7 @@ static JSBool
xml_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
JSProperty **propp)
{
return xml_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
return xml_lookupGeneric(cx, obj, NameToId(name), objp, propp);
}
static JSBool
@ -4842,7 +4842,7 @@ static JSBool
xml_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *v,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
return xml_defineGeneric(cx, obj, ATOM_TO_JSID(name), v, getter, setter, attrs);
return xml_defineGeneric(cx, obj, NameToId(name), v, getter, setter, attrs);
}
static JSBool
@ -4876,7 +4876,7 @@ xml_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value
static JSBool
xml_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
{
return xml_getGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
return xml_getGeneric(cx, obj, receiver, NameToId(name), vp);
}
static JSBool
@ -4903,7 +4903,7 @@ xml_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
static JSBool
xml_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
{
return xml_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
return xml_setGeneric(cx, obj, NameToId(name), vp, strict);
}
static JSBool
@ -4935,7 +4935,7 @@ xml_getGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp
static JSBool
xml_getPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
{
return xml_getGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
return xml_getGenericAttributes(cx, obj, NameToId(name), attrsp);
}
static JSBool
@ -4971,7 +4971,7 @@ xml_setGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp
static JSBool
xml_setPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
{
return xml_setGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
return xml_setGenericAttributes(cx, obj, NameToId(name), attrsp);
}
static JSBool
@ -5035,7 +5035,7 @@ xml_deleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool str
static JSBool
xml_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
{
return xml_deleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
return xml_deleteGeneric(cx, obj, NameToId(name), rval, strict);
}
static JSBool
@ -5595,13 +5595,13 @@ ValueToId(JSContext *cx, jsval v, AutoIdRooter *idr)
int32_t i = JSVAL_TO_INT(v);
if (INT_FITS_IN_JSID(i))
*idr->addr() = INT_TO_JSID(i);
else if (!js_ValueToStringId(cx, v, idr->addr()))
else if (!ValueToId(cx, v, idr->addr()))
return JS_FALSE;
} else if (JSVAL_IS_STRING(v)) {
JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v));
if (!atom)
return JS_FALSE;
*idr->addr() = ATOM_TO_JSID(atom);
*idr->addr() = AtomToId(atom);
} else if (!JSVAL_IS_PRIMITIVE(v)) {
*idr->addr() = OBJECT_TO_JSID(JSVAL_TO_OBJECT(v));
} else {
@ -5727,7 +5727,7 @@ xml_children(JSContext *cx, unsigned argc, jsval *vp)
JSObject *obj = ToObject(cx, &vp[1]);
if (!obj)
return false;
jsid name = ATOM_TO_JSID(cx->runtime->atomState.starAtom);
jsid name = NameToId(cx->runtime->atomState.starAtom);
return GetProperty(cx, obj, name, vp);
}
@ -6682,7 +6682,7 @@ xml_setChildren(JSContext *cx, unsigned argc, jsval *vp)
return JS_FALSE;
*vp = argc != 0 ? vp[2] : JSVAL_VOID; /* local root */
if (!PutProperty(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.starAtom), false, vp))
if (!PutProperty(cx, obj, NameToId(cx->runtime->atomState.starAtom), false, vp))
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(obj);
@ -7406,7 +7406,7 @@ js_InitNamespaceClass(JSContext *cx, JSObject *obj)
namespaceProto->setNameURI(empty);
const unsigned NAMESPACE_CTOR_LENGTH = 2;
JSFunction *ctor = global->createConstructor(cx, Namespace, CLASS_ATOM(cx, Namespace),
JSFunction *ctor = global->createConstructor(cx, Namespace, CLASS_NAME(cx, Namespace),
NAMESPACE_CTOR_LENGTH);
if (!ctor)
return NULL;
@ -7439,7 +7439,7 @@ js_InitQNameClass(JSContext *cx, JSObject *obj)
return NULL;
const unsigned QNAME_CTOR_LENGTH = 2;
JSFunction *ctor = global->createConstructor(cx, QName, CLASS_ATOM(cx, QName),
JSFunction *ctor = global->createConstructor(cx, QName, CLASS_NAME(cx, QName),
QNAME_CTOR_LENGTH);
if (!ctor)
return NULL;
@ -7480,7 +7480,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
}
const unsigned XML_CTOR_LENGTH = 1;
JSFunction *ctor = global->createConstructor(cx, XML, CLASS_ATOM(cx, XML), XML_CTOR_LENGTH);
JSFunction *ctor = global->createConstructor(cx, XML, CLASS_NAME(cx, XML), XML_CTOR_LENGTH);
if (!ctor)
return NULL;
@ -7747,7 +7747,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
JSAtom *name;
funid = GetLocalNameFromFunctionQName(qn, &name, cx)
? ATOM_TO_JSID(name)
? AtomToId(name)
: JSID_VOID;
obj = cx->stack.currentScriptedScopeChain();

View File

@ -3890,7 +3890,7 @@ mjit::Compiler::recompileCheckHelper()
return;
}
size_t *addr = script->addressOfUseCount();
uint32_t *addr = script->addressOfUseCount();
masm.add32(Imm32(1), AbsoluteAddress(addr));
#if defined(JS_CPU_X86) || defined(JS_CPU_ARM)
Jump jump = masm.branch32(Assembler::GreaterThanOrEqual, AbsoluteAddress(addr),
@ -4840,7 +4840,7 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
JSObject *singleton =
(*PC == JSOP_GETPROP || *PC == JSOP_CALLPROP) ? pushedSingleton(0) : NULL;
if (singleton && singleton->isFunction() && !hasTypeBarriers(PC) &&
testSingletonPropertyTypes(top, ATOM_TO_JSID(name), &testObject)) {
testSingletonPropertyTypes(top, NameToId(name), &testObject)) {
if (testObject) {
Jump notObject = frame.testObject(Assembler::NotEqual, top);
stubcc.linkExit(notObject, Uses(1));
@ -4865,7 +4865,7 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
/* Check if this is a property access we can make a loop invariant entry for. */
if (loop && loop->generatingInvariants() && !hasTypeBarriers(PC)) {
CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
if (FrameEntry *fe = loop->invariantProperty(topv, ATOM_TO_JSID(name))) {
if (FrameEntry *fe = loop->invariantProperty(topv, NameToId(name))) {
if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
frame.learnType(fe, knownType, false);
frame.pop();
@ -4889,7 +4889,7 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
* in a particular inline slot. Get the property directly in this case,
* without using an IC.
*/
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
types::TypeSet *types = frame.extra(top).types;
if (types && !types->unknownObject() &&
types->getObjectCount() == 1 &&
@ -5170,7 +5170,7 @@ mjit::Compiler::jsop_getprop_dispatch(PropertyName *name)
if (top->isNotType(JSVAL_TYPE_OBJECT))
return false;
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
if (id != types::MakeTypeId(cx, id))
return false;
@ -5324,7 +5324,7 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
*/
if (cx->typeInferenceEnabled() && js_CodeSpec[*PC].format & JOF_NAME) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
analysis->resolveNameAccess(cx, NameToId(name), true);
if (access.nesting) {
/* Use a SavedReg so it isn't clobbered by the stub call. */
RegisterID nameReg = frame.allocReg(Registers::SavedRegs).reg();
@ -5358,7 +5358,7 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
* Set the property directly if we are accessing a known object which
* always has the property in a particular inline slot.
*/
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
types::TypeSet *types = frame.extra(lhs).types;
if (JSOp(*PC) == JSOP_SETPROP && id == types::MakeTypeId(cx, id) &&
types && !types->unknownObject() &&
@ -5547,7 +5547,7 @@ mjit::Compiler::jsop_name(PropertyName *name, JSValueType type)
*/
if (cx->typeInferenceEnabled()) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
analysis->resolveNameAccess(cx, NameToId(name), true);
if (access.nesting) {
Address address = frame.loadNameAddress(access);
JSValueType type = knownPushedType(0);
@ -5620,7 +5620,7 @@ mjit::Compiler::jsop_xname(PropertyName *name)
*/
if (cx->typeInferenceEnabled()) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
analysis->resolveNameAccess(cx, NameToId(name), true);
if (access.nesting) {
frame.pop();
Address address = frame.loadNameAddress(access);
@ -5700,7 +5700,7 @@ mjit::Compiler::jsop_bindname(PropertyName *name)
*/
if (cx->typeInferenceEnabled()) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
analysis->resolveNameAccess(cx, NameToId(name), true);
if (access.nesting) {
RegisterID reg = frame.allocReg();
JSObject **pobj = &access.nesting->activeCall;
@ -6175,12 +6175,12 @@ mjit::Compiler::jsop_getgname(uint32_t index)
/* Optimize singletons like Math for JSOP_CALLPROP. */
JSObject *obj = pushedSingleton(0);
if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, ATOM_TO_JSID(name))) {
if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, NameToId(name))) {
frame.push(ObjectValue(*obj));
return;
}
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
JSValueType type = knownPushedType(0);
if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::MakeTypeId(cx, id) &&
!globalObj->getType(cx)->unknownProperties()) {
@ -6193,7 +6193,7 @@ mjit::Compiler::jsop_getgname(uint32_t index)
* then bake its address into the jitcode and guard against future
* reallocation of the global object's slots.
*/
const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
const js::Shape *shape = globalObj->nativeLookup(cx, NameToId(name));
if (shape && shape->hasDefaultGetter() && shape->hasSlot()) {
HeapSlot *value = &globalObj->getSlotRef(shape->slot());
if (!value->isUndefined() &&
@ -6304,7 +6304,7 @@ mjit::Compiler::jsop_setgname(PropertyName *name, bool popGuaranteed)
return;
}
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::MakeTypeId(cx, id) &&
!globalObj->getType(cx)->unknownProperties()) {
/*
@ -6316,7 +6316,7 @@ mjit::Compiler::jsop_setgname(PropertyName *name, bool popGuaranteed)
types::TypeSet *types = globalObj->getType(cx)->getProperty(cx, id, false);
if (!types)
return;
const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
const js::Shape *shape = globalObj->nativeLookup(cx, NameToId(name));
if (shape && shape->hasDefaultSetter() &&
shape->writable() && shape->hasSlot() &&
!types->isOwnProperty(cx, globalObj->getType(cx), true)) {
@ -7040,7 +7040,7 @@ mjit::Compiler::constructThis()
break;
}
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
jsid id = NameToId(cx->runtime->atomState.classPrototypeAtom);
types::TypeSet *protoTypes = fun->getType(cx)->getProperty(cx, id, false);
JSObject *proto = protoTypes->getSingleton(cx, true);

View File

@ -2664,13 +2664,13 @@ mjit::Compiler::jsop_initprop()
{
FrameEntry *obj = frame.peek(-2);
FrameEntry *fe = frame.peek(-1);
JSAtom *atom = script->getAtom(GET_UINT32_INDEX(PC));
PropertyName *name = script->getName(GET_UINT32_INDEX(PC));
JSObject *baseobj = frame.extra(obj).initObject;
if (!baseobj || monitored(PC)) {
prepareStubCall(Uses(2));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(stubs::InitProp, REJOIN_FALLTHROUGH);
return;
}
@ -2680,7 +2680,7 @@ mjit::Compiler::jsop_initprop()
#ifdef DEBUG
bool res =
#endif
LookupPropertyWithFlags(cx, baseobj, ATOM_TO_JSID(atom),
LookupPropertyWithFlags(cx, baseobj, NameToId(name),
JSRESOLVE_QUALIFIED, &holder, &prop);
JS_ASSERT(res && prop && holder == baseobj);

View File

@ -917,7 +917,7 @@ LoopState::invariantProperty(const CrossSSAValue &obj, jsid id)
if (skipAnalysis)
return NULL;
if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
if (id == NameToId(cx->runtime->atomState.lengthAtom))
return NULL;
uint32_t objSlot;
@ -1870,8 +1870,8 @@ LoopState::analyzeLoopBody(unsigned frame)
}
case JSOP_SETPROP: {
JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc));
jsid id = MakeTypeId(cx, ATOM_TO_JSID(atom));
PropertyName *name = script->getName(GET_UINT32_INDEX(pc));
jsid id = MakeTypeId(cx, NameToId(name));
TypeSet *objTypes = analysis->poppedTypes(pc, 1);
if (objTypes->unknownObject()) {
@ -2184,8 +2184,8 @@ LoopState::getEntryValue(const CrossSSAValue &iv, uint32_t *pslot, int32_t *pcon
}
case JSOP_GETPROP: {
JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc));
jsid id = ATOM_TO_JSID(atom);
PropertyName *name = script->getName(GET_UINT32_INDEX(pc));
jsid id = NameToId(name);
CrossSSAValue objcv(cv.frame, analysis->poppedValue(v.pushedOffset(), 0));
FrameEntry *tmp = invariantProperty(objcv, id);
if (!tmp)

View File

@ -91,7 +91,7 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
RecompilationMonitor monitor(f.cx);
const Shape *shape = obj.nativeLookup(f.cx, js_CheckForStringIndex(ATOM_TO_JSID(name)));
const Shape *shape = obj.nativeLookup(f.cx, NameToId(name));
if (monitor.recompiled()) {
stubs::Name(f);
@ -196,7 +196,7 @@ ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
RecompilationMonitor monitor(f.cx);
const Shape *shape = obj.nativeLookup(f.cx, ATOM_TO_JSID(name));
const Shape *shape = obj.nativeLookup(f.cx, NameToId(name));
if (!monitor.recompiled()) {
LookupStatus status = UpdateSetGlobalName(f, ic, &obj, shape);

View File

@ -470,7 +470,7 @@ class SetPropCompiler : public PICStubCompiler
JS_ASSERT(pic.typeMonitored);
RecompilationMonitor monitor(cx);
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
if (!obj->getType(cx)->unknownProperties()) {
types::AutoEnterTypeInference enter(cx);
@ -1053,7 +1053,7 @@ class GetPropCompiler : public PICStubCompiler
return Lookup_Cacheable;
}
void generateGetterStub(Assembler &masm, const Shape *shape,
void generateGetterStub(Assembler &masm, const Shape *shape, jsid userid,
Label start, Vector<Jump, 8> &shapeMismatches)
{
/*
@ -1115,7 +1115,7 @@ class GetPropCompiler : public PICStubCompiler
masm.restoreStackBase();
masm.setupABICall(Registers::NormalCall, 4);
masm.storeArg(3, vpReg);
masm.storeArg(2, ImmPtr((void *) JSID_BITS(shape->getUserId())));
masm.storeArg(2, ImmPtr((void *) JSID_BITS(userid)));
masm.storeArg(1, holdObjReg);
masm.storeArg(0, cxReg);
@ -1201,7 +1201,11 @@ class GetPropCompiler : public PICStubCompiler
}
if (!shape->hasDefaultGetter()) {
generateGetterStub(masm, shape, start, shapeMismatches);
jsid userid;
if (!shape->getUserId(cx, &userid))
return error();
generateGetterStub(masm, shape, userid, start, shapeMismatches);
if (setStubShapeOffset)
pic.getPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
return Lookup_Cacheable;
@ -2438,7 +2442,7 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
if (idval.isInt32() && INT_FITS_IN_JSID(idval.toInt32())) {
id = INT_TO_JSID(idval.toInt32());
} else {
if (!js_InternNonIntElementId(cx, obj, idval, &id))
if (!InternNonIntElementId(cx, obj, idval, &id))
THROW();
}

View File

@ -1087,7 +1087,7 @@ InitPropOrMethod(VMFrame &f, PropertyName *name, JSOp op)
JS_ASSERT(obj->isNative());
/* Get the immediate property name into id. */
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
? !js_SetPropertyHelper(cx, obj, id, 0, &rval, false)

View File

@ -618,6 +618,7 @@ static const struct JSOption {
{"typeinfer", JSOPTION_TYPE_INFERENCE},
{"werror", JSOPTION_WERROR},
{"xml", JSOPTION_XML},
{"strict_mode", JSOPTION_STRICT_MODE},
};
static uint32_t

View File

@ -224,7 +224,8 @@ function optionsInit() {
xml: true,
relimit: true,
methodjit: true,
methodjit_always: true
methodjit_always: true,
strict_mode: true
};
// record initial values to support resetting

View File

@ -0,0 +1,23 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (typeof options == "function") {
var opts = options();
if (!/\bstrict_mode\b/.test(opts))
options("strict_mode");
}
var ok = false;
try {
eval('foo = true;');
} catch (e) {
if (/^ReferenceError:/.test(e.toString()))
ok = true;
}
if (ok)
reportCompare(0, 0, "ok");
else
reportCompare(true, false, "this should have thrown a ReferenceError");

View File

@ -323,7 +323,6 @@ NormalArgumentsObject::optimizedGetElem(JSContext *cx, StackFrame *fp, const Val
jsid id;
if (!ValueToId(cx, elem, &id))
return false;
id = js_CheckForStringIndex(id);
if (JSID_IS_INT(id)) {
int32_t i = JSID_TO_INT(id);
@ -333,12 +332,12 @@ NormalArgumentsObject::optimizedGetElem(JSContext *cx, StackFrame *fp, const Val
}
}
if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {
if (id == NameToId(cx->runtime->atomState.lengthAtom)) {
*vp = Int32Value(fp->numActualArgs());
return true;
}
if (id == ATOM_TO_JSID(cx->runtime->atomState.calleeAtom)) {
if (id == NameToId(cx->runtime->atomState.calleeAtom)) {
*vp = ObjectValue(fp->callee());
return true;
}
@ -362,9 +361,9 @@ args_enumerate(JSContext *cx, JSObject *obj)
int argc = int(argsobj->initialLength());
for (int i = -2; i != argc; i++) {
jsid id = (i == -2)
? ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)
? NameToId(cx->runtime->atomState.lengthAtom)
: (i == -1)
? ATOM_TO_JSID(cx->runtime->atomState.calleeAtom)
? NameToId(cx->runtime->atomState.calleeAtom)
: INT_TO_JSID(i);
JSObject *pobj;
@ -481,15 +480,15 @@ strictargs_enumerate(JSContext *cx, JSObject *obj)
JSProperty *prop;
// length
if (!js_LookupProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), &pobj, &prop))
if (!js_LookupProperty(cx, argsobj, NameToId(cx->runtime->atomState.lengthAtom), &pobj, &prop))
return false;
// callee
if (!js_LookupProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.calleeAtom), &pobj, &prop))
if (!js_LookupProperty(cx, argsobj, NameToId(cx->runtime->atomState.calleeAtom), &pobj, &prop))
return false;
// caller
if (!js_LookupProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.callerAtom), &pobj, &prop))
if (!js_LookupProperty(cx, argsobj, NameToId(cx->runtime->atomState.callerAtom), &pobj, &prop))
return false;
for (uint32_t i = 0, argc = argsobj->initialLength(); i < argc; i++) {

View File

@ -791,11 +791,11 @@ Debugger::newCompletionValue(JSContext *cx, JSTrapStatus status, Value value, Va
switch (status) {
case JSTRAP_RETURN:
key = ATOM_TO_JSID(cx->runtime->atomState.returnAtom);
key = NameToId(cx->runtime->atomState.returnAtom);
break;
case JSTRAP_THROW:
key = ATOM_TO_JSID(cx->runtime->atomState.throwAtom);
key = NameToId(cx->runtime->atomState.throwAtom);
break;
case JSTRAP_ERROR:
@ -852,8 +852,8 @@ Debugger::parseResumptionValue(AutoCompartment &ac, bool ok, const Value &rv, Va
JSContext *cx = ac.context;
JSObject *obj;
const Shape *shape;
jsid returnId = ATOM_TO_JSID(cx->runtime->atomState.returnAtom);
jsid throwId = ATOM_TO_JSID(cx->runtime->atomState.throwAtom);
jsid returnId = NameToId(cx->runtime->atomState.returnAtom);
jsid throwId = NameToId(cx->runtime->atomState.throwAtom);
bool okResumption = rv.isObject();
if (okResumption) {
obj = &rv.toObject();
@ -890,7 +890,7 @@ CallMethodIfPresent(JSContext *cx, HandleObject obj, const char *name, int argc,
JSAtom *atom = js_Atomize(cx, name, strlen(name));
Value fval;
return atom &&
js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, &fval) &&
js_GetMethod(cx, obj, AtomToId(atom), 0, &fval) &&
(!js_IsCallable(fval) ||
Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
}
@ -3212,7 +3212,7 @@ DebuggerFrame_getArguments(JSContext *cx, unsigned argc, Value *vp)
JS_ASSERT(fp->numActualArgs() <= 0x7fffffff);
int32_t fargc = int32_t(fp->numActualArgs());
if (!DefineNativeProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
if (!DefineNativeProperty(cx, argsobj, NameToId(cx->runtime->atomState.lengthAtom),
Int32Value(fargc), NULL, NULL,
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0))
{

View File

@ -174,7 +174,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
if (!ctor)
return NULL;
objectCtor = js_NewFunction(cx, ctor, js_Object, 1, JSFUN_CONSTRUCTOR, self,
CLASS_ATOM(cx, Object));
CLASS_NAME(cx, Object));
if (!objectCtor)
return NULL;
}
@ -193,7 +193,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
if (!ctor)
return NULL;
functionCtor = js_NewFunction(cx, ctor, Function, 1, JSFUN_CONSTRUCTOR, self,
CLASS_ATOM(cx, Function));
CLASS_NAME(cx, Function));
if (!functionCtor)
return NULL;
JS_ASSERT(ctor == functionCtor);
@ -220,17 +220,17 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
}
/* Add the global Function and Object properties now. */
jsid objectId = ATOM_TO_JSID(CLASS_ATOM(cx, Object));
jsid objectId = NameToId(CLASS_NAME(cx, Object));
if (!self->addDataProperty(cx, objectId, JSProto_Object + JSProto_LIMIT * 2, 0))
return NULL;
jsid functionId = ATOM_TO_JSID(CLASS_ATOM(cx, Function));
jsid functionId = NameToId(CLASS_NAME(cx, Function));
if (!self->addDataProperty(cx, functionId, JSProto_Function + JSProto_LIMIT * 2, 0))
return NULL;
/* Heavy lifting done, but lingering tasks remain. */
/* ES5 15.1.2.1. */
jsid id = ATOM_TO_JSID(cx->runtime->atomState.evalAtom);
jsid id = NameToId(cx->runtime->atomState.evalAtom);
JSObject *evalobj = js_DefineFunction(cx, self, id, eval, 1, JSFUN_STUB_GSOPS);
if (!evalobj)
return NULL;

View File

@ -363,26 +363,26 @@ RegExpObject::assignInitialShape(JSContext *cx)
RootedVarObject self(cx, this);
/* The lastIndex property alone is writable but non-configurable. */
if (!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lastIndexAtom),
if (!addDataProperty(cx, NameToId(cx->runtime->atomState.lastIndexAtom),
LAST_INDEX_SLOT, JSPROP_PERMANENT))
{
return NULL;
}
/* Remaining instance properties are non-writable and non-configurable. */
if (!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom),
if (!self->addDataProperty(cx, NameToId(cx->runtime->atomState.sourceAtom),
SOURCE_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.globalAtom),
!self->addDataProperty(cx, NameToId(cx->runtime->atomState.globalAtom),
GLOBAL_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.ignoreCaseAtom),
!self->addDataProperty(cx, NameToId(cx->runtime->atomState.ignoreCaseAtom),
IGNORE_CASE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.multilineAtom),
!self->addDataProperty(cx, NameToId(cx->runtime->atomState.multilineAtom),
MULTILINE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY))
{
return NULL;
}
return self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.stickyAtom),
return self->addDataProperty(cx, NameToId(cx->runtime->atomState.stickyAtom),
STICKY_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY);
}
@ -405,17 +405,17 @@ RegExpObject::init(JSContext *cx, HandleAtom source, RegExpFlag flags)
}
DebugOnly<JSAtomState *> atomState = &cx->runtime->atomState;
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->lastIndexAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->lastIndexAtom))->slot() ==
LAST_INDEX_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->sourceAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->sourceAtom))->slot() ==
SOURCE_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->globalAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->globalAtom))->slot() ==
GLOBAL_FLAG_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->ignoreCaseAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->ignoreCaseAtom))->slot() ==
IGNORE_CASE_FLAG_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->multilineAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->multilineAtom))->slot() ==
MULTILINE_FLAG_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->stickyAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->stickyAtom))->slot() ==
STICKY_FLAG_SLOT);
/*

View File

@ -231,7 +231,7 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
if (!scopeChain)
return NULL;
if (!DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName),
if (!DefineNativeProperty(cx, scopeChain, AtomToId(lambdaName),
ObjectValue(fp->callee()), NULL, NULL,
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) {
return NULL;
@ -350,7 +350,7 @@ CallObject::setVarOp(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value
bool
CallObject::containsVarOrArg(PropertyName *name, Value *vp, JSContext *cx)
{
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
const Shape *shape = nativeLookup(cx, id);
if (!shape)
return false;
@ -483,7 +483,7 @@ with_LookupGeneric(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, JSPro
static JSBool
with_LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp, JSProperty **propp)
{
return with_LookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
return with_LookupGeneric(cx, obj, NameToId(name), objp, propp);
}
static JSBool
@ -511,7 +511,7 @@ with_GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value
static JSBool
with_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
{
return with_GetGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
return with_GetGeneric(cx, obj, receiver, NameToId(name), vp);
}
static JSBool
@ -806,7 +806,7 @@ block_setProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *v
bool
ClonedBlockObject::containsVar(PropertyName *name, Value *vp, JSContext *cx)
{
jsid id = ATOM_TO_JSID(name);
jsid id = NameToId(name);
const Shape *shape = nativeLookup(cx, id);
if (!shape)
return false;
@ -885,7 +885,7 @@ Class js::BlockClass = {
static uint32_t
FindObjectIndex(JSScript *script, StaticBlockObject *maybeBlock)
{
if (!maybeBlock || !JSScript::isValidOffset(script->objectsOffset))
if (!maybeBlock || !script->hasObjects())
return NO_PARENT_INDEX;
ObjectArray *objects = script->objects();
@ -957,7 +957,7 @@ js::XDRStaticBlockObject(XDRState<mode> *xdr, JSScript *script, StaticBlockObjec
/* The empty string indicates an int id. */
jsid id = atom != cx->runtime->emptyString
? ATOM_TO_JSID(atom)
? AtomToId(atom)
: INT_TO_JSID(i);
bool redeclared;

View File

@ -372,7 +372,7 @@ JSDependentString::undepend(JSContext *cx)
}
bool
JSFlatString::isIndex(uint32_t *indexp) const
JSFlatString::isIndexSlow(uint32_t *indexp) const
{
const jschar *s = charsZ();
jschar ch = *s;

View File

@ -44,7 +44,9 @@
#include "mozilla/Attributes.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jsfriendapi.h"
#include "jsstr.h"
#include "gc/Barrier.h"
#include "gc/Heap.h"
@ -510,6 +512,8 @@ class JSFlatString : public JSLinearString
bool isFlat() const MOZ_DELETE;
JSFlatString &asFlat() const MOZ_DELETE;
bool isIndexSlow(uint32_t *indexp) const;
public:
JS_ALWAYS_INLINE
const jschar *charsZ() const {
@ -523,7 +527,10 @@ class JSFlatString : public JSLinearString
* calling isIndex returns true, js::IndexToString(cx, *indexp) will be a
* string equal to this string.)
*/
bool isIndex(uint32_t *indexp) const;
inline bool isIndex(uint32_t *indexp) const {
const jschar *s = chars();
return JS7_ISDEC(*s) && isIndexSlow(indexp);
}
/*
* Returns a property name represented by this string, or null on failure.
@ -776,6 +783,12 @@ class PropertyName : public JSAtom
JS_STATIC_ASSERT(sizeof(PropertyName) == sizeof(JSString));
static JS_ALWAYS_INLINE jsid
NameToId(PropertyName *name)
{
return NON_INTEGER_ATOM_TO_JSID(name);
}
} /* namespace js */
/* Avoid requiring vm/String-inl.h just to call getChars. */

View File

@ -71,7 +71,7 @@ StringObject::init(JSContext *cx, HandleString str)
}
}
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))->slot()
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(cx->runtime->atomState.lengthAtom))->slot()
== LENGTH_SLOT);
self->setStringThis(str);

View File

@ -360,6 +360,9 @@ interface nsIXPCComponents_Utils : nsISupports
[implicit_jscontext]
attribute boolean methodjit_always;
[implicit_jscontext]
attribute boolean strict_mode;
[implicit_jscontext]
void setGCZeal(in long zeal);
};

View File

@ -717,6 +717,7 @@ static const struct JSOption {
{"strict", JSOPTION_STRICT},
{"werror", JSOPTION_WERROR},
{"xml", JSOPTION_XML},
{"strict_mode", JSOPTION_STRICT_MODE},
};
static uint32_t

View File

@ -4092,6 +4092,7 @@ GENERATE_JSOPTION_GETTER_SETTER(Xml, JSOPTION_XML)
GENERATE_JSOPTION_GETTER_SETTER(Relimit, JSOPTION_RELIMIT)
GENERATE_JSOPTION_GETTER_SETTER(Methodjit, JSOPTION_METHODJIT)
GENERATE_JSOPTION_GETTER_SETTER(Methodjit_always, JSOPTION_METHODJIT_ALWAYS)
GENERATE_JSOPTION_GETTER_SETTER(Strict_mode, JSOPTION_STRICT_MODE)
#undef GENERATE_JSOPTION_GETTER_SETTER

View File

@ -1197,7 +1197,7 @@ XPCJSRuntime::~XPCJSRuntime()
}
static void
GetCompartmentName(JSCompartment *c, bool getAddress, nsCString &name)
GetCompartmentName(JSCompartment *c, nsCString &name)
{
if (js::IsAtomsCompartment(c)) {
name.AssignLiteral("atoms");
@ -1205,9 +1205,6 @@ GetCompartmentName(JSCompartment *c, bool getAddress, nsCString &name)
nsJSPrincipals::get(principals)->GetScriptLocation(name);
// For system compartments we append the location, if there is one.
// And we append the address if |getAddress| is true, so that
// multiple system compartments (and there can be many) can be
// distinguished.
if (js::IsSystemCompartment(c)) {
xpc::CompartmentPrivate *compartmentPrivate =
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(c));
@ -1215,12 +1212,6 @@ GetCompartmentName(JSCompartment *c, bool getAddress, nsCString &name)
name.AppendLiteral(", ");
name.Append(compartmentPrivate->location);
}
if (getAddress) {
// ample; 64-bit address max is 18 chars
nsPrintfCString address(", 0x%llx", PRUint64(c));
name.Append(address);
}
}
// A hack: replace forward slashes with '\\' so they aren't
@ -1641,7 +1632,7 @@ class JSCompartmentsMultiReporter : public nsIMemoryMultiReporter
// silently ignore OOM errors
Paths *paths = static_cast<Paths *>(data);
nsCString path;
GetCompartmentName(c, /* getAddress = */ false, path);
GetCompartmentName(c, path);
path.Insert(js::IsSystemCompartment(c)
? NS_LITERAL_CSTRING("compartments/system/")
: NS_LITERAL_CSTRING("compartments/user/"),
@ -1698,7 +1689,7 @@ struct XPCJSRuntimeStats : public JS::RuntimeStats {
virtual void initExtraCompartmentStats(JSCompartment *c,
JS::CompartmentStats *cstats) MOZ_OVERRIDE {
nsCAutoString name;
GetCompartmentName(c, /* getAddress = */ true, name);
GetCompartmentName(c, name);
cstats->extra = strdup(name.get());
}
};

View File

@ -159,7 +159,7 @@ ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState,
AutoInfallibleTArray<nsIFrame*, 16> frames;
for (nsIFrame *f = aDescendantFrame; f != ancestorFrame;
f = f->GetParent()) {
f = f->GetParent()->GetFirstInFlow()) {
frames.AppendElement(f);
}

View File

@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
The git commit ID used was 3ef8175c72c40f02d68181d882a51d86d54eff6f.
The git commit ID used was d7368445b56327015cad554cb62a4be31051ed4e.

View File

@ -0,0 +1,381 @@
/*
* Copyright © 2011 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#undef NDEBUG
#include <assert.h>
#include <stdlib.h>
#include <pulse/pulseaudio.h>
#include "cubeb/cubeb.h"
struct cubeb {
pa_threaded_mainloop * mainloop;
pa_context * context;
};
struct cubeb_stream {
struct cubeb * context;
pa_stream * stream;
cubeb_data_callback data_callback;
cubeb_state_callback state_callback;
void * user_ptr;
pa_time_event * drain_timer;
pa_sample_spec sample_spec;
int shutdown;
};
enum cork_state {
UNCORK = 0,
CORK = 1 << 0,
NOTIFY = 1 << 1
};
static void
context_state_callback(pa_context * c, void * m)
{
if (pa_context_get_state(c) != PA_CONTEXT_TERMINATED) {
assert(PA_CONTEXT_IS_GOOD(pa_context_get_state(c)));
}
pa_threaded_mainloop_signal(m, 0);
}
static void
context_notify_callback(pa_context * c, void * m)
{
pa_threaded_mainloop_signal(m, 0);
}
static void
stream_success_callback(pa_stream * s, int success, void * m)
{
pa_threaded_mainloop_signal(m, 0);
}
static void
stream_drain_callback(pa_mainloop_api * a, pa_time_event * e, struct timeval const * tv, void * u)
{
cubeb_stream * stm = u;
/* there's no pa_rttime_free, so use this instead. */
a->time_free(stm->drain_timer);
stm->drain_timer = NULL;
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
}
static void
stream_state_callback(pa_stream * s, void * m)
{
/* XXX handle PA_STREAM_FAILED during creation */
if (pa_stream_get_state(s) == PA_STREAM_TERMINATED) {
} else {
assert(PA_STREAM_IS_GOOD(pa_stream_get_state(s)));
}
pa_threaded_mainloop_signal(m, 0);
}
static void
stream_request_callback(pa_stream * s, size_t nbytes, void * u)
{
cubeb_stream * stm;
void * buffer;
size_t size;
int r;
long got;
size_t towrite;
size_t frame_size;
stm = u;
if (stm->shutdown)
return;
frame_size = pa_frame_size(&stm->sample_spec);
assert(nbytes % frame_size == 0);
towrite = nbytes;
while (towrite) {
size = towrite;
r = pa_stream_begin_write(s, &buffer, &size);
assert(r == 0);
assert(size > 0);
assert(size % frame_size == 0);
got = stm->data_callback(stm, stm->user_ptr, buffer, size / frame_size);
if (got < 0) {
pa_stream_cancel_write(s);
stm->shutdown = 1;
return;
}
r = pa_stream_write(s, buffer, got * frame_size, NULL, 0, PA_SEEK_RELATIVE);
assert(r == 0);
if ((size_t) got < size / frame_size) {
size_t buffer_fill = pa_stream_get_buffer_attr(s)->maxlength - pa_stream_writable_size(s);
double buffer_time = (double) buffer_fill / stm->sample_spec.rate;
/* pa_stream_drain is useless, see PA bug# 866. this is a workaround. */
stm->drain_timer = pa_context_rttime_new(stm->context->context, pa_rtclock_now() + buffer_time * 1e6, stream_drain_callback, stm);
stm->shutdown = 1;
return;
}
towrite -= size;
}
assert(towrite == 0);
}
static void
state_wait(cubeb * ctx, pa_context_state_t target_state)
{
pa_threaded_mainloop_lock(ctx->mainloop);
for (;;) {
pa_context_state_t state = pa_context_get_state(ctx->context);
assert(PA_CONTEXT_IS_GOOD(state));
if (state == target_state)
break;
pa_threaded_mainloop_wait(ctx->mainloop);
}
pa_threaded_mainloop_unlock(ctx->mainloop);
}
static void
stream_state_wait(cubeb_stream * stm, pa_stream_state_t target_state)
{
pa_threaded_mainloop_lock(stm->context->mainloop);
for (;;) {
pa_stream_state_t state = pa_stream_get_state(stm->stream);
assert(PA_CONTEXT_IS_GOOD(state));
if (state == target_state)
break;
pa_threaded_mainloop_wait(stm->context->mainloop);
}
pa_threaded_mainloop_unlock(stm->context->mainloop);
}
static void
operation_wait(cubeb * ctx, pa_operation * o)
{
for (;;) {
if (pa_operation_get_state(o) != PA_OPERATION_RUNNING)
break;
pa_threaded_mainloop_wait(ctx->mainloop);
}
}
static void
stream_cork(cubeb_stream * stm, enum cork_state state)
{
pa_operation * o;
pa_threaded_mainloop_lock(stm->context->mainloop);
o = pa_stream_cork(stm->stream, state & CORK, stream_success_callback, stm->context->mainloop);
operation_wait(stm->context, o);
pa_operation_unref(o);
pa_threaded_mainloop_unlock(stm->context->mainloop);
if (state & NOTIFY) {
stm->state_callback(stm, stm->user_ptr,
state & CORK ? CUBEB_STATE_STOPPED : CUBEB_STATE_STARTED);
}
}
int
cubeb_init(cubeb ** context, char const * context_name)
{
cubeb * ctx;
*context = NULL;
ctx = calloc(1, sizeof(*ctx));
assert(ctx);
ctx->mainloop = pa_threaded_mainloop_new();
ctx->context = pa_context_new(pa_threaded_mainloop_get_api(ctx->mainloop), context_name);
pa_context_set_state_callback(ctx->context, context_state_callback, ctx->mainloop);
pa_threaded_mainloop_start(ctx->mainloop);
pa_threaded_mainloop_lock(ctx->mainloop);
pa_context_connect(ctx->context, NULL, 0, NULL);
pa_threaded_mainloop_unlock(ctx->mainloop);
state_wait(ctx, PA_CONTEXT_READY);
*context = ctx;
return CUBEB_OK;
}
void
cubeb_destroy(cubeb * ctx)
{
pa_operation * o;
if (ctx->context) {
pa_threaded_mainloop_lock(ctx->mainloop);
o = pa_context_drain(ctx->context, context_notify_callback, ctx->mainloop);
if (o) {
operation_wait(ctx, o);
pa_operation_unref(o);
}
pa_context_disconnect(ctx->context);
pa_context_unref(ctx->context);
pa_threaded_mainloop_unlock(ctx->mainloop);
}
if (ctx->mainloop) {
pa_threaded_mainloop_stop(ctx->mainloop);
pa_threaded_mainloop_free(ctx->mainloop);
}
free(ctx);
}
int
cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
cubeb_stream_params stream_params, unsigned int latency,
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
void * user_ptr)
{
pa_sample_spec ss;
cubeb_stream * stm;
pa_operation * o;
pa_buffer_attr battr;
pa_channel_map map;
assert(context);
*stream = NULL;
if (stream_params.rate < 1 || stream_params.rate > 192000 ||
stream_params.channels < 1 || stream_params.channels > 32 ||
latency < 1 || latency > 2000) {
return CUBEB_ERROR_INVALID_FORMAT;
}
switch (stream_params.format) {
case CUBEB_SAMPLE_S16LE:
ss.format = PA_SAMPLE_S16LE;
break;
case CUBEB_SAMPLE_S16BE:
ss.format = PA_SAMPLE_S16BE;
break;
case CUBEB_SAMPLE_FLOAT32LE:
ss.format = PA_SAMPLE_FLOAT32LE;
break;
case CUBEB_SAMPLE_FLOAT32BE:
ss.format = PA_SAMPLE_FLOAT32BE;
break;
default:
return CUBEB_ERROR_INVALID_FORMAT;
}
ss.rate = stream_params.rate;
ss.channels = stream_params.channels;
/* XXX check that this does the right thing for Vorbis and WaveEx */
pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_DEFAULT);
stm = calloc(1, sizeof(*stm));
assert(stm);
stm->context = context;
stm->data_callback = data_callback;
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
stm->sample_spec = ss;
battr.maxlength = -1;
battr.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &stm->sample_spec);
battr.prebuf = -1;
battr.minreq = battr.tlength / 2;
battr.fragsize = -1;
pa_threaded_mainloop_lock(stm->context->mainloop);
stm->stream = pa_stream_new(stm->context->context, stream_name, &ss, &map);
pa_stream_set_state_callback(stm->stream, stream_state_callback, stm->context->mainloop);
pa_stream_set_write_callback(stm->stream, stream_request_callback, stm);
pa_stream_connect_playback(stm->stream, NULL, &battr,
PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING |
PA_STREAM_START_CORKED,
NULL, NULL);
pa_threaded_mainloop_unlock(stm->context->mainloop);
stream_state_wait(stm, PA_STREAM_READY);
/* force a timing update now, otherwise timing info does not become valid
until some point after initialization has completed. */
pa_threaded_mainloop_lock(stm->context->mainloop);
o = pa_stream_update_timing_info(stm->stream, stream_success_callback, stm->context->mainloop);
operation_wait(stm->context, o);
pa_operation_unref(o);
pa_threaded_mainloop_unlock(stm->context->mainloop);
*stream = stm;
return CUBEB_OK;
}
void
cubeb_stream_destroy(cubeb_stream * stm)
{
if (stm->stream) {
stream_cork(stm, CORK);
pa_threaded_mainloop_lock(stm->context->mainloop);
if (stm->drain_timer) {
/* there's no pa_rttime_free, so use this instead. */
pa_threaded_mainloop_get_api(stm->context->mainloop)->time_free(stm->drain_timer);
}
pa_stream_disconnect(stm->stream);
pa_stream_unref(stm->stream);
pa_threaded_mainloop_unlock(stm->context->mainloop);
}
free(stm);
}
int
cubeb_stream_start(cubeb_stream * stm)
{
stream_cork(stm, UNCORK | NOTIFY);
return CUBEB_OK;
}
int
cubeb_stream_stop(cubeb_stream * stm)
{
stream_cork(stm, CORK | NOTIFY);
return CUBEB_OK;
}
int
cubeb_stream_get_position(cubeb_stream * stm, uint64_t * position)
{
int r;
pa_usec_t r_usec;
uint64_t bytes;
pa_threaded_mainloop_lock(stm->context->mainloop);
r = pa_stream_get_time(stm->stream, &r_usec);
pa_threaded_mainloop_unlock(stm->context->mainloop);
if (r != 0) {
return CUBEB_ERROR;
}
bytes = pa_usec_to_bytes(r_usec, &stm->sample_spec);
*position = bytes / pa_frame_size(&stm->sample_spec);
return CUBEB_OK;
}

View File

@ -216,6 +216,8 @@ cubeb_init(cubeb ** context, char const * context_name)
return CUBEB_ERROR;
}
SetThreadPriority(ctx->thread, THREAD_PRIORITY_TIME_CRITICAL);
InitializeCriticalSection(&ctx->lock);
ctx->active_streams = 0;

View File

@ -5,6 +5,7 @@ cp $1/include/cubeb/cubeb.h include
cp $1/src/cubeb_alsa.c src
cp $1/src/cubeb_winmm.c src
cp $1/src/cubeb_audiounit.c src
cp $1/src/cubeb_pulse.c src
cp $1/LICENSE .
cp $1/README .
cp $1/AUTHORS .