-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpz_code.cpp
94 lines (80 loc) · 2.38 KB
/
pz_code.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
* Plasma bytecode code structures and functions
* vim: ts=4 sw=4 et
*
* Copyright (C) Plasma Team
* Distributed under the terms of the MIT license, see ../LICENSE.code
*/
#include "pz_common.h"
#include "pz_code.h"
#include "pz_gc.h"
namespace pz {
Proc::Proc(NoGCScope & gc_cap, String name, bool is_builtin,
unsigned size)
: m_code_size(size)
, m_name(name)
, m_is_builtin(is_builtin)
, m_contexts(gc_cap, 0)
{
m_code = (uint8_t *)gc_cap.alloc_bytes(size, META);
heap_set_meta_info(&gc_cap.heap(), code(), this);
}
void Proc::add_context(GCCapability & gc_cap, unsigned offset,
String filename, unsigned line)
{
if (m_filename.hasValue()) {
assert(m_filename.value().equals(filename));
} else {
m_filename.set(filename);
}
set_context(gc_cap, offset, line);
}
void Proc::add_context(GCCapability & gc_cap, unsigned offset, unsigned line)
{
assert(m_filename.hasValue());
set_context(gc_cap, offset, line);
}
void Proc::no_context(GCCapability & gc_cap, unsigned offset)
{
set_context(gc_cap, offset, 0);
}
void Proc::set_context(GCCapability & gc_cap, unsigned offset, unsigned value)
{
bool res = m_contexts.append(gc_cap, OffsetContext(offset, value));
// We expect the return code to be true unless GCCapability is a
// NoGCScope, and it probably isn't.
if (!res) {
assert(res);
}
// Check that this isn't a NoGCScope so we know to fix the above
// assumption if that changes.
assert(gc_cap.can_gc());
}
unsigned Proc::line(unsigned offset, unsigned * last_lookup) const
{
unsigned start;
if (*last_lookup == 0 || m_contexts[*last_lookup - 1].offset > offset) {
start = 0;
} else {
start = *last_lookup - 1;
}
/*
* The loop condition is such that i and i+1 are both within the bounds
* of m_contexts.
*/
for (unsigned i = start; i + 1 < m_contexts.size(); i++) {
// If the current offset is between this and the next.
if ((m_contexts[i].offset <= offset) &&
(m_contexts[i+1].offset > offset))
{
*last_lookup = i;
return m_contexts[i].line;
}
}
if (m_contexts.size() > 0 && m_contexts.back().offset <= offset) {
*last_lookup = m_contexts.size() - 1;
return m_contexts.back().line;
}
return 0;
}
} // namespace pz