]> gitweb.factorcode.org Git - factor.git/blob - vm/callbacks.cpp
Merge branch 'master' of git://factorcode.org/git/factor
[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         parent->store_address_in_code_block(rel_class,
30                 (cell)(stub + 1) + offset,
31                 (cell)(stub->compiled + 1));
32
33         flush_icache((cell)stub,stub->size);
34 }
35
36 callback *callback_heap::add(code_block *compiled)
37 {
38         tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
39         tagged<byte_array> insns(array_nth(code_template.untagged(),0));
40         cell size = array_capacity(insns.untagged());
41
42         cell bump = align(size,sizeof(cell)) + sizeof(callback);
43         if(here + bump > seg->end) fatal_error("Out of callback space",0);
44
45         callback *stub = (callback *)here;
46         stub->compiled = compiled;
47         memcpy(stub + 1,insns->data<void>(),size);
48
49         stub->size = align(size,sizeof(cell));
50         here += bump;
51
52         update(stub);
53
54         return stub;
55 }
56
57 void factor_vm::primitive_callback()
58 {
59         tagged<word> w(dpop());
60         w.untag_check(this);
61
62         callback *stub = callbacks->add(w->code);
63         box_alien(stub + 1);
64 }
65
66 }