Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/js/src/vm/NativeObject.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
 * vim: set ts=8 sts=4 et sw=4 tw=99:
3
 * This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef vm_NativeObject_h
8
#define vm_NativeObject_h
9
10
#include "mozilla/Assertions.h"
11
#include "mozilla/Attributes.h"
12
13
#include <stdint.h>
14
15
#include "jsfriendapi.h"
16
#include "NamespaceImports.h"
17
18
#include "gc/Barrier.h"
19
#include "gc/Heap.h"
20
#include "gc/Marking.h"
21
#include "js/Value.h"
22
#include "vm/JSObject.h"
23
#include "vm/Shape.h"
24
#include "vm/ShapedObject.h"
25
#include "vm/StringType.h"
26
27
namespace js {
28
29
class Shape;
30
class TenuringTracer;
31
class UnboxedPlainObject;
32
33
/*
34
 * To really poison a set of values, using 'magic' or 'undefined' isn't good
35
 * enough since often these will just be ignored by buggy code (see bug 629974)
36
 * in debug builds and crash in release builds. Instead, we use a safe-for-crash
37
 * pointer.
38
 */
39
static MOZ_ALWAYS_INLINE void
40
Debug_SetValueRangeToCrashOnTouch(Value* beg, Value* end)
41
0
{
42
0
#ifdef DEBUG
43
0
    for (Value* v = beg; v != end; ++v) {
44
0
        *v = js::PoisonedObjectValue(0x48);
45
0
    }
46
0
#endif
47
0
}
Unexecuted instantiation: CTypes.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: StoreBuffer.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: jsutil.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: StructuredClone.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src0.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src1.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src10.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src11.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src12.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src14.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src15.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src17.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src18.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src19.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src2.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src20.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src21.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src22.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src23.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src24.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src25.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src26.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src27.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src28.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src29.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src3.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src30.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src31.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src32.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src33.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src34.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src35.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src36.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src37.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src38.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src39.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src4.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src40.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src41.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src42.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src43.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src44.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src45.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src5.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src6.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src7.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src8.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src9.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: RegExp.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: BinSource-auto.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: BinSource.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: BinToken.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: BinTokenReaderBase.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: BinTokenReaderMultipart.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: BinTokenReaderTester.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Parser.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Disassembler-x86-shared.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: jsmath.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Interpreter.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: VTuneWrapper.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src13.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
Unexecuted instantiation: Unified_cpp_js_src16.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, JS::Value*)
48
49
static MOZ_ALWAYS_INLINE void
50
Debug_SetValueRangeToCrashOnTouch(Value* vec, size_t len)
51
0
{
52
0
#ifdef DEBUG
53
0
    Debug_SetValueRangeToCrashOnTouch(vec, vec + len);
54
0
#endif
55
0
}
Unexecuted instantiation: CTypes.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: StoreBuffer.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: jsutil.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: StructuredClone.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src0.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src1.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src10.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src11.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src12.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src14.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src15.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src17.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src18.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src19.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src2.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src20.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src21.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src22.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src23.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src24.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src25.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src26.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src27.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src28.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src29.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src3.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src30.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src31.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src32.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src33.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src34.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src35.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src36.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src37.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src38.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src39.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src4.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src40.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src41.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src42.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src43.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src44.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src45.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src5.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src6.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src7.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src8.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src9.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: RegExp.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: BinSource-auto.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: BinSource.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: BinToken.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: BinTokenReaderBase.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: BinTokenReaderMultipart.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: BinTokenReaderTester.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Parser.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Disassembler-x86-shared.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: jsmath.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Interpreter.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: VTuneWrapper.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src13.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src16.cpp:js::Debug_SetValueRangeToCrashOnTouch(JS::Value*, unsigned long)
56
57
static MOZ_ALWAYS_INLINE void
58
Debug_SetValueRangeToCrashOnTouch(GCPtrValue* vec, size_t len)
59
0
{
60
0
#ifdef DEBUG
61
0
    Debug_SetValueRangeToCrashOnTouch((Value*) vec, len);
62
0
#endif
63
0
}
Unexecuted instantiation: CTypes.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: StoreBuffer.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: jsutil.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: StructuredClone.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src0.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src1.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src10.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src11.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src12.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src14.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src15.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src17.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src18.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src19.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src2.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src20.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src21.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src22.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src23.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src24.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src25.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src26.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src27.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src28.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src29.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src3.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src30.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src31.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src32.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src33.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src34.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src35.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src36.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src37.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src38.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src39.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src4.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src40.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src41.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src42.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src43.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src44.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src45.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src5.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src6.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src7.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src8.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src9.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: RegExp.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: BinSource-auto.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: BinSource.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: BinToken.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: BinTokenReaderBase.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: BinTokenReaderMultipart.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: BinTokenReaderTester.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Parser.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Disassembler-x86-shared.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: jsmath.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Interpreter.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: VTuneWrapper.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src13.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
Unexecuted instantiation: Unified_cpp_js_src16.cpp:js::Debug_SetValueRangeToCrashOnTouch(js::GCPtr<JS::Value>*, unsigned long)
64
65
static MOZ_ALWAYS_INLINE void
66
Debug_SetSlotRangeToCrashOnTouch(HeapSlot* vec, uint32_t len)
67
1.62M
{
68
#ifdef DEBUG
69
    Debug_SetValueRangeToCrashOnTouch((Value*) vec, len);
70
#endif
71
}
Unexecuted instantiation: CTypes.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: StoreBuffer.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: jsutil.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: StructuredClone.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src0.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src1.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src10.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src11.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src12.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src14.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src15.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src17.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src18.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src19.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src2.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src20.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src21.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src22.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src23.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src24.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src25.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src26.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src27.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src28.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src29.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src3.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src30.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src31.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src32.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src33.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src34.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src35.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src36.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unified_cpp_js_src37.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Line
Count
Source
67
1.62M
{
68
#ifdef DEBUG
69
    Debug_SetValueRangeToCrashOnTouch((Value*) vec, len);
70
#endif
71
}
Unexecuted instantiation: Unified_cpp_js_src38.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src39.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src4.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src40.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src41.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src42.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src43.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src44.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src45.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src5.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src6.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src7.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unified_cpp_js_src8.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Line
Count
Source
67
9
{
68
#ifdef DEBUG
69
    Debug_SetValueRangeToCrashOnTouch((Value*) vec, len);
70
#endif
71
}
Unexecuted instantiation: Unified_cpp_js_src9.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: RegExp.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: BinSource-auto.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: BinSource.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: BinToken.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: BinTokenReaderBase.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: BinTokenReaderMultipart.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: BinTokenReaderTester.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Parser.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Disassembler-x86-shared.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: jsmath.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Interpreter.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: VTuneWrapper.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src13.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
Unexecuted instantiation: Unified_cpp_js_src16.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, unsigned int)
72
73
static MOZ_ALWAYS_INLINE void
74
Debug_SetSlotRangeToCrashOnTouch(HeapSlot* begin, HeapSlot* end)
75
0
{
76
0
#ifdef DEBUG
77
0
    Debug_SetValueRangeToCrashOnTouch((Value*) begin, end - begin);
78
0
#endif
79
0
}
Unexecuted instantiation: CTypes.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: StoreBuffer.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: jsutil.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: StructuredClone.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src0.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src1.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src10.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src11.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src12.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src14.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src15.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src17.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src18.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src19.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src2.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src20.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src21.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src22.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src23.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src24.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src25.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src26.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src27.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src28.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src29.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src3.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src30.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src31.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src32.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src33.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src34.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src35.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src36.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src37.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src38.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src39.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src4.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src40.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src41.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src42.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src43.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src44.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src45.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src5.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src6.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src7.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src8.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src9.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: RegExp.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: BinSource-auto.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: BinSource.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: BinToken.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: BinTokenReaderBase.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: BinTokenReaderMultipart.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: BinTokenReaderTester.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Parser.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Disassembler-x86-shared.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: jsmath.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Interpreter.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: VTuneWrapper.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src13.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
Unexecuted instantiation: Unified_cpp_js_src16.cpp:js::Debug_SetSlotRangeToCrashOnTouch(js::HeapSlot*, js::HeapSlot*)
80
81
class ArrayObject;
82
83
/*
84
 * ES6 20130308 draft 8.4.2.4 ArraySetLength.
85
 *
86
 * |id| must be "length", |attrs| are the attributes to be used for the newly-
87
 * changed length property, |value| is the value for the new length, and
88
 * |result| receives an error code if the change is invalid.
89
 */
90
extern bool
91
ArraySetLength(JSContext* cx, Handle<ArrayObject*> obj, HandleId id,
92
               unsigned attrs, HandleValue value, ObjectOpResult& result);
