mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 905017 (part 3) - Move profiling stack stuff from jsapi.h to js/ProfilingStack.h. r=billm.
--HG-- extra : rebase_source : 8322f1c96b95685912375484172d47f53107947f
This commit is contained in:
parent
4caa0f8ea2
commit
c8e2369441
@ -302,6 +302,28 @@ def module_name(name):
|
||||
return name.replace('inlines.h', '').replace('-inl.h', '').replace('.h', '').replace('.cpp', '')
|
||||
|
||||
|
||||
def is_module_header(enclosing_inclname, header_inclname):
|
||||
'''Determine if an included name is the "module header", i.e. should be
|
||||
first in the file.'''
|
||||
|
||||
module = module_name(enclosing_inclname)
|
||||
|
||||
# Normal case, e.g. module == "foo/Bar", header_inclname == "foo/Bar.h".
|
||||
if module == module_name(header_inclname):
|
||||
return True
|
||||
|
||||
# A public header, e.g. module == "foo/Bar", header_inclname == "js/Bar.h".
|
||||
m = re.match(r'js\/(.*)\.h', header_inclname)
|
||||
if m is not None and module.endswith('/' + m.group(1)):
|
||||
return True
|
||||
|
||||
# A weird public header case.
|
||||
if module == 'jsmemorymetrics' and header_inclname == 'js/MemoryMetrics.h':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class Include(object):
|
||||
'''Important information for a single #include statement.'''
|
||||
|
||||
@ -313,7 +335,7 @@ class Include(object):
|
||||
def isLeaf(self):
|
||||
return True
|
||||
|
||||
def section(self, module):
|
||||
def section(self, enclosing_inclname):
|
||||
'''Identify which section inclname belongs to.
|
||||
|
||||
The section numbers are as follows.
|
||||
@ -333,12 +355,9 @@ class Include(object):
|
||||
if not self.inclname.endswith('.h'):
|
||||
return 7
|
||||
|
||||
# A couple of modules have the .h file in js/ and the .cpp file elsewhere and so need special
|
||||
# handling.
|
||||
if module == module_name(self.inclname) or \
|
||||
module == 'jsmemorymetrics' and self.inclname == 'js/MemoryMetrics.h' or \
|
||||
module == 'vm/PropertyKey' and self.inclname == 'js/PropertyKey.h' or \
|
||||
module == 'vm/StructuredClone' and self.inclname == 'js/StructuredClone.h':
|
||||
# A couple of modules have the .h file in js/ and the .cpp file elsewhere and so need
|
||||
# special handling.
|
||||
if is_module_header(enclosing_inclname, self.inclname):
|
||||
return 0
|
||||
|
||||
if '/' in self.inclname:
|
||||
@ -452,8 +471,6 @@ def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclname
|
||||
if inclname == include.inclname:
|
||||
error(filename, include.linenum, 'the file includes itself')
|
||||
|
||||
module = module_name(inclname)
|
||||
|
||||
def check_includes_order(include1, include2):
|
||||
'''Check the ordering of two #include statements.'''
|
||||
|
||||
@ -461,8 +478,8 @@ def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclname
|
||||
include2.inclname in oddly_ordered_inclnames:
|
||||
return
|
||||
|
||||
section1 = include1.section(module)
|
||||
section2 = include2.section(module)
|
||||
section1 = include1.section(inclname)
|
||||
section2 = include2.section(inclname)
|
||||
if (section1 > section2) or \
|
||||
((section1 == section2) and (include1.inclname.lower() > include2.inclname.lower())):
|
||||
error(filename, str(include1.linenum) + ':' + str(include2.linenum),
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "JavaScriptShared.h"
|
||||
#include "mozilla/jsipc/PJavaScriptParent.h"
|
||||
#include "jsclass.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#undef GetClassName
|
||||
|
94
js/public/ProfilingStack.h
Normal file
94
js/public/ProfilingStack.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef js_ProfilingStack_h
|
||||
#define js_ProfilingStack_h
|
||||
|
||||
#include "jsbytecode.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/Utility.h"
|
||||
|
||||
struct JSRuntime;
|
||||
class JSScript;
|
||||
|
||||
namespace js {
|
||||
|
||||
// A call stack can be specified to the JS engine such that all JS entry/exits
|
||||
// to functions push/pop an entry to/from the specified stack.
|
||||
//
|
||||
// For more detailed information, see vm/SPSProfiler.h.
|
||||
//
|
||||
class ProfileEntry
|
||||
{
|
||||
// All fields are marked volatile to prevent the compiler from re-ordering
|
||||
// instructions. Namely this sequence:
|
||||
//
|
||||
// entry[size] = ...;
|
||||
// size++;
|
||||
//
|
||||
// If the size modification were somehow reordered before the stores, then
|
||||
// if a sample were taken it would be examining bogus information.
|
||||
//
|
||||
// A ProfileEntry represents both a C++ profile entry and a JS one. Both use
|
||||
// the string as a description, but JS uses the sp as NULL to indicate that
|
||||
// it is a JS entry. The script_ is then only ever examined for a JS entry,
|
||||
// and the idx is used by both, but with different meanings.
|
||||
//
|
||||
const char * volatile string; // Descriptive string of this entry
|
||||
void * volatile sp; // Relevant stack pointer for the entry
|
||||
JSScript * volatile script_; // if js(), non-null script which is running
|
||||
int32_t volatile idx; // if js(), idx of pc, otherwise line number
|
||||
|
||||
public:
|
||||
// All of these methods are marked with the 'volatile' keyword because SPS's
|
||||
// representation of the stack is stored such that all ProfileEntry
|
||||
// instances are volatile. These methods would not be available unless they
|
||||
// were marked as volatile as well.
|
||||
|
||||
bool js() volatile {
|
||||
JS_ASSERT_IF(sp == NULL, script_ != NULL);
|
||||
return sp == NULL;
|
||||
}
|
||||
|
||||
uint32_t line() volatile { JS_ASSERT(!js()); return idx; }
|
||||
JSScript *script() volatile { JS_ASSERT(js()); return script_; }
|
||||
void *stackAddress() volatile { return sp; }
|
||||
const char *label() volatile { return string; }
|
||||
|
||||
void setLine(uint32_t aLine) volatile { JS_ASSERT(!js()); idx = aLine; }
|
||||
void setLabel(const char *aString) volatile { string = aString; }
|
||||
void setStackAddress(void *aSp) volatile { sp = aSp; }
|
||||
void setScript(JSScript *aScript) volatile { script_ = aScript; }
|
||||
|
||||
// We can't know the layout of JSScript, so look in vm/SPSProfiler.cpp.
|
||||
JS_FRIEND_API(jsbytecode *) pc() volatile;
|
||||
JS_FRIEND_API(void) setPC(jsbytecode *pc) volatile;
|
||||
|
||||
static size_t offsetOfString() { return offsetof(ProfileEntry, string); }
|
||||
static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); }
|
||||
static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); }
|
||||
static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); }
|
||||
|
||||
// The index used in the entry can either be a line number or the offset of
|
||||
// a pc into a script's code. To signify a NULL pc, use a -1 index. This is
|
||||
// checked against in pc() and setPC() to set/get the right pc.
|
||||
static const int32_t NullPCIndex = -1;
|
||||
};
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size,
|
||||
uint32_t max);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled);
|
||||
|
||||
JS_FRIEND_API(jsbytecode*)
|
||||
ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif /* js_ProfilingStack_h */
|
@ -1907,6 +1907,13 @@ extern JS_PUBLIC_DATA(const jsval) JSVAL_FALSE;
|
||||
extern JS_PUBLIC_DATA(const jsval) JSVAL_TRUE;
|
||||
extern JS_PUBLIC_DATA(const jsval) JSVAL_VOID;
|
||||
|
||||
namespace JS {
|
||||
|
||||
extern JS_PUBLIC_DATA(const Handle<Value>) NullHandleValue;
|
||||
extern JS_PUBLIC_DATA(const Handle<Value>) UndefinedHandleValue;
|
||||
|
||||
}
|
||||
|
||||
#undef JS_VALUE_IS_CONSTEXPR
|
||||
#undef JS_RETURN_LAYOUT_FROM_BITS
|
||||
|
||||
|
@ -302,6 +302,28 @@ def module_name(name):
|
||||
return name.replace('inlines.h', '').replace('-inl.h', '').replace('.h', '').replace('.cpp', '')
|
||||
|
||||
|
||||
def is_module_header(enclosing_inclname, header_inclname):
|
||||
'''Determine if an included name is the "module header", i.e. should be
|
||||
first in the file.'''
|
||||
|
||||
module = module_name(enclosing_inclname)
|
||||
|
||||
# Normal case, e.g. module == "foo/Bar", header_inclname == "foo/Bar.h".
|
||||
if module == module_name(header_inclname):
|
||||
return True
|
||||
|
||||
# A public header, e.g. module == "foo/Bar", header_inclname == "js/Bar.h".
|
||||
m = re.match(r'js\/(.*)\.h', header_inclname)
|
||||
if m is not None and module.endswith('/' + m.group(1)):
|
||||
return True
|
||||
|
||||
# A weird public header case.
|
||||
if module == 'jsmemorymetrics' and header_inclname == 'js/MemoryMetrics.h':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class Include(object):
|
||||
'''Important information for a single #include statement.'''
|
||||
|
||||
@ -313,7 +335,7 @@ class Include(object):
|
||||
def isLeaf(self):
|
||||
return True
|
||||
|
||||
def section(self, module):
|
||||
def section(self, enclosing_inclname):
|
||||
'''Identify which section inclname belongs to.
|
||||
|
||||
The section numbers are as follows.
|
||||
@ -333,12 +355,9 @@ class Include(object):
|
||||
if not self.inclname.endswith('.h'):
|
||||
return 7
|
||||
|
||||
# A couple of modules have the .h file in js/ and the .cpp file elsewhere and so need special
|
||||
# handling.
|
||||
if module == module_name(self.inclname) or \
|
||||
module == 'jsmemorymetrics' and self.inclname == 'js/MemoryMetrics.h' or \
|
||||
module == 'vm/PropertyKey' and self.inclname == 'js/PropertyKey.h' or \
|
||||
module == 'vm/StructuredClone' and self.inclname == 'js/StructuredClone.h':
|
||||
# A couple of modules have the .h file in js/ and the .cpp file elsewhere and so need
|
||||
# special handling.
|
||||
if is_module_header(enclosing_inclname, self.inclname):
|
||||
return 0
|
||||
|
||||
if '/' in self.inclname:
|
||||
@ -452,8 +471,6 @@ def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclname
|
||||
if inclname == include.inclname:
|
||||
error(filename, include.linenum, 'the file includes itself')
|
||||
|
||||
module = module_name(inclname)
|
||||
|
||||
def check_includes_order(include1, include2):
|
||||
'''Check the ordering of two #include statements.'''
|
||||
|
||||
@ -461,8 +478,8 @@ def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclname
|
||||
include2.inclname in oddly_ordered_inclnames:
|
||||
return
|
||||
|
||||
section1 = include1.section(module)
|
||||
section2 = include2.section(module)
|
||||
section1 = include1.section(inclname)
|
||||
section2 = include2.section(inclname)
|
||||
if (section1 > section2) or \
|
||||
((section1 == section2) and (include1.inclname.lower() > include2.inclname.lower())):
|
||||
error(filename, str(include1.linenum) + ':' + str(include2.linenum),
|
||||
|
@ -128,15 +128,6 @@ const jsid JSID_VOID = { size_t(JSID_TYPE_VOID) };
|
||||
const jsid JSID_EMPTY = { size_t(JSID_TYPE_OBJECT) };
|
||||
#endif
|
||||
|
||||
const jsval JSVAL_NULL = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL, 0));
|
||||
const jsval JSVAL_ZERO = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32, 0));
|
||||
const jsval JSVAL_ONE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32, 1));
|
||||
const jsval JSVAL_FALSE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, false));
|
||||
const jsval JSVAL_TRUE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, true));
|
||||
const jsval JSVAL_VOID = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0));
|
||||
const HandleValue JS::NullHandleValue = HandleValue::fromMarkedLocation(&JSVAL_NULL);
|
||||
const HandleValue JS::UndefinedHandleValue = HandleValue::fromMarkedLocation(&JSVAL_VOID);
|
||||
|
||||
const jsid voidIdValue = JSID_VOID;
|
||||
const jsid emptyIdValue = JSID_EMPTY;
|
||||
const HandleId JS::JSID_VOIDHANDLE = HandleId::fromMarkedLocation(&voidIdValue);
|
||||
|
@ -5087,9 +5087,6 @@ JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
|
||||
|
||||
namespace JS {
|
||||
|
||||
extern JS_PUBLIC_DATA(const Handle<Value>) NullHandleValue;
|
||||
extern JS_PUBLIC_DATA(const Handle<Value>) UndefinedHandleValue;
|
||||
|
||||
extern JS_PUBLIC_DATA(const Handle<jsid>) JSID_VOIDHANDLE;
|
||||
extern JS_PUBLIC_DATA(const Handle<jsid>) JSID_EMPTYHANDLE;
|
||||
|
||||
|
@ -991,24 +991,6 @@ js::GetEnterCompartmentDepth(JSContext *cx)
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, uint32_t max)
|
||||
{
|
||||
rt->spsProfiler.setProfilingStack(stack, size, max);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled)
|
||||
{
|
||||
rt->spsProfiler.enable(enabled);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(jsbytecode*)
|
||||
js::ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip)
|
||||
{
|
||||
return rt->spsProfiler.ipToPC(script, size_t(ip));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks)
|
||||
{
|
||||
|
@ -669,84 +669,6 @@ GetPCCountScriptSummary(JSContext *cx, size_t script);
|
||||
JS_FRIEND_API(JSString *)
|
||||
GetPCCountScriptContents(JSContext *cx, size_t script);
|
||||
|
||||
/*
|
||||
* A call stack can be specified to the JS engine such that all JS entry/exits
|
||||
* to functions push/pop an entry to/from the specified stack.
|
||||
*
|
||||
* For more detailed information, see vm/SPSProfiler.h
|
||||
*/
|
||||
class ProfileEntry
|
||||
{
|
||||
/*
|
||||
* All fields are marked volatile to prevent the compiler from re-ordering
|
||||
* instructions. Namely this sequence:
|
||||
*
|
||||
* entry[size] = ...;
|
||||
* size++;
|
||||
*
|
||||
* If the size modification were somehow reordered before the stores, then
|
||||
* if a sample were taken it would be examining bogus information.
|
||||
*
|
||||
* A ProfileEntry represents both a C++ profile entry and a JS one. Both use
|
||||
* the string as a description, but JS uses the sp as NULL to indicate that
|
||||
* it is a JS entry. The script_ is then only ever examined for a JS entry,
|
||||
* and the idx is used by both, but with different meanings.
|
||||
*/
|
||||
const char * volatile string; // Descriptive string of this entry
|
||||
void * volatile sp; // Relevant stack pointer for the entry
|
||||
JSScript * volatile script_; // if js(), non-null script which is running
|
||||
int32_t volatile idx; // if js(), idx of pc, otherwise line number
|
||||
|
||||
public:
|
||||
/*
|
||||
* All of these methods are marked with the 'volatile' keyword because SPS's
|
||||
* representation of the stack is stored such that all ProfileEntry
|
||||
* instances are volatile. These methods would not be available unless they
|
||||
* were marked as volatile as well
|
||||
*/
|
||||
|
||||
bool js() volatile {
|
||||
JS_ASSERT_IF(sp == NULL, script_ != NULL);
|
||||
return sp == NULL;
|
||||
}
|
||||
|
||||
uint32_t line() volatile { JS_ASSERT(!js()); return idx; }
|
||||
JSScript *script() volatile { JS_ASSERT(js()); return script_; }
|
||||
void *stackAddress() volatile { return sp; }
|
||||
const char *label() volatile { return string; }
|
||||
|
||||
void setLine(uint32_t aLine) volatile { JS_ASSERT(!js()); idx = aLine; }
|
||||
void setLabel(const char *aString) volatile { string = aString; }
|
||||
void setStackAddress(void *aSp) volatile { sp = aSp; }
|
||||
void setScript(JSScript *aScript) volatile { script_ = aScript; }
|
||||
|
||||
/* we can't know the layout of JSScript, so look in vm/SPSProfiler.cpp */
|
||||
JS_FRIEND_API(jsbytecode *) pc() volatile;
|
||||
JS_FRIEND_API(void) setPC(jsbytecode *pc) volatile;
|
||||
|
||||
static size_t offsetOfString() { return offsetof(ProfileEntry, string); }
|
||||
static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); }
|
||||
static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); }
|
||||
static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); }
|
||||
|
||||
/*
|
||||
* The index used in the entry can either be a line number or the offset of
|
||||
* a pc into a script's code. To signify a NULL pc, use a -1 index. This is
|
||||
* checked against in pc() and setPC() to set/get the right pc.
|
||||
*/
|
||||
static const int32_t NullPCIndex = -1;
|
||||
};
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size,
|
||||
uint32_t max);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled);
|
||||
|
||||
JS_FRIEND_API(jsbytecode*)
|
||||
ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FRIEND_API(bool)
|
||||
ContextHasOutstandingRequests(const JSContext *cx);
|
||||
|
@ -68,6 +68,7 @@ EXPORTS.js += [
|
||||
'../public/HeapAPI.h',
|
||||
'../public/LegacyIntTypes.h',
|
||||
'../public/MemoryMetrics.h',
|
||||
'../public/ProfilingStack.h',
|
||||
'../public/PropertyKey.h',
|
||||
'../public/RequiredDefines.h',
|
||||
'../public/RootingAPI.h',
|
||||
@ -132,6 +133,7 @@ CPP_SOURCES += [
|
||||
'TokenStream.cpp',
|
||||
'TypedArrayObject.cpp',
|
||||
'Unicode.cpp',
|
||||
'Value.cpp',
|
||||
'Verifier.cpp',
|
||||
'Xdr.cpp',
|
||||
'YarrCanonicalizeUCS2.cpp',
|
||||
|
@ -4,11 +4,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "js/CharacterEncoding.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsprf.h"
|
||||
|
||||
#include "js/CharacterEncoding.h"
|
||||
|
||||
using namespace JS;
|
||||
|
||||
Latin1CharsZ
|
||||
|
@ -265,14 +265,33 @@ SPSEntryMarker::~SPSEntryMarker()
|
||||
}
|
||||
|
||||
JS_FRIEND_API(jsbytecode*)
|
||||
ProfileEntry::pc() volatile {
|
||||
ProfileEntry::pc() volatile
|
||||
{
|
||||
JS_ASSERT_IF(idx != NullPCIndex, idx >= 0 && uint32_t(idx) < script()->length);
|
||||
return idx == NullPCIndex ? NULL : script()->code + idx;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
ProfileEntry::setPC(jsbytecode *pc) volatile {
|
||||
JS_ASSERT_IF(pc != NULL, script()->code <= pc &&
|
||||
pc < script()->code + script()->length);
|
||||
ProfileEntry::setPC(jsbytecode *pc) volatile
|
||||
{
|
||||
JS_ASSERT_IF(pc != NULL, script()->code <= pc && pc < script()->code + script()->length);
|
||||
idx = pc == NULL ? NullPCIndex : pc - script()->code;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, uint32_t max)
|
||||
{
|
||||
rt->spsProfiler.setProfilingStack(stack, size, max);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled)
|
||||
{
|
||||
rt->spsProfiler.enable(enabled);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(jsbytecode*)
|
||||
js::ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip)
|
||||
{
|
||||
return rt->spsProfiler.ipToPC(script, size_t(ip));
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "jsscript.h"
|
||||
|
||||
#include "js/ProfilingStack.h"
|
||||
|
||||
/*
|
||||
* SPS Profiler integration with the JS Engine
|
||||
* https://developer.mozilla.org/en/Performance/Profiling_with_the_Built-in_Profiler
|
||||
|
21
js/src/vm/Value.cpp
Normal file
21
js/src/vm/Value.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "js/Value.h"
|
||||
|
||||
const jsval JSVAL_NULL = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL, 0));
|
||||
const jsval JSVAL_ZERO = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32, 0));
|
||||
const jsval JSVAL_ONE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32, 1));
|
||||
const jsval JSVAL_FALSE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, false));
|
||||
const jsval JSVAL_TRUE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN, true));
|
||||
const jsval JSVAL_VOID = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0));
|
||||
|
||||
namespace JS {
|
||||
|
||||
const HandleValue NullHandleValue = HandleValue::fromMarkedLocation(&JSVAL_NULL);
|
||||
const HandleValue UndefinedHandleValue = HandleValue::fromMarkedLocation(&JSVAL_VOID);
|
||||
|
||||
} // namespace JS
|
@ -7,9 +7,10 @@
|
||||
#define __NSAUTOJSVALHOLDER_H__
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
/**
|
||||
* Simple class that looks and acts like a jsval except that it unroots
|
||||
* Simple class that looks and acts like a JS::Value except that it unroots
|
||||
* itself automatically if Root() is ever called. Designed to be rooted on the
|
||||
* context or runtime (but not both!).
|
||||
*/
|
||||
@ -44,7 +45,7 @@ public:
|
||||
else {
|
||||
this->Release();
|
||||
}
|
||||
*this = static_cast<jsval>(aOther);
|
||||
*this = static_cast<JS::Value>(aOther);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -76,10 +77,10 @@ public:
|
||||
|
||||
/**
|
||||
* Manually release, nullifying mVal, and mRt, but returning
|
||||
* the original jsval.
|
||||
* the original JS::Value.
|
||||
*/
|
||||
jsval Release() {
|
||||
jsval oldval = mVal;
|
||||
JS::Value Release() {
|
||||
JS::Value oldval = mVal;
|
||||
|
||||
if (mRt) {
|
||||
JS_RemoveValueRootRT(mRt, &mVal); // infallible
|
||||
@ -107,20 +108,20 @@ public:
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
jsval* ToJSValPtr() {
|
||||
JS::Value* ToJSValPtr() {
|
||||
return &mVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretend to be a jsval.
|
||||
* Pretend to be a JS::Value.
|
||||
*/
|
||||
operator jsval() const { return mVal; }
|
||||
operator JS::Value() const { return mVal; }
|
||||
|
||||
nsAutoJSValHolder &operator=(JSObject* aOther) {
|
||||
return *this = OBJECT_TO_JSVAL(aOther);
|
||||
}
|
||||
|
||||
nsAutoJSValHolder &operator=(jsval aOther) {
|
||||
nsAutoJSValHolder &operator=(JS::Value aOther) {
|
||||
#ifdef DEBUG
|
||||
if (JSVAL_IS_GCTHING(aOther) && !JSVAL_IS_NULL(aOther)) {
|
||||
MOZ_ASSERT(IsHeld(), "Not rooted!");
|
||||
@ -131,7 +132,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
jsval mVal;
|
||||
JS::Value mVal;
|
||||
JSRuntime* mRt;
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsNSSIOLayer.h"
|
||||
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include <stdint.h>
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/ProfilingStack.h"
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user