Skip to content

Commit

Permalink
Support conversion between pointers and integrals
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Feb 1, 2020
1 parent 770b265 commit 66ec117
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 12 deletions.
7 changes: 3 additions & 4 deletions lib/memory.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,9 @@ end

function memory.spanset(dest: auto, x: auto)
## check_span_subtype_match(dest, x)
if likely(dest.size > 0_u) then
for i:usize=0,<dest.size do
dest[i] = x
end
local T: type = #[x.type]#
for i:usize=0,<dest.size do
memcpy(&dest[i], &x, #T)
end
end

Expand Down
10 changes: 8 additions & 2 deletions nelua/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,12 @@ end
function IntegralType:is_convertible_from_type(type, explicit)
if type:is_integral() and self:is_inrange(type.min) and self:is_inrange(type.max) then
return true
elseif explicit and type:is_arithmetic() then
return true
elseif explicit then
if type:is_arithmetic() then
return true
elseif type:is_pointer() and self.size == cpusize then
return true
end
end
return ArithmeticType.is_convertible_from_type(self, type, explicit)
end
Expand Down Expand Up @@ -1255,6 +1259,8 @@ function PointerType:is_convertible_from_type(type, explicit)
return true
elseif type:is_nilptr() then
return true
elseif explicit and type:is_integral() and type.size == cpusize then
return true
end
return Type.is_convertible_from_type(self, type, explicit)
end
Expand Down
4 changes: 2 additions & 2 deletions runtime/c/nelua_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,11 @@ static void nelua_gc_mark_ptr(nelua_gc_t *gc, void *ptr) {
if (ptr == gc->items[i].ptr) {
if (gc->items[i].flags & Nelua_GC_MARK) { return; }
gc->items[i].flags |= Nelua_GC_MARK;
if (gc->items[i].flags & Nelua_GC_LEAF) { return; }
if (gc->items[i].flags & Nelua_GC_LEAF) { continue; }
for (k = 0; k < gc->items[i].size/sizeof(void*); k++) {
nelua_gc_mark_ptr(gc, ((void**)gc->items[i].ptr)[k]);
}
return;
continue;
}
i = (i+1) % gc->nslots; j++;
}
Expand Down
13 changes: 13 additions & 0 deletions spec/03-typechecker_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,11 @@ it("pointers", function()
b = nilptr
a = nilptr
]])
assert.analyze_ast([[
local x: usize = 1
local p: pointer = (@pointer)(x)
x = (@usize)(p)
]])
assert.ast_type_equals(
"local a = (@pointer)(nilptr) a = nilptr",
"local a: pointer = (@pointer)(nilptr) a = nilptr")
Expand Down Expand Up @@ -1070,6 +1075,14 @@ it("pointers", function()
local b: pointer(cchar)
b = a
]])
assert.analyze_error([[
local x: byte = 1
local p: pointer = (@pointer)(x)
]], "no viable type conversion")
assert.analyze_error([[
local p: pointer
local x: byte = (@byte)(p)
]], "no viable type conversion")
assert.analyze_error([[
local a: pointer(integer)
local b: pointer(boolean)
Expand Down
22 changes: 18 additions & 4 deletions spec/05-cgenerator_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1276,13 +1276,27 @@ it("pointers", function()
local function f(a: pointer): pointer return a end
local i: integer = 1
local p: pointer(integer) = &i
print($p)
assert($p == 1)
p = (@pointer(int64))(f(p))
i = 2
print($p)
assert($p == 2)
$p = 3
print(i)
]], "1\n2\n3")
assert(i == 3)
do
local x: usize = 0xffffffff
local p: pointer = (@pointer)(x)
x = (@usize)(p)
assert(x == 0xffffffff)
end
do
local x: isize = -1
local p: pointer = (@pointer)(x)
x = (@isize)(p)
assert(x == -1)
end
]])
end)

it("function pointers", function()
Expand Down
6 changes: 6 additions & 0 deletions tests/memory_test.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,21 @@ end
do -- spancompare
local pa = memory.spanalloc0(@vec2, 1)
local pb = memory.spanalloc0(@vec2, 1)
local pc = memory.spanalloc0(@vec2, 0)
assert(memory.spancompare(pa, pb) == 0)
pa[0].x = 1 pb[0].x = 2
assert(memory.spancompare(pa, pb) == -1)
assert(memory.spancompare(pb, pa) == 1)
pa[0].x = 2 pb[0].x = 1
assert(memory.spancompare(pa, pb) == 1)
assert(memory.spancompare(pb, pa) == -1)
pa[0].x = 2 pb[0].x = 2
assert(memory.spancompare(pa, pb) == 0)
assert(memory.spancompare(pa, pc) == 1)
assert(memory.spancompare(pc, pa) == -1)
memory.spandealloc(pa)
memory.spandealloc(pb)
memory.spandealloc(pc)
end

do -- spanequals
Expand Down

0 comments on commit 66ec117

Please sign in to comment.