93
94
/*
95
 * [SMDOC] NativeObject Elements layout
96
 *
97
 * Elements header used for native objects. The elements component of such objects
98
 * offers an efficient representation for all or some of the indexed properties
99
 * of the object, using a flat array of Values rather than a shape hierarchy
100
 * stored in the object's slots. This structure is immediately followed by an
101
 * array of elements, with the elements member in an object pointing to the
102
 * beginning of that array (the end of this structure).
103
 * See below for usage of this structure.
104
 *
105
 * The sets of properties represented by an object's elements and slots
106
 * are disjoint. The elements contain only indexed properties, while the slots
107
 * can contain both named and indexed properties; any indexes in the slots are
108
 * distinct from those in the elements. If isIndexed() is false for an object,
109
 * all indexed properties (if any) are stored in the dense elements.
110
 *
111
 * Indexes will be stored in the object's slots instead of its elements in
112
 * the following case:
113
 *  - there are more than MIN_SPARSE_INDEX slots total and the load factor
114
 *    (COUNT / capacity) is less than 0.25
115
 *  - a property is defined that has non-default property attributes.
116
 *
117
 * We track these pieces of metadata for dense elements:
118
 *  - The length property as a uint32_t, accessible for array objects with
119
 *    ArrayObject::{length,setLength}().  This is unused for non-arrays.
120
 *  - The number of element slots (capacity), gettable with
121
 *    getDenseCapacity().
122
 *  - The array's initialized length, accessible with
123
 *    getDenseInitializedLength().
124
 *
125
 * Holes in the array are represented by MagicValue(JS_ELEMENTS_HOLE) values.
126
 * These indicate indexes which are not dense properties of the array. The
127
 * property may, however, be held by the object's properties.
128
 *
129
 * The capacity and length of an object's elements are almost entirely
130
 * unrelated!  In general the length may be greater than, less than, or equal
131
 * to the capacity.  The first case occurs with |new Array(100)|.  The length
132
 * is 100, but the capacity remains 0 (indices below length and above capacity
133
 * must be treated as holes) until elements between capacity and length are
134
 * set.  The other two cases are common, depending upon the number of elements
135
 * in an array and the underlying allocator used for element storage.
136
 *
137
 * The only case in which the capacity and length of an object's elements are
138
 * related is when the object is an array with non-writable length.  In this
139
 * case the capacity is always less than or equal to the length.  This permits
140
 * JIT code to optimize away the check for non-writable length when assigning
141
 * to possibly out-of-range elements: such code already has to check for
142
 * |index < capacity|, and fallback code checks for non-writable length.
143
 *
144
 * The initialized length of an object specifies the number of elements that
145
 * have been initialized. All elements above the initialized length are
146
 * holes in the object, and the memory for all elements between the initialized
147
 * length and capacity is left uninitialized. The initialized length is some
148
 * value less than or equal to both the object's length and the object's
149
 * capacity.
150
 *
151
 * There is flexibility in exactly the value the initialized length must hold,
152
 * e.g. if an array has length 5, capacity 10, completely empty, it is valid
153
 * for the initialized length to be any value between zero and 5, as long as
154
 * the in memory values below the initialized length have been initialized with
155
 * a hole value. However, in such cases we want to keep the initialized length
156
 * as small as possible: if the object is known to have no hole values below
157
 * its initialized length, then it is "packed" and can be accessed much faster
158
 * by JIT code.
159
 *
160
 * Elements do not track property creation order, so enumerating the elements
161
 * of an object does not necessarily visit indexes in the order they were
162
 * created.
163
 *
164
 *
165
 * [SMDOC] NativeObject shifted elements optimization
166
 *
167
 * Shifted elements
168
 * ----------------
169
 * It's pretty common to use an array as a queue, like this:
170
 *
171
 *    while (arr.length > 0)
172
 *        foo(arr.shift());
173
 *
174
 * To ensure we don't get quadratic behavior on this, elements can be 'shifted'
175
 * in memory. tryShiftDenseElements does this by incrementing elements_ to point
176
 * to the next element and moving the ObjectElements header in memory (so it's
177
 * stored where the shifted Value used to be).
178
 *
179
 * Shifted elements can be moved when we grow the array, when the array is
180
 * made non-extensible (for simplicity, shifted elements are not supported on
181
 * objects that are non-extensible, have copy-on-write elements, or on arrays
182
 * with non-writable length).
183
 */
184
class ObjectElements
185
{
186
  public:
187
    enum Flags: uint16_t {
188
        // Integers written to these elements must be converted to doubles.
189
        CONVERT_DOUBLE_ELEMENTS     = 0x1,
190
191
        // Present only if these elements correspond to an array with
192
        // non-writable length; never present for non-arrays.
193
        NONWRITABLE_ARRAY_LENGTH    = 0x2,
194
195
        // These elements are shared with another object and must be copied
196
        // before they can be changed. A pointer to the original owner of the
197
        // elements, which is immutable, is stored immediately after the
198
        // elements data. There is one case where elements can be written to
199
        // before being copied: when setting the CONVERT_DOUBLE_ELEMENTS flag
200
        // the shared elements may change (from ints to doubles) without
201
        // making a copy first.
202
        COPY_ON_WRITE               = 0x4,
203
204
        // For TypedArrays only: this TypedArray's storage is mapping shared
205
        // memory.  This is a static property of the TypedArray, set when it
206
        // is created and never changed.
207
        SHARED_MEMORY               = 0x8,
208
209
        // These elements are set to integrity level "sealed". This flag should
210
        // only be set on non-extensible objects.
211
        SEALED                      = 0x10,
212
213
        // These elements are set to integrity level "frozen". If this flag is
214
        // set, the SEALED flag must be set as well.
215
        FROZEN                      = 0x20,
216
    };
217
218
    // The flags word stores both the flags and the number of shifted elements.
219
    // Allow shifting 2047 elements before actually moving the elements.
220
    static const size_t NumShiftedElementsBits = 11;
221
    static const size_t MaxShiftedElements = (1 << NumShiftedElementsBits) - 1;
222
    static const size_t NumShiftedElementsShift = 32 - NumShiftedElementsBits;
223
    static const size_t FlagsMask = (1 << NumShiftedElementsShift) - 1;
224
    static_assert(MaxShiftedElements == 2047,
225
                  "MaxShiftedElements should match the comment");
226
227
  private:
228
    friend class ::JSObject;
229
    friend class ArrayObject;
230
    friend class NativeObject;
231
    friend class TenuringTracer;
232
233
    friend bool js::SetIntegrityLevel(JSContext* cx, HandleObject obj, IntegrityLevel level);
234
235
    friend bool
236
    ArraySetLength(JSContext* cx, Handle<ArrayObject*> obj, HandleId id,
237
                   unsigned attrs, HandleValue value, ObjectOpResult& result);
238
239
    // The NumShiftedElementsBits high bits of this are used to store the
240
    // number of shifted elements, the other bits are available for the flags.
241
    // See Flags enum above.
242
    uint32_t flags;
243
244
    /*
245
     * Number of initialized elements. This is <= the capacity, and for arrays
246
     * is <= the length. Memory for elements above the initialized length is
247
     * uninitialized, but values between the initialized length and the proper
248
     * length are conceptually holes.
249
     */
250
    uint32_t initializedLength;
251
252
    /* Number of allocated slots. */
253
    uint32_t capacity;
254
255
    /* 'length' property of array objects, unused for other objects. */
256
    uint32_t length;
257
258
9
    bool shouldConvertDoubleElements() const {
259
9
        return flags & CONVERT_DOUBLE_ELEMENTS;
260
9
    }
261
0
    void setShouldConvertDoubleElements() {
262
0
        // Note: allow isCopyOnWrite() here, see comment above.
263
0
        flags |= CONVERT_DOUBLE_ELEMENTS;
264
0
    }
265
0
    void clearShouldConvertDoubleElements() {
266
0
        MOZ_ASSERT(!isCopyOnWrite());
267
0
        flags &= ~CONVERT_DOUBLE_ELEMENTS;
268
0
    }
269
104
    bool hasNonwritableArrayLength() const {
270
104
        return flags & NONWRITABLE_ARRAY_LENGTH;
271
104
    }
272
0
    void setNonwritableArrayLength() {
273
0
        // See ArrayObject::setNonWritableLength.
274
0
        MOZ_ASSERT(capacity == initializedLength);
275
0
        MOZ_ASSERT(numShiftedElements() == 0);
276
0
        MOZ_ASSERT(!isCopyOnWrite());
277
0
        flags |= NONWRITABLE_ARRAY_LENGTH;
278
0
    }
279
365
    bool isCopyOnWrite() const {
280
365
        return flags & COPY_ON_WRITE;
281
365
    }
282
0
    void clearCopyOnWrite() {
283
0
        MOZ_ASSERT(isCopyOnWrite());
284
0
        flags &= ~COPY_ON_WRITE;
285
0
    }
286
287
0
    void addShiftedElements(uint32_t count) {
288
0
        MOZ_ASSERT(count < capacity);
289
0
        MOZ_ASSERT(count < initializedLength);
290
0
        MOZ_ASSERT(!(flags & (NONWRITABLE_ARRAY_LENGTH | SEALED | FROZEN | COPY_ON_WRITE)));
291
0
        uint32_t numShifted = numShiftedElements() + count;
292
0
        MOZ_ASSERT(numShifted <= MaxShiftedElements);
293
0
        flags = (numShifted << NumShiftedElementsShift) | (flags & FlagsMask);
294
0
        capacity -= count;
295
0
        initializedLength -= count;
296
0
    }
297
0
    void unshiftShiftedElements(uint32_t count) {
298
0
        MOZ_ASSERT(count > 0);
299
0
        MOZ_ASSERT(!(flags & (NONWRITABLE_ARRAY_LENGTH | SEALED | FROZEN | COPY_ON_WRITE)));
300
0
        uint32_t numShifted = numShiftedElements();
301
0
        MOZ_ASSERT(count <= numShifted);
302
0
        numShifted -= count;
303
0
        flags = (numShifted << NumShiftedElementsShift) | (flags & FlagsMask);
304
0
        capacity += count;
305
0
        initializedLength += count;
306
0
    }
307
0
    void clearShiftedElements() {
308
0
        flags &= FlagsMask;
309
0
        MOZ_ASSERT(numShiftedElements() == 0);
310
0
    }
311
312
0
    void seal() {
313
0
        MOZ_ASSERT(!isSealed());
314
0
        MOZ_ASSERT(!isFrozen());
315
0
        MOZ_ASSERT(!isCopyOnWrite());
316
0
        flags |= SEALED;
317
0
    }
318
0
    void freeze() {
319
0
        MOZ_ASSERT(isSealed());
320
0
        MOZ_ASSERT(!isFrozen());
321
0
        MOZ_ASSERT(!isCopyOnWrite());
322
0
        flags |= FROZEN;
323
0
    }
324
325
  public:
326
    constexpr ObjectElements(uint32_t capacity, uint32_t length)
327
      : flags(0), initializedLength(0), capacity(capacity), length(length)
328
18
    {}
329
330
    enum class SharedMemory {
331
        IsShared
332
    };
333
334
    constexpr ObjectElements(uint32_t capacity, uint32_t length, SharedMemory shmem)
335
      : flags(SHARED_MEMORY), initializedLength(0), capacity(capacity), length(length)
336
0
    {}
337
338
109
    HeapSlot* elements() {
339
109
        return reinterpret_cast<HeapSlot*>(uintptr_t(this) + sizeof(ObjectElements));
340
109
    }
341
0
    const HeapSlot* elements() const {
342
0
        return reinterpret_cast<const HeapSlot*>(uintptr_t(this) + sizeof(ObjectElements));
343
0
    }
344
2.59k
    static ObjectElements* fromElements(HeapSlot* elems) {
345
2.59k
        return reinterpret_cast<ObjectElements*>(uintptr_t(elems) - sizeof(ObjectElements));
346
2.59k
    }
347
348
0
    bool isSharedMemory() const {
349
0
        return flags & SHARED_MEMORY;
350
0
    }
351
352
0
    GCPtrNativeObject& ownerObject() const {
353
0
        MOZ_ASSERT(isCopyOnWrite());
354
0
        return *(GCPtrNativeObject*)(&elements()[initializedLength]);
355
0
    }
356
357
0
    static int offsetOfFlags() {
358
0
        return int(offsetof(ObjectElements, flags)) - int(sizeof(ObjectElements));
359
0
    }
360
4
    static int offsetOfInitializedLength() {
361
4
        return int(offsetof(ObjectElements, initializedLength)) - int(sizeof(ObjectElements));
362
4
    }
363
0
    static int offsetOfCapacity() {
364
0
        return int(offsetof(ObjectElements, capacity)) - int(sizeof(ObjectElements));
365
0
    }
366
1
    static int offsetOfLength() {
367
1
        return int(offsetof(ObjectElements, length)) - int(sizeof(ObjectElements));
368
1
    }
369
370
    static void ConvertElementsToDoubles(JSContext* cx, uintptr_t elements);
371
    static bool MakeElementsCopyOnWrite(JSContext* cx, NativeObject* obj);
372
373
    static MOZ_MUST_USE bool PreventExtensions(JSContext* cx, NativeObject* obj);
374
    static void FreezeOrSeal(JSContext* cx, NativeObject* obj, IntegrityLevel level);
375
376
0
    bool isSealed() const {
377
0
        return flags & SEALED;
378
0
    }
379
0
    bool isFrozen() const {
380
0
        return flags & FROZEN;
381
0
    }
382
383
0
    uint8_t elementAttributes() const {
384
0
        if (isFrozen()) {
385
0
            return JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY;
386
0
        }
387
0
        if (isSealed()) {
388
0
            return JSPROP_ENUMERATE | JSPROP_PERMANENT;
389
0
        }
390
0
        return JSPROP_ENUMERATE;
391
0
    }
392
393
499
    uint32_t numShiftedElements() const {
394
499
        uint32_t numShifted = flags >> NumShiftedElementsShift;
395
499
        MOZ_ASSERT_IF(numShifted > 0,
396
499
                      !(flags & (NONWRITABLE_ARRAY_LENGTH | SEALED | FROZEN | COPY_ON_WRITE)));
397
499
        return numShifted;
398
499
    }
399
400
54
    uint32_t numAllocatedElements() const {
401
54
        return VALUES_PER_HEADER + capacity + numShiftedElements();
402
54
    }
403
404
    // This is enough slots to store an object of this class. See the static
405
    // assertion below.
406
    static const size_t VALUES_PER_HEADER = 2;
407
};
408
409
static_assert(ObjectElements::VALUES_PER_HEADER * sizeof(HeapSlot) == sizeof(ObjectElements),
410
              "ObjectElements doesn't fit in the given number of slots");
