From 4a71579b757d3a2eb6902c84391f429838ad4912 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Thu, 30 Jan 2020 12:33:44 -0300 Subject: git subrepo clone https://git.savannah.gnu.org/git/lightning.git deps/lightning subrepo: subdir: "deps/lightning" merged: "b0b8eb5" upstream: origin: "https://git.savannah.gnu.org/git/lightning.git" branch: "master" commit: "b0b8eb5" git-subrepo: version: "0.4.1" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "a04d8c2" --- deps/lightning/lib/jit_note.c | 414 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 deps/lightning/lib/jit_note.c (limited to 'deps/lightning/lib/jit_note.c') diff --git a/deps/lightning/lib/jit_note.c b/deps/lightning/lib/jit_note.c new file mode 100644 index 0000000..c79b818 --- /dev/null +++ b/deps/lightning/lib/jit_note.c @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include +#include + +/* + * Prototypes + */ +#define new_note(u, v) _new_note(_jit, u, v) +static jit_note_t *_new_note(jit_state_t *, jit_uint8_t*, char*); +static void new_line(jit_int32_t,jit_note_t*,char*,jit_int32_t,jit_int32_t); +#define note_search_index(u) _note_search_index(_jit, u) +static jit_int32_t _note_search_index(jit_state_t*, jit_uint8_t*); +static jit_int32_t line_insert_index(jit_note_t*,jit_int32_t); +static jit_int32_t line_search_index(jit_note_t*,jit_int32_t); +static jit_int32_t offset_insert_index(jit_line_t*,jit_int32_t); +static jit_int32_t offset_search_index(jit_line_t*,jit_int32_t); + +/* + * Implementation + */ +void +jit_init_note(void) +{ +} + +void +jit_finish_note(void) +{ +} + +jit_node_t * +_jit_name(jit_state_t *_jit, const char *name) +{ + jit_node_t *node; + + node = jit_new_node(jit_code_name); + if (name) + node->v.n = jit_data(name, strlen(name) + 1, 1); + else + node->v.p = NULL; + if (_jitc->note.head == NULL) + _jitc->note.head = _jitc->note.tail = node; + else { + _jitc->note.tail->link = node; + _jitc->note.tail = node; + } + ++_jit->note.length; + _jitc->note.size += sizeof(jit_note_t); + /* remember previous note is invalid due to name change */ + _jitc->note.note = NULL; + return (_jitc->note.name = node); +} + +jit_node_t * +_jit_note(jit_state_t *_jit, const char *name, int line) +{ + jit_node_t *node; + + node = jit_new_node(jit_code_note); + if (name) + node->v.n = jit_data(name, strlen(name) + 1, 1); + else + node->v.p = NULL; + node->w.w = line; + if (_jitc->note.head == NULL) + _jitc->note.head = _jitc->note.tail = node; + else { + _jitc->note.tail->link = node; + _jitc->note.tail = node; + } + if (_jitc->note.note == NULL || + (name == NULL && _jitc->note.note != NULL) || + (name != NULL && _jitc->note.note == NULL) || + (name != NULL && _jitc->note.note != NULL && + strcmp(name, (char *)_jitc->data.ptr + _jitc->note.note->v.n->u.w))) + _jitc->note.size += sizeof(jit_line_t); + _jitc->note.size += sizeof(jit_int32_t) * 2; + return (_jitc->note.note = node); +} + +void +_jit_annotate(jit_state_t *_jit) +{ + jit_node_t *node; + jit_note_t *note; + jit_line_t *line; + jit_word_t length; + jit_word_t note_offset; + jit_word_t line_offset; + + /* initialize pointers in mmaped data area */ + _jit->note.ptr = (jit_note_t *)_jitc->note.base; + _jit->note.length = 0; + + note = NULL; + for (node = _jitc->note.head; node; node = node->link) { + if (node->code == jit_code_name) + note = new_note(node->u.p, node->v.p ? node->v.n->u.p : NULL); + else if (node->v.p) { + if (note == NULL) + note = new_note(node->u.p, NULL); + jit_set_note(note, node->v.n->u.p, node->w.w, + (jit_uint8_t *)node->u.p - note->code); + } + } + /* last note */ + if (note) + note->size = _jit->pc.uc - note->code; + + /* annotations may be very complex with conditions to extend + * or ignore redundant notes, as well as add entries to earlier + * notes, so, relocate the information to the data buffer, + * with likely over allocated reserved space */ + + /* relocate jit_line_t objects */ + for (note_offset = 0; note_offset < _jit->note.length; note_offset++) { + note = _jit->note.ptr + note_offset; + if ((length = sizeof(jit_line_t) * note->length) == 0) + continue; + assert(_jitc->note.base + length < _jit->data.ptr + _jit->data.length); + jit_memcpy(_jitc->note.base, note->lines, length); + jit_free((jit_pointer_t *)¬e->lines); + note->lines = (jit_line_t *)_jitc->note.base; + _jitc->note.base += length; + } + + /* relocate offset and line number information */ + for (note_offset = 0; note_offset < _jit->note.length; note_offset++) { + note = _jit->note.ptr + note_offset; + for (line_offset = 0; line_offset < note->length; line_offset++) { + line = note->lines + line_offset; + length = sizeof(jit_int32_t) * line->length; + assert(_jitc->note.base + length < + _jit->data.ptr + _jit->data.length); + jit_memcpy(_jitc->note.base, line->linenos, length); + jit_free((jit_pointer_t *)&line->linenos); + line->linenos = (jit_int32_t *)_jitc->note.base; + _jitc->note.base += length; + assert(_jitc->note.base + length < + _jit->data.ptr + _jit->data.length); + jit_memcpy(_jitc->note.base, line->offsets, length); + jit_free((jit_pointer_t *)&line->offsets); + line->offsets = (jit_int32_t *)_jitc->note.base; + _jitc->note.base += length; + } + } +} + +void +_jit_set_note(jit_state_t *_jit, jit_note_t *note, + char *file, int lineno, jit_int32_t offset) +{ + jit_line_t *line; + jit_int32_t index; + + index = line_insert_index(note, offset); + if (note->length && index == note->length && + note->lines[index - 1].file == file) + --index; + if (index >= note->length || note->lines[index].file != file) + new_line(index, note, file, lineno, offset); + else { + line = note->lines + index; + index = offset_insert_index(line, offset); + if (index < line->length && line->offsets[index] == offset) { + /* common case if no code was generated for several source lines */ + if (line->linenos[index] < lineno) + line->linenos[index] = lineno; + } + else if (index < line->length && line->linenos[index] == lineno) { + /* common case of extending entry */ + if (line->offsets[index] > offset) + line->offsets[index] = offset; + } + else { + /* line or offset changed */ + if ((line->length & 15) == 0) { + jit_realloc((jit_pointer_t *)&line->linenos, + line->length * sizeof(jit_int32_t), + (line->length + 17) * sizeof(jit_int32_t)); + jit_realloc((jit_pointer_t *)&line->offsets, + line->length * sizeof(jit_int32_t), + (line->length + 17) * sizeof(jit_int32_t)); + } + if (index < note->length) { + jit_memmove(line->linenos + index + 1, line->linenos + index, + sizeof(jit_int32_t) * (line->length - index)); + jit_memmove(line->offsets + index + 1, line->offsets + index, + sizeof(jit_int32_t) * (line->length - index)); + } + line->linenos[index] = lineno; + line->offsets[index] = offset; + ++line->length; + } + } +} + +jit_bool_t +_jit_get_note(jit_state_t *_jit, jit_pointer_t code, + char **name, char **file, jit_int32_t *lineno) +{ + jit_note_t *note; + jit_line_t *line; + jit_int32_t index; + jit_int32_t offset; + + if ((index = note_search_index((jit_uint8_t *)code)) >= _jit->note.length) + return (0); + note = _jit->note.ptr + index; + if ((jit_uint8_t *)code < note->code || + (jit_uint8_t *)code >= note->code + note->size) + return (0); + offset = (jit_uint8_t *)code - note->code; + if ((index = line_search_index(note, offset)) >= note->length) + return (0); + if (index == 0 && offset < note->lines[0].offsets[0]) + return (0); + line = note->lines + index; + if ((index = offset_search_index(line, offset)) >= line->length) + return (0); + + if (name) + *name = note->name; + if (file) + *file = line->file; + if (lineno) + *lineno = line->linenos[index]; + + return (1); +} + +static jit_note_t * +_new_note(jit_state_t *_jit, jit_uint8_t *code, char *name) +{ + jit_note_t *note; + jit_note_t *prev; + + if (_jit->note.length) { + prev = _jit->note.ptr + _jit->note.length - 1; + assert(code >= prev->code); + prev->size = code - prev->code; + } + note = (jit_note_t *)_jitc->note.base; + _jitc->note.base += sizeof(jit_note_t); + ++_jit->note.length; + note->code = code; + note->name = name; + + return (note); +} + +static void +new_line(jit_int32_t index, jit_note_t *note, + char *file, jit_int32_t lineno, jit_int32_t offset) +{ + jit_line_t *line; + + if (note->lines == NULL) + jit_alloc((jit_pointer_t *)¬e->lines, 16 * sizeof(jit_line_t)); + else if ((note->length & 15) == 15) + jit_realloc((jit_pointer_t *)¬e->lines, + note->length * sizeof(jit_line_t), + (note->length + 17) * sizeof(jit_line_t)); + + if (index < note->length) + jit_memmove(note->lines + index + 1, note->lines + index, + sizeof(jit_line_t) * (note->length - index)); + line = note->lines + index; + ++note->length; + + line->file = file; + line->length = 1; + jit_alloc((jit_pointer_t *)&line->linenos, 16 * sizeof(jit_int32_t)); + line->linenos[0] = lineno; + jit_alloc((jit_pointer_t *)&line->offsets, 16 * sizeof(jit_int32_t)); + line->offsets[0] = offset; +} + +static jit_int32_t +_note_search_index(jit_state_t *_jit, jit_uint8_t *code) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_note_t *notes; + + bot = 0; + top = _jit->note.length; + notes = _jit->note.ptr; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (code < notes[index].code) + top = index; + else if (code >= notes[index].code && + code - notes[index].code < notes[index].size) + break; + else + bot = index + 1; + } + + return (index); +} + +static jit_int32_t +line_insert_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_line_t *lines; + + bot = 0; + top = note->length; + if ((lines = note->lines) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *lines[index].offsets) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +line_search_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_line_t *lines; + + bot = 0; + top = note->length; + if ((lines = note->lines) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *lines[index].offsets) + top = index; + /* offset should be already verified to be in range */ + else if (index == note->length - 1 || + (offset >= *lines[index].offsets && + offset < *lines[index + 1].offsets)) + break; + else + bot = index + 1; + } + + return (index); +} + +static jit_int32_t +offset_insert_index(jit_line_t *line, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_int32_t *offsets; + + bot = 0; + top = line->length; + offsets = line->offsets; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < offsets[index]) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +offset_search_index(jit_line_t *line, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_int32_t *offsets; + + bot = 0; + top = line->length; + offsets = line->offsets; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < offsets[index]) + top = index; + /* offset should be already verified to be in range */ + else if (index == line->length - 1 || + (offset >= offsets[index] && offset < offsets[index + 1])) + break; + else + bot = index + 1; + } + + return (index); +} -- cgit v1.2.3