After reading this document, I'm not sure whether or not the following code will make the run-time copy binaries of A internally.
f(<<>>, A) ->
A;
f(<<X:2/binary, R/binary>>, A) ->
I = binary_to_integer(X, 16),
f(R, <<A/binary, I>>).
My guess is "no", because A isn't sent nor is it deconstructed. Am I right, or did I miss something?
Your code will not result in run-time copying of the A binaries since no sharing of sub-binaries is done. If we manually unroll the sequence of append operations it looks something like
A0 = <<A/binary, SomeByte>>,
A1 = <<A0/binary, SomeByte1>>,
A2 = <<A1/binary, SomeByte2>>,
.....
An = <<An-1, SomeByteN>>.
So we are only appending to the binary resulting from the latest append operation, i.e. there is a single reference to the ProcBin that was created for A0(as described in the efficiency documentation).
Why not use bin_opt_info option ?
For your code :
[root#nimbus bin_test]# erlc +bin_opt_info a.erl
a.erl:8: Warning: OPTIMIZED: creation of sub binary delayed
For the code in https://gist.github.com/wardbekker/5673200
The output is :
[root#nimbus bin_test]# erlc +bin_opt_info test.erl
test.erl:14: Warning: OPTIMIZED: creation of sub binary delayed
[root#nimbus bin_test]# erlc +bin_opt_info test2.erl
test2.erl:8: Warning: variable 'A' is unused
test2.erl:13: Warning: OPTIMIZED: creation of sub binary delayed
Related
It seems:
Dialyzer and erlc both error when there is a user-defined attribute in a source file before -module
Shell session demonstrating:
~ cat sample.erl
-my_attr(my_value).
-module(sample).
-compile([export_all, nowarn_export_all]).
main(_) ->
ok.
~ erlc sample.erl
sample.erl:1:2: no module definition
% 1| -my_attr(my_value).
% | ^
~ dialyzer sample.erl
Checking whether the PLT /Users/mheiber/Library/Caches/erlang/.dialyzer_plt is up-to-date... yes
Proceeding with analysis...
dialyzer: Analysis failed with error:
Could not scan the following file(s):
/Users/mheiber/sample.erl:1:2: no module definition
Last messages in the log cache:
Reading files and computing callgraph...
Is the contract for order of user-defined attributes documented anywhere? Or is this a bug?
All I could find in the docs is that predefined attributes must come before function declarations:
https://www.erlang.org/doc/reference_manual/modules.html#pre-defined-module-attributes
-module(Module).
Module declaration, defining the name of the module. The name Module,
an atom, is to be same as the file name minus the extension .erl.
Otherwise code loading does not work as intended.
This attribute is to be specified first and is the only mandatory attribute.
I am trying to make a project I am working on compile with ocamlbuild, in order to avoid the use of a regular Makefile, which I find to be slightly more complicated.
Specifically, I have a syntax extension file (extend.ml), which I need to be compiled first. In a regular Makefile there would be a rule:
extend.cmo: extend.ml
$(OCAMLC) -pp "camlp5o pa_extend.cmo q_MLast.cmo" -I +camlp5 -c $<
and then, for calculating the dependencies there would be a rule like this:
depend: $(MLFILES) extend.cmo
$(OCAMLDEP) -pp "camlp5o ./extend.cmo"
Of course, the creation of any object file would require a similar rule to the one above.
My question is, how can I integrate these rules/requirements to one ocamlbuild command (if possible)?
I have tried to compile the extend.ml file first, and then use the following command:
ocamlbuild -pp "camlp5o ./extend.cmo" -I +camlp5 -use-menhir -no-hygiene Main.byte
but I don't think it's optimal in any way.
Unfortunately, I am not familiar with the use of ocamlbuild as a compilation tool, so any help will be much appreciated.
You could define two new tags, compile_extend and use_extend, that specify the expected options. In your myocamlbuild.ml file:
open Ocamlbuild_plugin
let my_flags () =
flag ["ocaml"; "pp"; "compile_extend"]
(S [A"camlp5o"; A "pa_extend.cmo"; A "q_MLast.cmo"]);
flag ["ocaml"; "pp"; "use_extend"]
(S [A"camlp5o"; A "extend.cmo"]);
(* files with the use_extend flag must depend on extend.cmo *)
dep ["ocaml"; "use_extend"] ["extend.cmo"];
()
let () =
dispatch (function
| After_rules ->
my_flags ();
| _ -> ())
Then you would have a tags file with:
"extend.cmo": compile_extend
<Main.*>: use_extend
That said, this is all bling guessing, I have not tested this setup. Could you provide a tarball with an example extend.ml file and Main.ml allowing to reproduce your situation?
Here a snippet of generated .c code from .Lex.
And the Coredump is coming at the very first Iteration
while (1) /* loops until end-of-file is reached */{
yy_cp = yy_c_buf_p;
/* Support of yytext. */
*yy_cp = yy_hold_char; // receiving coredump here
/* yy_bp points to the position in yy_ch_buf of the start of
* the current run.*/
yy_bp = yy_cp;
yy_current_state = yy_start;}
Here you can find code
I have answer of my own question. Here are some explanation of Solution
I have two .Lex (Type1_Lex.l & Type2_Lex.l)and two .Yacc (Type1_Yacc.y & Type2_Yacc.y) code
I am compiling all and relevant .c (Type1_Lex.c, Type2_Lex.c, Type1_Yacc.c & Type2_Yacc.v) and .h files are getting generated
And further compilation of .c with generates Type1_Lex.o, Type2_Lex.o, Type1_Yacc.o Type2_Yacc.o
Further I am putting all these object files in a single .a
The Problems are Here
...
ld: Warning: size of symbol `yy_create_buffer' changed from 318 in libuperbe.a(TYPE1_Lex.o) to 208 in libxxx.a (TYPE2_Lex.o)
ld: Warning: size of symbol `yy_load_buffer_state' changed from 262 in libuperbe.a(TYPE1_Lex.o) to 146 in libxxx.a(TYPE2_Lex.o)
ld: Warning: size of symbol `yy_init_buffer' changed from 278 in libuperbe.a(TYPE1_Lex.o) to 164 in libxxx.a(TYPE2_Lex.o)
Some symbols are same in both generated .c (TYPE1_Lex.c & TYPE2_Lex.c)
When both object file bind in a single .a the similar
(yy_create_buffer,yy_init_buffer,yy_load_buffer_state) symbols got
overridden.
At the runtime when the methods yy_create_buffer(),yy_init_buffer(), yy_load_buffer_state() should be called defined in TYPE2_Lex.c but in actual those methods are called from the file TYPE1_Lex.c and the leads to the memory corruption some how.
For moving ahead I decided to use sed with following patterns :
Sed TYPE2_Lex.c with :
s/yy_create_buffer()/TYPE1_create_buffer/g
s/yy_init_buffer()/TYPE1_init_buffer/g
s/yy_load_buffer_state()/TYPE1_load_buffer_state/g
Sed TYPE2_Lex.c with
s/yy_create_buffer()/TYPE2_create_buffer/g
s/yy_init_buffer()/TYPE2_init_buffer/g
s/yy_load_buffer_state()/TYPE2_load_buffer_state/g
So that the Loader can easily differentiate the symbol. And at the run time confusion between the methods name become null.
After all these Step I am able to move ahead :)
Thanks all for your help :)
I'm attempting to compile Zero29 with the --standalone compiler flag. The project itself compiles fine, but I have a unit test project that exercises some code in the Zero29 project, even though it's an executable program (.exe).
Everything works fine without the --standalone compilation flag.
However, when I add the --standalone compilation flag to the Zero29 project, the Zero29 project compiles fine, but in the unit test project, the compiler complains about this Discriminated Union defined in the Zero29 project:
namespace Ploeh.ZeroToNine
open System
open Ploeh.ZeroToNine.Versioning
type Arg =
| Assign of Version
| AssignRank of Rank * int
| Increment of Rank
| ListVersions
| ShowHelp
| Unknown of string list
The unit test project directly references the Zero29 project:
Zero29.UnitTests --references--> Zero29 (where --standalone is added)
When I attempt to compile the entire solution, the Zero29 project compiles with the --standalone flag, but then compilation of Zero29.UnitTests fails. There are several errors, but they are all the same, so here's a single example:
error FS0039: The value or constructor 'Assign' is not defined
Which points to the third line of this code:
let ParseAssignVersionReturnsCorrectResult(version : string) =
let actual = [| "-a"; version |] |> Args.Parse
verify <# [Assign(Version version)] = (actual |> Seq.toList) #>
The strange thing is that while the compiler complains about Assign in the third line of this code snippet, it doesn't complain about the use of Args.Parse, even though it's defined in the same code file as the Arg Discriminated Union.
Why does it do that, and how can I resolve this issue?
(I've attempted to distil the problem here, but the links I've provided point to the actual code files on GitHub, if more information is required.)
Libraries compiled with the --standalone switch cannot expose any F# datatypes. This is, for one, expressly stated in Pickering (2007), p. 210. In your case, a discriminated union is one of these prohibited types. The fact that the file is an executable changes nothing here: it becomes a library the moment you attempt to use it as one.
There have been also multiple reports (for example, here and here) that even libraries compiled with --standalone behave, quoting one of these sources, “funky.” It would be safe to say that the use of this switch should perhaps be limited to stand-alone executables only (and they cannot pretend to be a library even when under unit tests).
Pickering R. (2007). Foundations of F#. Apress.
I've been using fslex and fsyacc, and the F# source files (.fs they generate from the lexer (.fsl) and parser (.fsp) rules refer to the original .fsl (and sometimes to the same .fs source file) all over the place with statement such as this (numbers are line numbers):
lex.fs
1 # 1 "/[PROJECT-PATH-HERE]/lex.fsp
...
16 # 16 "/PROJECT-PATH-HERE]/lex.fs
17 // This is the type of tokens accepted by the parser
18 type token =
19 | EOF
...
Also, the .fs files generated by pars.fsp do the same kind of thing, but additionaly reference to the F# signature file (.fsi) generated alongside it. What does any of this do/mean?
The annotations you see in the generated code are F# Compiler Directives (specifically, the 'line' directive).
The 'line' directive makes it so that when the F# compiler needs to emit a warning/error message for some part of the generated code, it has a way to determine which part of the original file corresponds to that part of the generated code. In other words, the F# compiler can generate a warning/error message referencing the original code which is the basis of the generated code causing the error.