411
412
/*
413
 * Shared singletons for objects with no elements.
414
 * emptyObjectElementsShared is used only for TypedArrays, when the TA
415
 * maps shared memory.
416
 */
417
extern HeapSlot* const emptyObjectElements;
418
extern HeapSlot* const emptyObjectElementsShared;
419
420
struct Class;
421
class AutoCheckShapeConsistency;
422
class GCMarker;
423
class Shape;
424
425
class NewObjectCache;
426
427
// Operations which change an object's dense elements can either succeed, fail,
428
// or be unable to complete. The latter is used when the object's elements must
429
// become sparse instead. The enum below is used for such operations.
430
enum class DenseElementResult {
431
    Failure,
432
    Success,
433
    Incomplete
434
};
435
436
enum class ShouldUpdateTypes {
437
    Update,
438
    DontUpdate
439
};
440
441
/*
442
 * [SMDOC] NativeObject layout
443
 *
444
 * NativeObject specifies the internal implementation of a native object.
445
 *
446
 * Native objects use ShapedObject::shape to record property information. Two
447
 * native objects with the same shape are guaranteed to have the same number of
448
 * fixed slots.
449
 *
450
 * Native objects extend the base implementation of an object with storage for
451
 * the object's named properties and indexed elements.
452
 *
453
 * These are stored separately from one another. Objects are followed by a
454
 * variable-sized array of values for inline storage, which may be used by
455
 * either properties of native objects (fixed slots), by elements (fixed
456
 * elements), or by other data for certain kinds of objects, such as
457
 * ArrayBufferObjects and TypedArrayObjects.
458
 *
459
 * Named property storage can be split between fixed slots and a dynamically
460
 * allocated array (the slots member). For an object with N fixed slots, shapes
461
 * with slots [0..N-1] are stored in the fixed slots, and the remainder are
462
 * stored in the dynamic array. If all properties fit in the fixed slots, the
463
 * 'slots_' member is nullptr.
464
 *
465
 * Elements are indexed via the 'elements_' member. This member can point to
466
 * either the shared emptyObjectElements and emptyObjectElementsShared singletons,
467
 * into the inline value array (the address of the third value, to leave room
468
 * for a ObjectElements header;in this case numFixedSlots() is zero) or to
469
 * a dynamically allocated array.
470
 *
471
 * Slots and elements may both be non-empty. The slots may be either names or
472
 * indexes; no indexed property will be in both the slots and elements.
473
 */
