trifork / erjang

A JVM-based Erlang VM
http://www.erjang.org
Apache License 2.0
726 stars 62 forks source link

Generated code may contain references to nonexisting field EObject.elemNN #12

Closed eriksoe closed 14 years ago

eriksoe commented 14 years ago

CompilerVisitor generates such code for get_tuple_element when the argument is not statically known to be a tuple.

Modules for which such generated code has been seen: error_handler and yeccparser. The assertion assert(val.type.getInternalName().startsWith("erjang/ETuple")); is triggered if inserted in the get_tuple_element case in CompilerVisitor.

(When fixing this, please also ensure that things also go right if get_tuple_element is used to extract element N from something which is statically only known to be a tuple of size M where M<N.)

krestenkrab commented 14 years ago

Urgh; this is pretty bad. I was hoping that the surrounding logic (eg BEAM code checking conditions for a record update operation) would ensure the proper conditions.

That error should also cause a verifier error; I have not seen such ones for this case. But perhaps another erlc generates such patterns.

krestenkrab commented 14 years ago

Oops, in this instruction sequence from error_handler:check_inheritance/2; {x,1} is a tuple, but it is established by means of BIFs, not instructions. The last instruction gets tuple element 1, but X1 is only known to contain whatever is in the head of {x,0}

{get_list,{x,0},{x,1},{x,2}}.
{bif,tuple_size,{f,31},[{x,1}],{x,3}}.
{bif,element,{f,31},[{integer,1},{x,1}],{x,4}}.
{bif,element,{f,31},[{integer,2},{x,1}],{x,5}}.
{bif,tuple_size,{f,31},[{x,5}],{x,6}}.
{get_tuple_element,{x,1},1,{x,7}}.

So in this case, we will have to encode that get_tuple_element instruction as a call to erlang:element/2. Somehow erlc must know that the instruction will not fail (and it is clear to see why), but we don't really have machinery to establish the same integrity assertion.

eriksoe commented 14 years ago

I suspect the lack of a verifier error is due to fields being resolved lazily... a bit of a surprise there.

krestenkrab commented 14 years ago

I fixed the compiler, so that if type inference cannot establish that the argument to get_tuple_element is a tuple, I insert a cast. So I am closing this.