~davbo/ubuntu/trusty/jq/merge-debian-changes

« back to all changes in this revision

Viewing changes to frame_layout.h

  • Committer: David King
  • Date: 2017-04-12 15:47:07 UTC
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: dave@davbo.org-20170412154707-qq74qifqttlcqb3r
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifndef FRAME_LAYOUT_H
2
 
#include "forkable_stack.h"
3
 
#include "bytecode.h"
4
 
 
5
 
struct closure {
6
 
  struct bytecode* bc;
7
 
  stack_idx env;
8
 
};
9
 
 
10
 
struct continuation {
11
 
  struct bytecode* bc;
12
 
  stack_idx env;
13
 
  uint16_t* retaddr;
14
 
};
15
 
 
16
 
typedef union frame_elem {
17
 
  FORKABLE_STACK_HEADER;
18
 
  struct continuation cont;
19
 
  struct closure closure;
20
 
  jv jsonval;
21
 
} *frame_ptr;
22
 
 
23
 
/*
24
 
 * Frame layout
25
 
 * fr[0] - FORKABLE_STACK_HEADER (next pointer)
26
 
 * fr[1] - self (used to store return addresses, etc)
27
 
 * fr[2...nclosures+2] - closure params
28
 
 * fr[nclosures+2..nclosures+nlocals+2] - local variables
29
 
 */
30
 
 
31
 
static int frame_size(struct bytecode* bc) {
32
 
  return sizeof(union frame_elem) * (bc->nclosures + bc->nlocals + 2);
33
 
}
34
 
 
35
 
static struct continuation* frame_self(frame_ptr fr) {
36
 
  return &fr[1].cont;
37
 
}
38
 
 
39
 
static struct closure* frame_closure_arg(frame_ptr fr, int closure) {
40
 
  assert(closure >= 0);
41
 
  assert(closure < frame_self(fr)->bc->nclosures);
42
 
  return &fr[2+closure].closure;
43
 
}
44
 
 
45
 
static jv* frame_local_var(frame_ptr fr, int var) {
46
 
  assert(var >= 0);
47
 
  assert(var < frame_self(fr)->bc->nlocals);
48
 
  return &fr[2 + frame_self(fr)->bc->nclosures + var].jsonval;
49
 
}
50
 
 
51
 
 
52
 
static frame_ptr frame_current(struct forkable_stack* stk) {
53
 
  frame_ptr fp = forkable_stack_peek(stk);
54
 
  if (forkable_stack_peek_next(stk, fp)) {
55
 
    struct bytecode* bc = frame_self(forkable_stack_peek_next(stk, fp))->bc;
56
 
    assert(frame_self(fp)->retaddr >= bc->code && frame_self(fp)->retaddr < bc->code + bc->codelen);
57
 
  } else {
58
 
    assert(frame_self(fp)->retaddr == 0);
59
 
  }
60
 
  return fp;
61
 
}
62
 
 
63
 
static struct bytecode* frame_current_bytecode(struct forkable_stack* stk) {
64
 
  return frame_self(frame_current(stk))->bc;
65
 
}
66
 
static uint16_t** frame_current_retaddr(struct forkable_stack* stk) {
67
 
  return &frame_self(frame_current(stk))->retaddr;
68
 
}
69
 
 
70
 
static frame_ptr frame_get_parent(struct forkable_stack* stk, frame_ptr fr) {
71
 
  return forkable_stack_from_idx(stk, frame_self(fr)->env);
72
 
}
73
 
 
74
 
static frame_ptr frame_get_level(struct forkable_stack* stk, frame_ptr fr, int level) {
75
 
  for (int i=0; i<level; i++) {
76
 
    fr = frame_get_parent(stk, fr);
77
 
  }
78
 
  return fr;
79
 
}
80
 
 
81
 
static frame_ptr frame_push(struct forkable_stack* stk, struct closure cl, uint16_t* retaddr) {
82
 
  frame_ptr fp = forkable_stack_push(stk, frame_size(cl.bc));
83
 
  struct continuation* cc = frame_self(fp);
84
 
  cc->bc = cl.bc;
85
 
  cc->env = cl.env;
86
 
  cc->retaddr = retaddr;
87
 
  for (int i=0; i<cl.bc->nlocals; i++) {
88
 
    *frame_local_var(fp, i) = jv_invalid();
89
 
  }
90
 
  return fp;
91
 
}
92
 
 
93
 
static void frame_pop(struct forkable_stack* stk) {
94
 
  frame_ptr fp = frame_current(stk);
95
 
  if (forkable_stack_pop_will_free(stk)) {
96
 
    int nlocals = frame_self(fp)->bc->nlocals;
97
 
    for (int i=0; i<nlocals; i++) {
98
 
      jv_free(*frame_local_var(fp, i));
99
 
    }
100
 
  }
101
 
  forkable_stack_pop(stk);
102
 
}
103
 
 
104
 
#endif