474
class NativeObject : public ShapedObject
475
{
476
  protected:
477
    /* Slots for object properties. */
478
    js::HeapSlot* slots_;
479
480
    /* Slots for object dense elements. */
481
    js::HeapSlot* elements_;
482
483
    friend class ::JSObject;
484
485
  private:
486
0
    static void staticAsserts() {
487
0
        static_assert(sizeof(NativeObject) == sizeof(JSObject_Slots0),
488
0
                      "native object size must match GC thing size");
489
0
        static_assert(sizeof(NativeObject) == sizeof(shadow::Object),
490
0
                      "shadow interface must match actual implementation");
491
0
        static_assert(sizeof(NativeObject) % sizeof(Value) == 0,
492
0
                      "fixed slots after an object must be aligned");
493
0
494
0
        static_assert(offsetof(NativeObject, group_) == offsetof(shadow::Object, group),
495
0
                      "shadow type must match actual type");
496
0
        static_assert(offsetof(NativeObject, slots_) == offsetof(shadow::Object, slots),
497
0
                      "shadow slots must match actual slots");
498
0
        static_assert(offsetof(NativeObject, elements_) == offsetof(shadow::Object, _1),
499
0
                      "shadow placeholder must match actual elements");
500
0
501
0
        static_assert(MAX_FIXED_SLOTS <= Shape::FIXED_SLOTS_MAX,
502
0
                      "verify numFixedSlots() bitfield is big enough");
503
0
        static_assert(sizeof(NativeObject) + MAX_FIXED_SLOTS * sizeof(Value) == JSObject::MAX_BYTE_SIZE,
504
0
                      "inconsistent maximum object size");
505
0
    }
506
507
  public:
508
61.5M
    Shape* lastProperty() const {
509
61.5M
        MOZ_ASSERT(shape());
510
61.5M
        return shape();
511
61.5M
    }
512
513
0
    uint32_t propertyCount() const {
514
0
        return lastProperty()->entryCount();
515
0
    }
516
517
0
    bool hasShapeTable() const {
518
0
        return lastProperty()->hasTable();
519
0
    }
520
521
62
    HeapSlotArray getDenseElements() {
522
62
        return HeapSlotArray(elements_, !getElementsHeader()->isCopyOnWrite());
523
62
    }
524
129
    HeapSlotArray getDenseElementsAllowCopyOnWrite() {
525
129
        // Backdoor allowing direct access to copy on write elements.
526
129
        return HeapSlotArray(elements_, true);
527
129
    }
528
40
    const Value& getDenseElement(uint32_t idx) const {
529
40
        MOZ_ASSERT(idx < getDenseInitializedLength());
530
40
        return elements_[idx];
531
40
    }
532
141
    bool containsDenseElement(uint32_t idx) {
533
141
        return idx < getDenseInitializedLength() && !elements_[idx].isMagic(JS_ELEMENTS_HOLE);
534
141
    }
535
524
    uint32_t getDenseInitializedLength() const {
536
524
        return getElementsHeader()->initializedLength;
537
524
    }
538
378
    uint32_t getDenseCapacity() const {
539
378
        return getElementsHeader()->capacity;
540
378
    }
541
542
0
    bool isSharedMemory() const {
543
0
        return getElementsHeader()->isSharedMemory();
544
0
    }
545
546
    // Update the last property, keeping the number of allocated slots in sync
547
    // with the object's new slot span.
548
    MOZ_ALWAYS_INLINE bool setLastProperty(JSContext* cx, Shape* shape);
549
550
    // As for setLastProperty(), but allows the number of fixed slots to
551
    // change. This can only be used when fixed slots are being erased from the
552
    // object, and only when the object will not require dynamic slots to cover
553
    // the new properties.
554
    void setLastPropertyShrinkFixedSlots(Shape* shape);
555
556
    // As for setLastProperty(), but changes the class associated with the
557
    // object to a non-native one. This leaves the object with a type and shape
558
    // that are (temporarily) inconsistent.
559
    void setLastPropertyMakeNonNative(Shape* shape);
560
561
    // As for setLastProperty(), but changes the class associated with the
562
    // object to a native one. The object's type has already been changed, and
563
    // this brings the shape into sync with it.
564
    void setLastPropertyMakeNative(JSContext* cx, Shape* shape);
565
566
    // Newly-created TypedArrays that map a SharedArrayBuffer are
567
    // marked as shared by giving them an ObjectElements that has the
568
    // ObjectElements::SHARED_MEMORY flag set.
569
0
    void setIsSharedMemory() {
570
0
        MOZ_ASSERT(elements_ == emptyObjectElements);
571
0
        elements_ = emptyObjectElementsShared;
572
0
    }
573
574
    inline bool isInWholeCellBuffer() const;
575
576
    static inline JS::Result<NativeObject*, JS::OOM&>
577
    create(JSContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
578
           js::HandleShape shape, js::HandleObjectGroup group);
579
580
    static inline JS::Result<NativeObject*, JS::OOM&>
581
    createWithTemplate(JSContext* cx, js::gc::InitialHeap heap, HandleObject templateObject);
582
583
#ifdef DEBUG
584
    static void enableShapeConsistencyChecks();
585
#endif
586
587
  protected:
588
#ifdef DEBUG
589
    friend class js::AutoCheckShapeConsistency;
590
    void checkShapeConsistency();
591
#else
592
0
    void checkShapeConsistency() { }
593
#endif
594
595
    static Shape*
596
    replaceWithNewEquivalentShape(JSContext* cx, HandleNativeObject obj,
597
                                  Shape* existingShape, Shape* newShape = nullptr,
598
                                  bool accessorShape = false);
599
600
    /*
601
     * Remove the last property of an object, provided that it is safe to do so
602
     * (the shape and previous shape do not carry conflicting information about
603
     * the object itself).
604
     */
605
    inline void removeLastProperty(JSContext* cx);
606
    inline bool canRemoveLastProperty();
607
608
    /*
609
     * Update the slot span directly for a dictionary object, and allocate
610
     * slots to cover the new span if necessary.
611
     */
612
    bool setSlotSpan(JSContext* cx, uint32_t span);
613
614
    static MOZ_MUST_USE bool toDictionaryMode(JSContext* cx, HandleNativeObject obj);
615
616
  private:
617
    friend class TenuringTracer;
618
619
    /*
620
     * Get internal pointers to the range of values starting at start and
621
     * running for length.
622
     */
623
    void getSlotRangeUnchecked(uint32_t start, uint32_t length,
624
                               HeapSlot** fixedStart, HeapSlot** fixedEnd,
625
                               HeapSlot** slotsStart, HeapSlot** slotsEnd)
626
645
    {
627
645
        MOZ_ASSERT(start + length >= start);
628
645
629
645
        uint32_t fixed = numFixedSlots();
630
645
        if (start < fixed) {
631
426
            if (start + length < fixed) {
632
241
                *fixedStart = &fixedSlots()[start];
633
241
                *fixedEnd = &fixedSlots()[start + length];
634
241
                *slotsStart = *slotsEnd = nullptr;
635
241
            } else {
636
185
                uint32_t localCopy = fixed - start;
637
185
                *fixedStart = &fixedSlots()[start];
638
185
                *fixedEnd = &fixedSlots()[start + localCopy];
639
185
                *slotsStart = &slots_[0];
640
185
                *slotsEnd = &slots_[length - localCopy];
641
185
            }
642
426
        } else {
643
219
            *fixedStart = *fixedEnd = nullptr;
644
219
            *slotsStart = &slots_[start - fixed];
645
219
            *slotsEnd = &slots_[start - fixed + length];
646
219
        }
647
645
    }
648
649
    void getSlotRange(uint32_t start, uint32_t length,
650
                      HeapSlot** fixedStart, HeapSlot** fixedEnd,
651
                      HeapSlot** slotsStart, HeapSlot** slotsEnd)
652
380
    {
653
380
        MOZ_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
654
380
        getSlotRangeUnchecked(start, length, fixedStart, fixedEnd, slotsStart, slotsEnd);
655
380
    }
656
657
  protected:
658
    friend class GCMarker;
659
    friend class Shape;
660
    friend class NewObjectCache;
661
662
0
    void invalidateSlotRange(uint32_t start, uint32_t length) {
663
#ifdef DEBUG
664
        HeapSlot* fixedStart;
665
        HeapSlot* fixedEnd;
666
        HeapSlot* slotsStart;
667
        HeapSlot* slotsEnd;
668
        getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
669
        Debug_SetSlotRangeToCrashOnTouch(fixedStart, fixedEnd);
670
        Debug_SetSlotRangeToCrashOnTouch(slotsStart, slotsEnd);
671
#endif /* DEBUG */
672
    }
673
674
    void initializeSlotRange(uint32_t start, uint32_t count);
675
676
    /*
677
     * Initialize a flat array of slots to this object at a start slot.  The
678
     * caller must ensure that are enough slots.
679
     */
680
    void initSlotRange(uint32_t start, const Value* vector, uint32_t length);
681
682
    /*
683
     * Copy a flat array of slots to this object at a start slot. Caller must
684
     * ensure there are enough slots in this object.
685
     */
686
    void copySlotRange(uint32_t start, const Value* vector, uint32_t length);
687
688
#ifdef DEBUG
689
    enum SentinelAllowed {
690
        SENTINEL_NOT_ALLOWED,
691
        SENTINEL_ALLOWED
692
    };
693
694
    /*
695
     * Check that slot is in range for the object's allocated slots.
696
     * If sentinelAllowed then slot may equal the slot capacity.
697
     */
698
    bool slotInRange(uint32_t slot, SentinelAllowed sentinel = SENTINEL_NOT_ALLOWED) const;
699
700
    /*
701
     * Check whether a slot is a fixed slot.
702
     */
703
    bool slotIsFixed(uint32_t slot) const;
704
705
    /*
706
     * Check whether the supplied number of fixed slots is correct.
707
     */
708
    bool isNumFixedSlots(uint32_t nfixed) const;
709
#endif
710
711
    /*
712
     * Minimum size for dynamically allocated slots in normal Objects.
713
     * ArrayObjects don't use this limit and can have a lower slot capacity,
714
     * since they normally don't have a lot of slots.
715
     */
716
    static const uint32_t SLOT_CAPACITY_MIN = 8;
717
718
33.8M
    HeapSlot* fixedSlots() const {
719
33.8M
        return reinterpret_cast<HeapSlot*>(uintptr_t(this) + sizeof(NativeObject));
720
33.8M
    }
721
722
  public:
723
724
    /* Object allocation may directly initialize slots so this is public. */
725
6.54M
    void initSlots(HeapSlot* slots) {
726
6.54M
        slots_ = slots;
727
6.54M
    }
728
729
    static MOZ_MUST_USE bool generateOwnShape(JSContext* cx, HandleNativeObject obj,
730
                                              Shape* newShape = nullptr)
731
14
    {
732
14
        return replaceWithNewEquivalentShape(cx, obj, obj->lastProperty(), newShape);
733
14
    }
734
735
    static MOZ_MUST_USE bool reshapeForShadowedProp(JSContext* cx, HandleNativeObject obj);
736
    static MOZ_MUST_USE bool reshapeForProtoMutation(JSContext* cx, HandleNativeObject obj);
737
    static bool clearFlag(JSContext* cx, HandleNativeObject obj, BaseShape::Flag flag);
738
739
    // The maximum number of slots in an object.
740
    // |MAX_SLOTS_COUNT * sizeof(JS::Value)| shouldn't overflow
741
    // int32_t (see slotsSizeMustNotOverflow).
742
    static const uint32_t MAX_SLOTS_COUNT = (1 << 28) - 1;
743
744
1.62M
    static void slotsSizeMustNotOverflow() {
745
1.62M
        static_assert(NativeObject::MAX_SLOTS_COUNT <= INT32_MAX / sizeof(JS::Value),
746
1.62M
                      "every caller of this method requires that a slot "
747
1.62M
                      "number (or slot count) count multiplied by "
748
1.62M
                      "sizeof(Value) can't overflow uint32_t (and sometimes "
749
1.62M
                      "int32_t, too)");
750
1.62M
    }
751
752
61.5M
    uint32_t numFixedSlots() const {
753
61.5M
        return reinterpret_cast<const shadow::Object*>(this)->numFixedSlots();
754
61.5M
    }
755
756
    // Get the number of fixed slots when the shape pointer may have been
757
    // forwarded by a moving GC. You need to use this rather that
758
    // numFixedSlots() in a trace hook if you access an object that is not the
759
    // object being traced, since it may have a stale shape pointer.
760
    inline uint32_t numFixedSlotsMaybeForwarded() const;
761
762
1
    uint32_t numUsedFixedSlots() const {
763
1
        uint32_t nslots = lastProperty()->slotSpan(getClass());
764
1
        return Min(nslots, numFixedSlots());
765
1
    }
766
767
3.26M
    uint32_t slotSpan() const {
768
3.26M
        if (inDictionaryMode()) {
769
660
            return lastProperty()->base()->slotSpan();
770
660
        }
771
3.26M
        return lastProperty()->slotSpan();
772
3.26M
    }
773
774
    /* Whether a slot is at a fixed offset from this object. */
775
95
    bool isFixedSlot(size_t slot) {
776
95
        return slot < numFixedSlots();
777
95
    }
778
779
    /* Index into the dynamic slots array to use for a dynamic slot. */
780
21
    size_t dynamicSlotIndex(size_t slot) {
781
21
        MOZ_ASSERT(slot >= numFixedSlots());
782
21
        return slot - numFixedSlots();
783
21
    }
784
785
    /*
786
     * The methods below shadow methods on JSObject and are more efficient for
787
     * known-native objects.
788
     */
789
8.12M
    bool hasAllFlags(js::BaseShape::Flag flags) const {
790
8.12M
        MOZ_ASSERT(flags);
791
8.12M
        return shape()->hasAllObjectFlags(flags);
792
8.12M
    }
793
794
    // Native objects are never proxies. Call isExtensible instead.
795
    bool nonProxyIsExtensible() const = delete;
796
797
3.25M
    bool isExtensible() const {
798
3.25M
        return !hasAllFlags(js::BaseShape::NOT_EXTENSIBLE);
799
3.25M
    }
800
801
    /*
802
     * Whether there may be indexed properties on this object, excluding any in
803
     * the object's elements.
804
     */
805
1.62M
    bool isIndexed() const {
806
1.62M
        return hasAllFlags(js::BaseShape::INDEXED);
807
1.62M
    }
808
809
0
    static bool setHadElementsAccess(JSContext* cx, HandleNativeObject obj) {
810
0
        return setFlags(cx, obj, js::BaseShape::HAD_ELEMENTS_ACCESS);
811
0
    }
812
813
    /*
814
     * Whether SETLELEM was used to access this object. See also the comment near
815
     * PropertyTree::MAX_HEIGHT.
816
     */
817
3.25M
    bool hadElementsAccess() const {
818
3.25M
        return hasAllFlags(js::BaseShape::HAD_ELEMENTS_ACCESS);
819
3.25M
    }
820
821
1
    bool hasInterestingSymbol() const {
822
1
        return hasAllFlags(js::BaseShape::HAS_INTERESTING_SYMBOL);
823
1
    }
824
825
    /*
826
     * Grow or shrink slots immediately before changing the slot span.
827
     * The number of allocated slots is not stored explicitly, and changes to
828
     * the slots must track changes in the slot span.
829
     */
830
    bool growSlots(JSContext* cx, uint32_t oldCount, uint32_t newCount);
831
    void shrinkSlots(JSContext* cx, uint32_t oldCount, uint32_t newCount);
832
833
    /*
834
     * This method is static because it's called from JIT code. On OOM, returns
835
     * false without leaving a pending exception on the context.
836
     */
837
    static bool growSlotsDontReportOOM(JSContext* cx, NativeObject* obj, uint32_t newCount);
838
839
    /*
840
     * Like growSlotsDontReportOOM but for dense elements. This will return
841
     * false if we failed to allocate a dense element for some reason (OOM, too
842
     * many dense elements, non-writable array length, etc).
843
     */
844
    static bool addDenseElementDontReportOOM(JSContext* cx, NativeObject* obj);
845
846
9.44M
    bool hasDynamicSlots() const { return !!slots_; }
847
848
    /* Compute dynamicSlotsCount() for this object. */
849
    MOZ_ALWAYS_INLINE uint32_t numDynamicSlots() const;
850
851
0
    bool empty() const {
852
0
        return lastProperty()->isEmptyShape();
853
0
    }
854
855
    Shape* lookup(JSContext* cx, jsid id);
856
614
    Shape* lookup(JSContext* cx, PropertyName* name) {
857
614
        return lookup(cx, NameToId(name));
858
614
    }
859
860
19
    bool contains(JSContext* cx, jsid id) {
861
19
        return lookup(cx, id) != nullptr;
862
19
    }
863
6
    bool contains(JSContext* cx, PropertyName* name) {
864
6
        return lookup(cx, name) != nullptr;
865
6
    }
866
0
    bool contains(JSContext* cx, Shape* shape) {
867
0
        return lookup(cx, shape->propid()) == shape;
868
0
    }
869
870
0
    bool containsShapeOrElement(JSContext* cx, jsid id) {
871
0
        if (JSID_IS_INT(id) && containsDenseElement(JSID_TO_INT(id))) {
872
0
            return true;
873
0
        }
874
0
        return contains(cx, id);
875
0
    }
876
877
    /* Contextless; can be called from other pure code. */
878
    Shape* lookupPure(jsid id);
879
0
    Shape* lookupPure(PropertyName* name) {
880
0
        return lookupPure(NameToId(name));
881
0
    }
882
883
0
    bool containsPure(jsid id) {
884
0
        return lookupPure(id) != nullptr;
885
0
    }
886
0
    bool containsPure(PropertyName* name) {
887
0
        return containsPure(NameToId(name));
888
0
    }
889
0
    bool containsPure(Shape* shape) {
890
0
        return lookupPure(shape->propid()) == shape;
891
0
    }
892
893
    /*
894
     * Allocate and free an object slot.
895
     *
896
     * FIXME: bug 593129 -- slot allocation should be done by object methods
897
     * after calling object-parameter-free shape methods, avoiding coupling
898
     * logic across the object vs. shape module wall.
899
     */
900
    static bool allocDictionarySlot(JSContext* cx, HandleNativeObject obj, uint32_t* slotp);
901
    void freeSlot(JSContext* cx, uint32_t slot);
902
903
  private:
904
    static MOZ_ALWAYS_INLINE Shape* getChildDataProperty(JSContext* cx, HandleNativeObject obj,
905
                                                         HandleShape parent,
906
                                                         MutableHandle<StackShape> child);
907
    static MOZ_ALWAYS_INLINE Shape* getChildAccessorProperty(JSContext* cx, HandleNativeObject obj,
908
                                                             HandleShape parent,
909
                                                             MutableHandle<StackShape> child);
910
911
    static MOZ_ALWAYS_INLINE bool
912
    maybeConvertToOrGrowDictionaryForAdd(JSContext* cx, HandleNativeObject obj, HandleId id,
913
                                         ShapeTable** table, ShapeTable::Entry** entry,
914
                                         const AutoKeepShapeTables& keep);
915
916
    static bool maybeToDictionaryModeForPut(JSContext* cx, HandleNativeObject obj,
917
                                            MutableHandleShape shape);
918
919
  public:
920
    /* Add a property whose id is not yet in this scope. */
921
    static MOZ_ALWAYS_INLINE Shape* addDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
922
                                                    uint32_t slot, unsigned attrs);
