-
Notifications
You must be signed in to change notification settings - Fork 9
/
Preloader.cr
79 lines (66 loc) · 2.78 KB
/
Preloader.cr
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
module Anyolite
module Preloader
@@content = {} of String => Array(UInt8)
module AtCompiletime
# Caches the bytecode from *filename*, so it is automatically included
# into the final application.
macro load_bytecode_file(filename)
{% file_content = read_file?(filename) %}
{% if file_content %}
Anyolite::Preloader.add_content({{filename}}, {{file_content}}.bytes)
{% else %}
puts "Could not find #{filename}"
{% end %}
end
# Caches the Ruby script in *filename* directly as bytecode.
macro load_bytecode_array_from_file(filename)
{% ary = run("./BytecodeGetter.cr", filename) %}
Anyolite::Preloader.add_content({{filename}}, {{ary}}.map(&.to_u8))
end
# Converts the Ruby script in *filename* to bytecode, which is
# then stored in *target_filename*.
macro transform_script_to_bytecode(filename, target_filename)
{% run("./BytecodeCompiler.cr", filename, target_filename) %}
end
# Converts the Ruby script in *filename* to bytecode.
macro transform_script_to_bytecode_string(filename)
{% run("./BytecodeGetter.cr", filename) %}
end
end
# Caches the bytecode file *filename*
def self.add_content(filename : String, bytes : Array(UInt8))
@@content[filename] = bytes
end
# Executes the bytecode file *filename* in context of the `RbInterpreter` *rb*.
#
# If it was already cached, it will be taken from the cache instead.
def self.execute_bytecode_from_cache_or_file(rb : RbInterpreter, filename : String)
if @@content[filename]?
rb.execute_bytecode(@@content[filename])
else
rb.load_bytecode_from_file(filename)
end
end
# Converts the Ruby script in *filename* to bytecode, which is
# then stored in *target_filename*.
def self.transform_script_to_bytecode(filename : String, target_filename : String)
error_code = RbCore.transform_script_to_bytecode(filename, target_filename)
case error_code
when 1 then raise "Could not load script file #{filename}"
when 2 then raise "Error when loading script file #{filename}"
when 3 then raise "Could not write to target file #{target_filename}"
end
end
# Converts the Ruby script in *filename* to bytecode.
def self.transform_script_to_bytecode_array(filename : String)
container = RbCore.transform_script_to_bytecode_container(filename)
case container.error_code
when 1 then raise "Could not load script file #{filename}"
when 2 then raise "Error when loading script file #{filename}"
end
safe_result = String.new(container.content, container.size)
RbCore.free_bytecode_container(container)
safe_result.bytes
end
end
end