]> gitweb.factorcode.org Git - factor.git/blob - vm/callbacks.cpp
Merge branch 'master' into no_literal_table
[factor.git] / vm / callbacks.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 callback_heap::callback_heap(cell size, factor_vm *parent_) :
7         seg(new segment(size,true)),
8         here(seg->start),
9         parent(parent_) {}
10
11 callback_heap::~callback_heap()
12 {
13         delete seg;
14         seg = NULL;
15 }
16
17 void factor_vm::init_callbacks(cell size)
18 {
19         callbacks = new callback_heap(size,this);
20 }
21
22 void callback_heap::update(callback *stub)
23 {
24         tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
25
26         cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
27         cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
28
29         embedded_pointer ptr(rel_class,offset + (cell)(stub + 1));
30         ptr.store_address((cell)(stub->compiled + 1));
31
32         flush_icache((cell)stub,stub->size);
33 }
34
35 callback *callback_heap::add(code_block *compiled)
36 {
37         tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
38         tagged<byte_array> insns(array_nth(code_template.untagged(),0));
39         cell size = array_capacity(insns.untagged());
40
41         cell bump = align(size,sizeof(cell)) + sizeof(callback);
42         if(here + bump > seg->end) fatal_error("Out of callback space",0);
43
44         callback *stub = (callback *)here;
45         stub->compiled = compiled;
46         memcpy(stub + 1,insns->data<void>(),size);
47
48         stub->size = align(size,sizeof(cell));
49         here += bump;
50
51         update(stub);
52
53         return stub;
54 }
55
56 void factor_vm::primitive_callback()
57 {
58         tagged<word> w(dpop());
59         w.untag_check(this);
60
61         callback *stub = callbacks->add(w->code);
62         box_alien(stub + 1);
63 }
64
65 }