923
924
    static MOZ_ALWAYS_INLINE Shape* addAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
925
                                                        JSGetterOp getter, JSSetterOp setter,
926
                                                        unsigned attrs);
927
928
    static Shape* addEnumerableDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id);
929
930
    /* Add a data property whose id is not yet in this scope. */
931
    static Shape* addDataProperty(JSContext* cx, HandleNativeObject obj,
932
                                  HandlePropertyName name, uint32_t slot, unsigned attrs);
933
934
    /* Add or overwrite a property for id in this scope. */
935
    static Shape*
936
    putDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id, unsigned attrs);
937
938
    static Shape*
939
    putAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
940
                        JSGetterOp getter, JSSetterOp setter, unsigned attrs);
941
942
    /* Change the given property into a sibling with the same id in this scope. */
943
    static Shape*
944
    changeProperty(JSContext* cx, HandleNativeObject obj, HandleShape shape,
945
                   unsigned attrs, JSGetterOp getter, JSSetterOp setter);
946
947
    /* Remove the property named by id from this object. */
948
    static bool removeProperty(JSContext* cx, HandleNativeObject obj, jsid id);
949
950
    /* Clear the scope, making it empty. */
951
    static void clear(JSContext* cx, HandleNativeObject obj);
952
953
  protected:
954
    /*
955
     * Internal helper that adds a shape not yet mapped by this object.
956
     *
957
     * Notes:
958
     * 1. getter and setter must be normalized based on flags (see jsscope.cpp).
959
     * 2. Checks for non-extensibility must be done by callers.
960
     */
961
    static Shape*
962
    addDataPropertyInternal(JSContext* cx, HandleNativeObject obj, HandleId id,
963
                            uint32_t slot, unsigned attrs, ShapeTable* table,
964
                            ShapeTable::Entry* entry, const AutoKeepShapeTables& keep);
965
966
    static Shape*
967
    addAccessorPropertyInternal(JSContext* cx, HandleNativeObject obj, HandleId id,
968
                                JSGetterOp getter, JSSetterOp setter, unsigned attrs,
969
                                ShapeTable* table, ShapeTable::Entry* entry,
970
                                const AutoKeepShapeTables& keep);
971
972
    static MOZ_MUST_USE bool fillInAfterSwap(JSContext* cx, HandleNativeObject obj,
973
                                             const AutoValueVector& values, void* priv);
974
975
  public:
976
    // Return true if this object has been converted from shared-immutable
977
    // prototype-rooted shape storage to dictionary-shapes in a doubly-linked
978
    // list.
979
17.9M
    bool inDictionaryMode() const {
980
17.9M
        return lastProperty()->inDictionary();
981
17.9M
    }
982
983
40.3M
    const Value& getSlot(uint32_t slot) const {
984
40.3M
        MOZ_ASSERT(slotInRange(slot));
985
40.3M
        uint32_t fixed = numFixedSlots();
986
40.3M
        if (slot < fixed) {
987
22.4M
            return fixedSlots()[slot];
988
22.4M
        }
989
17.8M
        return slots_[slot - fixed];
990
17.8M
    }
991
992
0
    const HeapSlot* getSlotAddressUnchecked(uint32_t slot) const {
993
0
        uint32_t fixed = numFixedSlots();
994
0
        if (slot < fixed) {
995
0
            return fixedSlots() + slot;
996
0
        }
997
0
        return slots_ + (slot - fixed);
998
0
    }
999
1000
6.50M
    HeapSlot* getSlotAddressUnchecked(uint32_t slot) {
1001
6.50M
        uint32_t fixed = numFixedSlots();
1002
6.50M
        if (slot < fixed) {
1003
3.25M
            return fixedSlots() + slot;
1004
3.25M
        }
1005
3.25M
        return slots_ + (slot - fixed);
1006
3.25M
    }
1007
1008
3.25M
    HeapSlot* getSlotAddress(uint32_t slot) {
1009
3.25M
        /*
1010
3.25M
         * This can be used to get the address of the end of the slots for the
1011
3.25M
         * object, which may be necessary when fetching zero-length arrays of
1012
3.25M
         * slots (e.g. for callObjVarArray).
1013
3.25M
         */
1014
3.25M
        MOZ_ASSERT(slotInRange(slot, SENTINEL_ALLOWED));
1015
3.25M
        return getSlotAddressUnchecked(slot);
1016
3.25M
    }
1017
1018
0
    const HeapSlot* getSlotAddress(uint32_t slot) const {
1019
0
        /*
1020
0
         * This can be used to get the address of the end of the slots for the
1021
0
         * object, which may be necessary when fetching zero-length arrays of
1022
0
         * slots (e.g. for callObjVarArray).
1023
0
         */
1024
0
        MOZ_ASSERT(slotInRange(slot, SENTINEL_ALLOWED));
1025
0
        return getSlotAddressUnchecked(slot);
1026
0
    }
1027
1028
3.25M
    MOZ_ALWAYS_INLINE HeapSlot& getSlotRef(uint32_t slot) {
1029
3.25M
        MOZ_ASSERT(slotInRange(slot));
1030
3.25M
        return *getSlotAddress(slot);
1031
3.25M
    }
1032
1033
0
    MOZ_ALWAYS_INLINE const HeapSlot& getSlotRef(uint32_t slot) const {
1034
0
        MOZ_ASSERT(slotInRange(slot));
1035
0
        return *getSlotAddress(slot);
1036
0
    }
1037
1038
    // Check requirements on values stored to this object.
1039
3.25M
    MOZ_ALWAYS_INLINE void checkStoredValue(const Value& v) {
1040
3.25M
        MOZ_ASSERT(IsObjectValueInCompartment(v, compartment()));
1041
3.25M
        MOZ_ASSERT(AtomIsMarked(zoneFromAnyThread(), v));
1042
3.25M
    }
