Skip to content

Commit

Permalink
Auto detect unitname for Nelua lib, deprecate field pragmas, move GC
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Feb 15, 2020
1 parent cb017d3 commit 1e428c9
Show file tree
Hide file tree
Showing 23 changed files with 81 additions and 158 deletions.
2 changes: 1 addition & 1 deletion docs/pages/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ Memory can be allocated using C malloc and free.

```nelua
require 'memory'
require 'allocators.generic_allocator'
require 'allocators.generic'
local Person = @record{name: string, age: integer}
local p: Person* = generic_allocator.new(@Person)
Expand Down
2 changes: 1 addition & 1 deletion examples/linkedlist.nelua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'memory'
require 'allocators.generic_allocator'
require 'allocators.generic'

local allocator = @generic_allocator

Expand Down
2 changes: 1 addition & 1 deletion examples/overview.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ do -- Dereferencing and referencing
end

require 'memory'
require 'allocators.generic_allocator'
require 'allocators.generic'

do -- Allocating memory
local Person = @record{name: string, age: integer}
Expand Down
82 changes: 40 additions & 42 deletions lib/gc.nelua → lib/allocators/gc.nelua
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
-- Tiny and simple mark and sweep garbage collector
-- Implementation based on https://github.com/orangeduck/tgc

## unitname = 'nelua'
## cinclude '<setjmp.h>'

require 'memory'
require 'allocators.generic_allocator'
require 'allocators.generic'

local jmp_buf <cimport,nodecl> = @record{dummy: usize}
local function setjmp(env: jmp_buf) <cimport,nodecl> end
Expand Down Expand Up @@ -335,14 +334,13 @@ function GC:_sweep() <noinline>
self.nitems = self.nitems - 1
end

self:_unmark_all()
self:_resize_less()

self.mitems = self.nitems + (@usize)(self.nitems * self.sweepfactor) + 1

for j:usize=0,<self.nfrees do
if self.frees[j].ptr then
if self.frees[j].finalizer then
if self.frees[j].finalizer then
--self.frees[j].finalizer(self.frees[j].ptr)
end
allocator.dealloc(self.frees[j].ptr)
Expand Down Expand Up @@ -492,44 +490,6 @@ function GC:dealloc(ptr: pointer)
end
end

function GC:set_finalizer(ptr: pointer, finalizer: FinalizerPtr)
local p: GCItem* = self:_get_ptr(ptr)
if p then
p.finalizer = finalizer
end
end

function GC:set_flags(ptr: pointer, flags: usize)
local p: GCItem* = self:_get_ptr(ptr)
if p then
p.flags = flags
end
end

function GC:get_flags(ptr: pointer): usize
local p: GCItem* = self:_get_ptr(ptr)
if p then
return p.flags
end
return 0
end

function GC:get_finalizer(ptr: pointer): FinalizerPtr
local p: GCItem* = self:_get_ptr(ptr)
if p then
return p.finalizer
end
return nilptr
end

function GC:get_size(ptr: pointer): usize
local p: GCItem* = self:_get_ptr(ptr)
if p then
return p.size
end
return 0
end

function GC:_mark_statics()
## local emit_mark_static = hygienize(function(sym, symtype)
gc:add(&#[sym]#, #[symtype.size]#, GCFlags.ROOT, nilptr)
Expand Down Expand Up @@ -563,3 +523,41 @@ local function main(argc: cint, argv: cchar**): cint <entrypoint>
gc:stop()
return ret
end

require 'allocators.interface'

global gc_allocator = @record{}

function gc_allocator.alloc(size: usize): pointer
check(size > 0_u, 'gc_allocator.alloc: size cannot be zero')
local p: pointer = gc:alloc(size)
check(p, 'gc_allocator.alloc: allocation fail')
return p
end

function gc_allocator.alloc0(size: usize): pointer
check(size > 0_u, 'gc_allocator.alloc0: size must be greater than 0')
local p: pointer = gc:alloc0(size)
check(p, 'gc_allocator.alloc0: allocation fail')
return p
end

function gc_allocator.realloc(p: pointer, size: usize): pointer
check(size > 0_u, 'gc_allocator.realloc: size must be greater than 0')
p = gc:realloc(p, size)
check(size == 0 or p, 'gc_allocator.realloc: allocation fail')
return p
end

function gc_allocator.realloc0(p: pointer, newsize: usize, oldsize: usize): pointer
check(newsize > 0_u, 'gc_allocator.realloc0: size must be greater than 0')
p = gc:realloc0(p, newsize, oldsize)
check(newsize == 0_u or p, 'gc_allocator.realloc0: allocation fail')
return p
end

function gc_allocator.dealloc(p: pointer)
gc:dealloc(p)
end

## implement_allocator_interface(gc_allocator)
40 changes: 0 additions & 40 deletions lib/allocators/gc_allocator.nelua

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
## unitname = 'nelua'

require 'allocators.allocator_interface'
require 'allocators.interface'

local function memset(s: pointer, c: cint, n: csize): pointer <cimport'memset',cinclude'<string.h>',nodecl> end
local function malloc(size: csize): pointer <cimport'malloc',cinclude'<stdlib.h>',nodecl> end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
##[[
unitname = 'nelua'
--------------------------------------------------------------------------------
-- compile time checks utilities
local function check_span_subtype(v)
Expand Down
2 changes: 0 additions & 2 deletions lib/io.nelua
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## unitname = 'nelua'

--TODO: optional arguments/returns

--------------------------------------------------------------------------------
Expand Down
2 changes: 0 additions & 2 deletions lib/math.nelua
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## unitname = 'nelua'

global math = @record{}

-- constants
Expand Down
2 changes: 0 additions & 2 deletions lib/memory.nelua
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
##[[
unitname = 'nelua'
--------------------------------------------------------------------------------
-- compile time checks utilities
local function check_span_subtype(v)
Expand Down
4 changes: 1 addition & 3 deletions lib/os.nelua
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## unitname = 'nelua'

--TODO: optional params/returns

--------------------------------------------------------------------------------
Expand Down Expand Up @@ -55,7 +53,7 @@ end

function os.date(): string
--TODO: implement os date
return 'NIY (not implementet yet)'
return 'NIY (not implemented yet)'
end

function os.difftime(t1: integer, t2: integer): integer
Expand Down
7 changes: 2 additions & 5 deletions lib/sequence.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@
-- By default its use the garbage collector unless explicitly told not to do so,
-- thus by default there is no need to manually reset the sequence.


## unitname = 'nelua'

require 'memory'

## local make_sequence = generalize(function(T, allocator)
## staticassert(traits.is_type(T), "invalid type '%s'", T)
## local codenameprefix = 'nelua_sequence_'..T.name
## local codenameprefix = 'sequence_'..T.name
## if allocator then
local allocator: type = #[allocator]#
## codenameprefix = codenameprefix..'_'..allocator.nick
## else
require 'allocators.gc_allocator'
require 'allocators.gc'
local allocator: type = @gc_allocator
## end

Expand Down
16 changes: 11 additions & 5 deletions nelua/builtins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,27 @@ function builtins.require(context, node)
end
end

local unitname = argnode.attr.value
attr.unitname = pegger.filename_to_unitname(unitname)

-- load it and parse
local filepath = fs.findmodulefile(unitname, config.path)
local unitpath = argnode.attr.value
local filepath = fs.findmodulefile(unitpath, config.path)
if not filepath then
if canloadatruntime then
-- maybe it would succeed at runtime
attr.runtime_require = true
return
else
node:raisef("in require: module '%s' not found", unitname)
node:raisef("in require: module '%s' not found", unitpath)
end
end

-- nelua internal libs have unit name of just 'nelua'
local unitname = pegger.filename_to_unitname(unitpath)
local nelualibpath = fs.join(config.data_path, 'lib')
if filepath:find(nelualibpath, 1, true) then
unitname = 'nelua'
end
attr.unitname = unitname

local reqnode = context.requires[filepath]
if reqnode and reqnode ~= node then
-- already required
Expand Down
3 changes: 0 additions & 3 deletions nelua/cgenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ local traits = require 'nelua.utils.traits'
local errorer = require 'nelua.utils.errorer'
local stringer = require 'nelua.utils.stringer'
local tabler = require 'nelua.utils.tabler'
local fs = require 'nelua.utils.fs'
local config = require 'nelua.configer'.get()
local cdefs = require 'nelua.cdefs'
local cbuiltins = require 'nelua.cbuiltins'
local typedefs = require 'nelua.typedefs'
Expand Down Expand Up @@ -1151,7 +1149,6 @@ end

function generator.generate(ast, context)
CContext.promote_context(context, visitors, typevisitors)
context.runtime_path = fs.join(config.runtime_path, 'c')

emit_main(ast, context)

Expand Down
16 changes: 6 additions & 10 deletions nelua/configer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,8 @@ local function create_parser(argv)
return argparser
end

local function get_runtime_path(arg0)
return fs.join(fs.getdatapath(arg0), 'runtime')
end

local function get_path(arg0)
local libdir = fs.join(fs.getdatapath(arg0), 'lib')
local function get_path(data_path)
local libdir = fs.join(data_path, 'lib')
return
fs.join(libdir,'?.nelua')..';'..
fs.join(libdir,'?','init.nelua')..';'..
Expand All @@ -84,8 +80,8 @@ function configer.parse(args)
local argparser = create_parser(tabler.copy(args))
local ok, options = argparser:pparse(args)
except.assertraise(ok, options)
config.runtime_path = get_runtime_path(args[0])
config.path = get_path(args[0])
config.data_path = fs.getdatapath(args[0])
config.path = get_path(config.data_path)
metamagic.setmetaindex(options, defconfig)
metamagic.setmetaindex(config, options, true)
return config
Expand All @@ -96,8 +92,8 @@ function configer.get()
end

local function init_default_configs()
defconfig.path = get_path()
defconfig.runtime_path = get_runtime_path()
defconfig.data_path = fs.getdatapath()
defconfig.path = get_path(defconfig.data_path)
defconfig.cc = get_cc()
defconfig.cflags = os.getenv('CFLAGS') or ''
metamagic.setmetaindex(config, defconfig)
Expand Down
12 changes: 1 addition & 11 deletions nelua/preprocessor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ function preprocessor.preprocess(context, ast)
local symbol = ppcontext.context.scope.symbols[key]
if symbol then
return symbol
elseif typedefs.field_pragmas[key] then
return context.pragmas[key]
elseif typedefs.call_pragmas[key] then
return function(...)
local args = tabler.pack(...)
Expand All @@ -242,15 +240,7 @@ function preprocessor.preprocess(context, ast)
return nil
end
end, __newindex = function(_, key, value)
if typedefs.field_pragmas[key] then
local ok, err = typedefs.field_pragmas[key](value)
if not ok then
raise_preprocess_error("invalid type for preprocess variable '%s': %s", key, err)
end
context.pragmas[key] = value
else
rawset(ppcontext.context.env, key, value)
end
rawset(ppcontext.context.env, key, value)
end})

-- try to run the preprocess otherwise capture and show the error
Expand Down
7 changes: 0 additions & 7 deletions nelua/typedefs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,6 @@ typedefs.call_pragmas = {
afterinfer = shaper.shape{n=shaper.number, shaper.func},
}

typedefs.field_pragmas = {
noinit = shaper.boolean,
nostatic = shaper.boolean,
nofloatsuffix = shaper.boolean,
unitname = shaper.string:is_optional(),
}

local common_annots = {
cimport = shaper.shape{shaper.string:is_optional()},
onestring = shaper.shape{shaper.string},
Expand Down
3 changes: 2 additions & 1 deletion nelua/utils/fs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ function fs.getdatapath(arg0)
path = fs.join(fs.getpathdir(path), 'conf')
end
else --luacov:enable
path = fs.getpathdir(fs.getpathdir(fs.getpathdir(fs.abspath(debug.getinfo(1).short_src))))
local thispath = debug.getinfo(1).short_src
path = fs.getpathdir(fs.getpathdir(fs.getpathdir(fs.abspath(thispath))))
end
return path
end
Expand Down
Loading

0 comments on commit 1e428c9

Please sign in to comment.