1043
1044
3.25M
    MOZ_ALWAYS_INLINE void setSlot(uint32_t slot, const Value& value) {
1045
3.25M
        MOZ_ASSERT(slotInRange(slot));
1046
3.25M
        checkStoredValue(value);
1047
3.25M
        getSlotRef(slot).set(this, HeapSlot::Slot, slot, value);
1048
3.25M
    }
1049
1050
355
    MOZ_ALWAYS_INLINE void initSlot(uint32_t slot, const Value& value) {
1051
355
        MOZ_ASSERT(getSlot(slot).isUndefined());
1052
355
        MOZ_ASSERT(slotInRange(slot));
1053
355
        checkStoredValue(value);
1054
355
        initSlotUnchecked(slot, value);
1055
355
    }
1056
1057
3.25M
    MOZ_ALWAYS_INLINE void initSlotUnchecked(uint32_t slot, const Value& value) {
1058
3.25M
        getSlotAddressUnchecked(slot)->init(this, HeapSlot::Slot, slot, value);
1059
3.25M
    }
1060
1061
    // MAX_FIXED_SLOTS is the biggest number of fixed slots our GC
1062
    // size classes will give an object.
1063
    static const uint32_t MAX_FIXED_SLOTS = shadow::Object::MAX_FIXED_SLOTS;
1064
1065
  protected:
1066
    MOZ_ALWAYS_INLINE bool updateSlotsForSpan(JSContext* cx, size_t oldSpan, size_t newSpan);
1067
1068
  private:
1069
44
    void prepareElementRangeForOverwrite(size_t start, size_t end) {
1070
44
        MOZ_ASSERT(end <= getDenseInitializedLength());
1071
44
        MOZ_ASSERT(!denseElementsAreCopyOnWrite());
1072
44
        for (size_t i = start; i < end; i++) {
1073
0
            elements_[i].destroy();
1074
0
        }
1075
44
    }
1076
1077
    /*
1078
     * Trigger the write barrier on a range of slots that will no longer be
1079
     * reachable.
1080
     */
1081
0
    void prepareSlotRangeForOverwrite(size_t start, size_t end) {
1082
0
        for (size_t i = start; i < end; i++) {
1083
0
            getSlotAddressUnchecked(i)->destroy();
1084
0
        }
1085
0
    }
1086
1087
    inline void shiftDenseElementsUnchecked(uint32_t count);
1088
1089
  public:
1090
    static bool rollbackProperties(JSContext* cx, HandleNativeObject obj,
1091
                                   uint32_t slotSpan);
1092
1093
    MOZ_ALWAYS_INLINE void setSlotWithType(JSContext* cx, Shape* shape,
1094
                                           const Value& value, bool overwriting = true);
1095
1096
9.74M
    MOZ_ALWAYS_INLINE const Value& getReservedSlot(uint32_t index) const {
1097
9.74M
        MOZ_ASSERT(index < JSSLOT_FREE(getClass()));
1098
9.74M
        return getSlot(index);
1099
9.74M
    }
1100
1101
0
    MOZ_ALWAYS_INLINE const HeapSlot& getReservedSlotRef(uint32_t index) const {
1102
0
        MOZ_ASSERT(index < JSSLOT_FREE(getClass()));
1103
0
        return getSlotRef(index);
1104
0
    }
1105
1106
0
    MOZ_ALWAYS_INLINE HeapSlot& getReservedSlotRef(uint32_t index) {
1107
0
        MOZ_ASSERT(index < JSSLOT_FREE(getClass()));
1108
0
        return getSlotRef(index);
1109
0
    }
1110
1111
299
    MOZ_ALWAYS_INLINE void initReservedSlot(uint32_t index, const Value& v) {
1112
299
        MOZ_ASSERT(index < JSSLOT_FREE(getClass()));
1113
299
        initSlot(index, v);
1114
299
    }
1115
1116
349
    MOZ_ALWAYS_INLINE void setReservedSlot(uint32_t index, const Value& v) {
1117
349
        MOZ_ASSERT(index < JSSLOT_FREE(getClass()));
1118
349
        setSlot(index, v);
1119
349
    }
1120
1121
    /* For slots which are known to always be fixed, due to the way they are allocated. */
1122
1123
0
    HeapSlot& getFixedSlotRef(uint32_t slot) {
1124
0
        MOZ_ASSERT(slotIsFixed(slot));
1125
0
        return fixedSlots()[slot];
1126
0
    }
1127
1128
0
    const Value& getFixedSlot(uint32_t slot) const {
1129
0
        MOZ_ASSERT(slotIsFixed(slot));
1130
0
        return fixedSlots()[slot];
1131
0
    }
1132
1133
0
    void setFixedSlot(uint32_t slot, const Value& value) {
1134
0
        MOZ_ASSERT(slotIsFixed(slot));
1135
0
        checkStoredValue(value);
1136
0
        fixedSlots()[slot].set(this, HeapSlot::Slot, slot, value);
1137
0
    }
1138
1139
92
    void initFixedSlot(uint32_t slot, const Value& value) {
1140
92
        MOZ_ASSERT(slotIsFixed(slot));
1141
92
        checkStoredValue(value);
1142
92
        fixedSlots()[slot].init(this, HeapSlot::Slot, slot, value);
1143
92
    }
1144
1145
    /*
1146
     * Get the number of dynamic slots to allocate to cover the properties in
1147
     * an object with the given number of fixed slots and slot span. The slot
1148
     * capacity is not stored explicitly, and the allocated size of the slot
1149
     * array is kept in sync with this count.
1150
     */
1151
    static MOZ_ALWAYS_INLINE uint32_t dynamicSlotsCount(uint32_t nfixed, uint32_t span,
1152
                                                        const Class* clasp);
1153
    static MOZ_ALWAYS_INLINE uint32_t dynamicSlotsCount(Shape* shape);
1154
1155
    /* Elements accessors. */
1156
1157
    // The maximum size, in sizeof(Value), of the allocation used for an
1158
    // object's dense elements.  (This includes space used to store an
1159
    // ObjectElements instance.)
1160
    // |MAX_DENSE_ELEMENTS_ALLOCATION * sizeof(JS::Value)| shouldn't overflow
1161
    // int32_t (see elementsSizeMustNotOverflow).
1162
    static const uint32_t MAX_DENSE_ELEMENTS_ALLOCATION = (1 << 28) - 1;
1163
1164
    // The maximum number of usable dense elements in an object.
1165
    static const uint32_t MAX_DENSE_ELEMENTS_COUNT =
1166
        MAX_DENSE_ELEMENTS_ALLOCATION - ObjectElements::VALUES_PER_HEADER;
1167
1168
2
    static void elementsSizeMustNotOverflow() {
1169
2
        static_assert(NativeObject::MAX_DENSE_ELEMENTS_COUNT <= INT32_MAX / sizeof(JS::Value),
1170
2
                      "every caller of this method require that an element "
1171
2
                      "count multiplied by sizeof(Value) can't overflow "
1172
2
                      "uint32_t (and sometimes int32_t ,too)");
1173
2
    }
1174
1175
2.54k
    ObjectElements* getElementsHeader() const {
1176
2.54k
        return ObjectElements::fromElements(elements_);
1177
2.54k
    }
1178
1179
    // Returns a pointer to the first element, including shifted elements.
1180
106
    inline HeapSlot* unshiftedElements() const {
1181
106
        return elements_ - getElementsHeader()->numShiftedElements();
1182
106
    }
1183
1184
    // Like getElementsHeader, but returns a pointer to the unshifted header.
1185
    // This is mainly useful for free()ing dynamic elements: the pointer
1186
    // returned here is the one we got from malloc.
1187
55
    void* getUnshiftedElementsHeader() const {
1188
55
        return ObjectElements::fromElements(unshiftedElements());
1189
55
    }
1190
1191
181
    uint32_t unshiftedIndex(uint32_t index) const {
1192
181
        return index + getElementsHeader()->numShiftedElements();
1193
181
    }
1194
1195
    /* Accessors for elements. */
1196
110
    bool ensureElements(JSContext* cx, uint32_t capacity) {
1197
110
        MOZ_ASSERT(!denseElementsAreCopyOnWrite());
1198
110
        MOZ_ASSERT(isExtensible());
1199
110
        if (capacity > getDenseCapacity()) {
1200
1
            return growElements(cx, capacity);
1201
1
        }
1202
109
        return true;
1203
109
    }
1204
1205
    // Try to shift |count| dense elements, see the "Shifted elements" comment.
1206
    inline bool tryShiftDenseElements(uint32_t count);
1207
1208
    // Try to make space for |count| dense elements at the start of the array.
1209
    bool tryUnshiftDenseElements(uint32_t count);
1210
1211
    // Move the elements header and all shifted elements to the start of the
1212
    // allocated elements space, so that numShiftedElements is 0 afterwards.
1213
    void moveShiftedElements();
1214
1215
    // If this object has many shifted elements call moveShiftedElements.
1216
    void maybeMoveShiftedElements();
1217
1218
    static bool goodElementsAllocationAmount(JSContext* cx, uint32_t reqAllocated,
1219
                                             uint32_t length, uint32_t* goodAmount);
1220
    bool growElements(JSContext* cx, uint32_t newcap);
1221
    void shrinkElements(JSContext* cx, uint32_t cap);
1222
0
    void setDynamicElements(ObjectElements* header) {
1223
0
        MOZ_ASSERT(!hasDynamicElements());
1224
0
        elements_ = header->elements();
1225
0
        MOZ_ASSERT(hasDynamicElements());
1226
0
    }
1227
1228
    static bool CopyElementsForWrite(JSContext* cx, NativeObject* obj);
1229
1230
104
    bool maybeCopyElementsForWrite(JSContext* cx) {
1231
104
        if (denseElementsAreCopyOnWrite()) {
1232
0
            return CopyElementsForWrite(cx, this);
1233
0
        }
1234
104
        return true;
1235
104
    }
1236
1237
  private:
1238
    inline void ensureDenseInitializedLengthNoPackedCheck(uint32_t index, uint32_t extra);
1239
1240
    // Run a post write barrier that encompasses multiple contiguous elements in a
1241
    // single step.
1242
    inline void elementsRangeWriteBarrierPost(uint32_t start, uint32_t count);
1243
1244
  public:
1245
    // When an array's length becomes non-writable, writes to indexes greater
1246
    // greater than or equal to the length don't change the array.  We handle
1247
    // this with a check for non-writable length in most places. But in JIT code
1248
    // every check counts -- so we piggyback the check on the already-required
1249
    // range check for |index < capacity| by making capacity of arrays with
1250
    // non-writable length never exceed the length. This mechanism is also used
1251
    // when an object becomes non-extensible.
1252
0
    void shrinkCapacityToInitializedLength(JSContext* cx) {
1253
0
        if (getElementsHeader()->numShiftedElements() > 0) {
1254
0
            moveShiftedElements();
1255
0
        }
1256
0
1257
0
        ObjectElements* header = getElementsHeader();
1258
0
        uint32_t len = header->initializedLength;
1259
0
        if (header->capacity > len) {
1260
0
            shrinkElements(cx, len);
1261
0
            header = getElementsHeader();
1262
0
            header->capacity = len;
1263
0
        }
1264
0
    }
1265
1266
  private:
1267
44
    void setDenseInitializedLengthInternal(uint32_t length) {
1268
44
        MOZ_ASSERT(length <= getDenseCapacity());
1269
44
        MOZ_ASSERT(!denseElementsAreCopyOnWrite());
1270
44
        MOZ_ASSERT(!denseElementsAreFrozen());
1271
44
        prepareElementRangeForOverwrite(length, getElementsHeader()->initializedLength);
1272
44
        getElementsHeader()->initializedLength = length;
1273
44
    }
1274
1275
  public:
1276
44
    void setDenseInitializedLength(uint32_t length) {
1277
44
        MOZ_ASSERT(isExtensible());
1278
44
        setDenseInitializedLengthInternal(length);
1279
44
    }
1280
1281
0
    void setDenseInitializedLengthMaybeNonExtensible(JSContext* cx, uint32_t length) {
1282
0
        setDenseInitializedLengthInternal(length);
1283
0
        if (!isExtensible()) {
1284
0
            shrinkCapacityToInitializedLength(cx);
1285
0
        }
1286
0
    }
1287
1288
    inline void ensureDenseInitializedLength(JSContext* cx,
1289
                                             uint32_t index, uint32_t extra);
1290
1291
94
    void setDenseElement(uint32_t index, const Value& val) {
1292
94
        MOZ_ASSERT(index < getDenseInitializedLength());
1293
94
        MOZ_ASSERT(!denseElementsAreCopyOnWrite());
1294
94
        MOZ_ASSERT(!denseElementsAreFrozen());
1295
94
        checkStoredValue(val);
1296
94
        elements_[index].set(this, HeapSlot::Element, unshiftedIndex(index), val);
1297
94
    }
1298
1299
86
    void initDenseElement(uint32_t index, const Value& val) {
1300
86
        MOZ_ASSERT(index < getDenseInitializedLength());
1301
86
        MOZ_ASSERT(!denseElementsAreCopyOnWrite());
1302
86
        MOZ_ASSERT(isExtensible());
1303
86
        checkStoredValue(val);
1304
86
        elements_[index].init(this, HeapSlot::Element, unshiftedIndex(index), val);
1305
86
    }
1306
1307
94
    void setDenseElementMaybeConvertDouble(uint32_t index, const Value& val) {
1308
94
        if (val.isInt32() && shouldConvertDoubleElements()) {
1309
0
            setDenseElement(index, DoubleValue(val.toInt32()));
1310
94
        } else {
1311
94
            setDenseElement(index, val);
1312
94
        }
1313
94
    }
1314
1315
  private:
1316
    inline void addDenseElementType(JSContext* cx, uint32_t index, const Value& val);
1317
1318
  public:
1319
    inline void setDenseElementWithType(JSContext* cx, uint32_t index,
1320
                                        const Value& val);
1321
    inline void initDenseElementWithType(JSContext* cx, uint32_t index,
1322
                                         const Value& val);
1323
    inline void setDenseElementHole(JSContext* cx, uint32_t index);
1324
    inline void removeDenseElementForSparseIndex(JSContext* cx, uint32_t index);
1325
1326
    inline Value getDenseOrTypedArrayElement(uint32_t idx);
1327
1328
    inline void copyDenseElements(uint32_t dstStart, const Value* src, uint32_t count);
1329
    inline void initDenseElements(const Value* src, uint32_t count);
1330
    inline void initDenseElements(NativeObject* src, uint32_t srcStart, uint32_t count);
1331
    inline void moveDenseElements(uint32_t dstStart, uint32_t srcStart, uint32_t count);
1332
    inline void moveDenseElementsNoPreBarrier(uint32_t dstStart, uint32_t srcStart, uint32_t count);
1333
    inline void reverseDenseElementsNoPreBarrier(uint32_t length);
1334
1335
    inline DenseElementResult
1336
    setOrExtendDenseElements(JSContext* cx, uint32_t start, const Value* vp, uint32_t count,
1337
                             ShouldUpdateTypes updateTypes = ShouldUpdateTypes::Update);
1338
1339
9
    bool shouldConvertDoubleElements() {
1340
9
        return getElementsHeader()->shouldConvertDoubleElements();
1341
9
    }
1342
1343
    inline void setShouldConvertDoubleElements();
1344
    inline void clearShouldConvertDoubleElements();
1345
1346
303
    bool denseElementsAreCopyOnWrite() {
1347
303
        return getElementsHeader()->isCopyOnWrite();
1348
303
    }
1349
1350
0
    bool denseElementsAreSealed() const {
1351
0
        return getElementsHeader()->isSealed();
1352
0
    }
1353
0
    bool denseElementsAreFrozen() const {
1354
0
        return getElementsHeader()->isFrozen();
1355
0
    }
1356
1357
    /* Packed information for this object's elements. */
1358
    inline bool writeToIndexWouldMarkNotPacked(uint32_t index);
1359
    inline void markDenseElementsNotPacked(JSContext* cx);
1360
1361
    // Ensures that the object can hold at least index + extra elements. This
1362
    // returns DenseElement_Success on success, DenseElement_Failed on failure
1363
    // to grow the array, or DenseElement_Incomplete when the object is too
1364
    // sparse to grow (this includes the case of index + extra overflow). In
1365
    // the last two cases the object is kept intact.
1366
    inline DenseElementResult ensureDenseElements(JSContext* cx,
1367
                                                  uint32_t index, uint32_t extra);
1368
1369
    inline DenseElementResult extendDenseElements(JSContext* cx,
1370
                                                  uint32_t requiredCapacity, uint32_t extra);
1371
1372
    /* Small objects are dense, no matter what. */
1373
    static const uint32_t MIN_SPARSE_INDEX = 1000;
1374
1375
    /*
1376
     * Element storage for an object will be sparse if fewer than 1/8 indexes
1377
     * are filled in.
1378
     */
1379
    static const unsigned SPARSE_DENSITY_RATIO = 8;
1380
1381
    /*
1382
     * Check if after growing the object's elements will be too sparse.
1383
     * newElementsHint is an estimated number of elements to be added.
1384
     */
1385
    bool willBeSparseElements(uint32_t requiredCapacity, uint32_t newElementsHint);
1386
1387
    /*
1388
     * After adding a sparse index to obj, see if it should be converted to use
1389
     * dense elements.
1390
     */
1391
    static DenseElementResult maybeDensifySparseElements(JSContext* cx,
1392
                                                         HandleNativeObject obj);
1393
1394
219
    inline HeapSlot* fixedElements() const {
1395
219
        static_assert(2 * sizeof(Value) == sizeof(ObjectElements),
1396
219
                      "when elements are stored inline, the first two "
1397
219
                      "slots will hold the ObjectElements header");
1398
219
        return &fixedSlots()[2];
1399
219
    }
1400
1401
#ifdef DEBUG
1402
    bool canHaveNonEmptyElements();
1403
#endif
1404
1405
6.54M
    void setEmptyElements() {
1406
6.54M
        elements_ = emptyObjectElements;
1407
6.54M
    }
1408
1409
168
    void setFixedElements(uint32_t numShifted = 0) {
1410
168
        MOZ_ASSERT(canHaveNonEmptyElements());
1411
168
        elements_ = fixedElements() + numShifted;
1412
168
    }
1413
1414
7.77M
    inline bool hasDynamicElements() const {
1415
7.77M
        /*
1416
7.77M
         * Note: for objects with zero fixed slots this could potentially give
1417
7.77M
         * a spurious 'true' result, if the end of this object is exactly
1418
7.77M
         * aligned with the end of its arena and dynamic slots are allocated
1419
7.77M
         * immediately afterwards. Such cases cannot occur for dense arrays
1420
7.77M
         * (which have at least two fixed slots) and can only result in a leak.
1421
7.77M
         */
1422
7.77M
        return !hasEmptyElements() && !hasFixedElements();
1423
7.77M
    }
1424
1425
51
    inline bool hasFixedElements() const {
1426
51
        return unshiftedElements() == fixedElements();
1427
51
    }
1428
1429
7.79M
    inline bool hasEmptyElements() const {
1430
7.79M
        return elements_ == emptyObjectElements || elements_ == emptyObjectElementsShared;
1431
7.79M
    }
1432
1433
    /*
1434
     * Get a pointer to the unused data in the object's allocation immediately
1435
     * following this object, for use with objects which allocate a larger size
1436
     * class than they need and store non-elements data inline.
1437
     */
1438
    inline uint8_t* fixedData(size_t nslots) const;
1439
1440
    inline void privateWriteBarrierPre(void** oldval);
1441
1442
0
    void privateWriteBarrierPost(void** pprivate) {
1443
0
        gc::Cell** cellp = reinterpret_cast<gc::Cell**>(pprivate);
1444
0
        MOZ_ASSERT(cellp);
1445
0
        MOZ_ASSERT(*cellp);
1446
0
        gc::StoreBuffer* storeBuffer = (*cellp)->storeBuffer();
1447
0
        if (storeBuffer) {
1448
0
            storeBuffer->putCell(cellp);
1449
0
        }
1450
0
    }
1451
1452
    /* Private data accessors. */
1453
1454
8.16M
    inline void*& privateRef(uint32_t nfixed) const { /* XXX should be private, not protected! */
1455
8.16M
        /*
1456
8.16M
         * The private pointer of an object can hold any word sized value.
1457
8.16M
         * Private pointers are stored immediately after the last fixed slot of
1458
8.16M
         * the object.
1459
8.16M
         */
1460
8.16M
        MOZ_ASSERT(isNumFixedSlots(nfixed));
1461
8.16M
        MOZ_ASSERT(hasPrivate());
1462
8.16M
        HeapSlot* end = &fixedSlots()[nfixed];
1463
8.16M
        return *reinterpret_cast<void**>(end);
1464
8.16M
    }
1465
1466
1
    bool hasPrivate() const {
1467
1
        return getClass()->hasPrivate();
1468
1
    }
1469
21
    void* getPrivate() const {
1470
21
        return privateRef(numFixedSlots());
1471
21
    }
1472
4.87M
    void setPrivate(void* data) {
1473
4.87M
        void** pprivate = &privateRef(numFixedSlots());
1474
4.87M
        privateWriteBarrierPre(pprivate);
1475
4.87M
        *pprivate = data;
1476
4.87M
    }
1477
1478
0
    void setPrivateGCThing(gc::Cell* cell) {
1479
0
        MOZ_ASSERT_IF(IsMarkedBlack(this), !cell->isMarkedGray());
1480
0
        void** pprivate = &privateRef(numFixedSlots());
1481
0
        privateWriteBarrierPre(pprivate);
1482
0
        *pprivate = reinterpret_cast<void*>(cell);
1483
0
        privateWriteBarrierPost(pprivate);
1484
0
    }
1485
1486
0
    void setPrivateUnbarriered(void* data) {
1487
0
        void** pprivate = &privateRef(numFixedSlots());
1488
0
        *pprivate = data;
1489
0
    }
1490
3.28M
    void initPrivate(void* data) {
1491
3.28M
        privateRef(numFixedSlots()) = data;
1492
3.28M
    }
1493
1494
    /* Access private data for an object with a known number of fixed slots. */
1495
0
    inline void* getPrivate(uint32_t nfixed) const {
1496
0
        return privateRef(nfixed);
1497
0
    }
1498
0
    void setPrivateUnbarriered(uint32_t nfixed, void* data) {
1499
0
        void** pprivate = &privateRef(nfixed);
1500
0
        *pprivate = data;
1501
0
    }
1502
1503
    static inline NativeObject*
1504
    copy(JSContext* cx, gc::AllocKind kind, gc::InitialHeap heap,
1505
         HandleNativeObject templateObject);
1506
1507
    /* Return the allocKind we would use if we were to tenure this object. */
1508
    inline js::gc::AllocKind allocKindForTenure() const;
1509
1510
    void updateShapeAfterMovingGC();
1511
    void sweepDictionaryListPointer();
1512
    void updateDictionaryListPointerAfterMinorGC(NativeObject* old);
1513
1514
    // Native objects are never wrappers, so a native object always has a realm
1515
    // and global.
1516
1.76k
    JS::Realm* realm() const {
1517
1.76k
        return nonCCWRealm();
1518
1.76k
    }
1519
    inline js::GlobalObject& global() const;
1520
1521
    /* JIT Accessors */
1522
6
    static size_t offsetOfElements() { return offsetof(NativeObject, elements_); }
1523
0
    static size_t offsetOfFixedElements() {
1524
0
        return sizeof(NativeObject) + sizeof(ObjectElements);
1525
0
    }
1526
1527
86
    static size_t getFixedSlotOffset(size_t slot) {
1528
86
        return sizeof(NativeObject) + slot * sizeof(Value);
1529
86
    }
1530
0
    static size_t getPrivateDataOffset(size_t nfixed) { return getFixedSlotOffset(nfixed); }
1531
32
    static size_t offsetOfSlots() { return offsetof(NativeObject, slots_); }
1532
};
1533
1534
// Object class for plain native objects created using '{}' object literals,
1535
// 'new Object()', 'Object.create', etc.
1536
class PlainObject : public NativeObject
1537
{
1538
  public:
1539
    static const js::Class class_;
1540
1541
    /* Return the allocKind we would use if we were to tenure this object. */
1542
    inline js::gc::AllocKind allocKindForTenure() const;
1543
};
1544
1545
inline void
1546
NativeObject::privateWriteBarrierPre(void** oldval)
1547
4.87M
{
1548
4.87M
    JS::shadow::Zone* shadowZone = this->shadowZoneFromAnyThread();
1549
4.87M
    if (shadowZone->needsIncrementalBarrier() && *oldval && getClass()->hasTrace()) {
1550
0
        getClass()->doTrace(shadowZone->barrierTracer(), this);
1551
0
    }
1552
4.87M
}
1553
1554
1555
/*** Standard internal methods *******************************************************************/
1556
1557
/*
1558
 * These functions should follow the algorithms in ES6 draft rev 29 section 9.1
1559
 * ("Ordinary Object Internal Methods"). It's an ongoing project.
1560
 *
1561
 * Many native objects are not "ordinary" in ES6, so these functions also have
1562
 * to serve some of the special needs of Functions (9.2, 9.3, 9.4.1), Arrays
1563
 * (9.4.2), Strings (9.4.3), and so on.
1564
 */
1565
1566
extern bool
1567
NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
1568
                     Handle<JS::PropertyDescriptor> desc,
1569
                     ObjectOpResult& result);
1570
1571
extern bool
1572
NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
1573
                         unsigned attrs, ObjectOpResult& result);
1574
1575
/* If the result out-param is omitted, throw on failure. */
1576
extern bool
1577
NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
1578
                             GetterOp getter, SetterOp setter, unsigned attrs);
1579
1580
extern bool
1581
NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
1582
                             HandleObject getter, HandleObject setter, unsigned attrs);
1583
1584
extern bool
1585
NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
1586
                         unsigned attrs);
1587
1588
extern bool
1589
NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
1590
                         HandleValue value, unsigned attrs);
1591
1592
extern bool
1593
NativeHasProperty(JSContext* cx, HandleNativeObject obj, HandleId id, bool* foundp);
1594
1595
extern bool
1596
NativeGetOwnPropertyDescriptor(JSContext* cx, HandleNativeObject obj, HandleId id,
1597
                               MutableHandle<JS::PropertyDescriptor> desc);
1598
1599
extern bool
1600
NativeGetProperty(JSContext* cx, HandleNativeObject obj, HandleValue receiver, HandleId id,
1601
                  MutableHandleValue vp);
1602
1603
extern bool
1604
NativeGetPropertyNoGC(JSContext* cx, NativeObject* obj, const Value& receiver, jsid id, Value* vp);
1605
1606
inline bool
1607
NativeGetProperty(JSContext* cx, HandleNativeObject obj, HandleId id, MutableHandleValue vp)
1608
0
{
1609
0
    RootedValue receiver(cx, ObjectValue(*obj));
1610
0
    return NativeGetProperty(cx, obj, receiver, id, vp);
1611
0
}
1612
1613
bool
1614
SetPropertyByDefining(JSContext* cx, HandleId id, HandleValue v, HandleValue receiver,
1615
                      ObjectOpResult& result);
1616
1617
bool
1618
SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
1619
                   HandleValue receiver, ObjectOpResult& result);
1620
1621
/*
1622
 * Indicates whether an assignment operation is qualified (`x.y = 0`) or
1623
 * unqualified (`y = 0`). In strict mode, the latter is an error if no such
1624
 * variable already exists.
1625
 *
1626
 * Used as an argument to NativeSetProperty.
1627
 */
1628
enum QualifiedBool {
1629
    Unqualified = 0,
1630
    Qualified = 1
1631
};
1632
1633
template <QualifiedBool Qualified>
1634
extern bool
1635
NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue v,
1636
                  HandleValue receiver, ObjectOpResult& result);
1637
1638
extern bool
1639
NativeSetElement(JSContext* cx, HandleNativeObject obj, uint32_t index, HandleValue v,
1640
                 HandleValue receiver, ObjectOpResult& result);
1641
1642
extern bool
1643
NativeDeleteProperty(JSContext* cx, HandleNativeObject obj, HandleId id, ObjectOpResult& result);
1644
1645
1646
/*** SpiderMonkey nonstandard internal methods ***************************************************/
1647
1648
template <AllowGC allowGC>
1649
extern bool
1650
NativeLookupOwnProperty(JSContext* cx,
1651
                        typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
1652
                        typename MaybeRooted<jsid, allowGC>::HandleType id,
1653
                        typename MaybeRooted<PropertyResult, allowGC>::MutableHandleType propp);
1654
1655
/*
1656
 * Get a property from `receiver`, after having already done a lookup and found
1657
 * the property on a native object `obj`.
1658
 *
1659
 * `shape` must not be null and must not be an implicit dense property. It must
1660
 * be present in obj's shape chain.
1661
 */
1662
extern bool
1663
NativeGetExistingProperty(JSContext* cx, HandleObject receiver, HandleNativeObject obj,
1664
                          HandleShape shape, MutableHandleValue vp);
1665
1666
/* * */
1667
1668
extern bool
1669
GetNameBoundInEnvironment(JSContext* cx, HandleObject env, HandleId id, MutableHandleValue vp);
1670
1671
} /* namespace js */
1672
1673
template <>
1674
inline bool
1675
0
JSObject::is<js::NativeObject>() const { return isNative(); }
1676
1677
namespace js {
1678
1679
// Alternate to JSObject::as<NativeObject>() that tolerates null pointers.
1680
inline NativeObject*
1681
MaybeNativeObject(JSObject* obj)
1682
62
{
1683
62
    return obj ? &obj->as<NativeObject>() : nullptr;
1684
62
}
1685
1686
// Defined in NativeObject-inl.h.
1687
bool IsPackedArray(JSObject* obj);
1688
1689
extern void
1690
AddPropertyTypesAfterProtoChange(JSContext* cx, NativeObject* obj, ObjectGroup* oldGroup);
1691
1692
// Specializations of 7.3.23 CopyDataProperties(...) for NativeObjects.
1693
extern bool
1694
CopyDataPropertiesNative(JSContext* cx, HandlePlainObject target, HandleNativeObject from,
1695
                         HandlePlainObject excludedItems, bool* optimized);
1696
1697
extern bool
1698
CopyDataPropertiesNative(JSContext* cx, HandlePlainObject target,
1699
                         Handle<UnboxedPlainObject*> from, HandlePlainObject excludedItems,
1700
                         bool* optimized);
1701
1702
} // namespace js
1703
1704
#endif /* vm_NativeObject_h */