GNU make: expansion of a deferred construct - gnu-make

On this site containing the documentation describing how make reads a Makefile, there is the following paragraph:
[...]
It’s important to understand this two-phase approach because it has a direct impact on how variable and function expansion happens; this is often a source of some confusion when writing makefiles. Here we will present a summary of the phases in which expansion happens for different constructs within the makefile. We say that expansion is immediate if it happens during the first phase: in this case make will expand any variables or functions in that section of a construct as the makefile is parsed. We say that expansion is deferred if expansion is not performed immediately. Expansion of a deferred construct is not performed until either the construct appears later in an immediate context, or until the second phase.
[...]
I do not know what the highlighted part means.
Does it try to say that if there is a variable reference first found in a deferred section it will not be expanded during the first phase, but if the same variable reference is then found (later in the Makefile) in an immediate context, that variable reference will be expanded? Why would it say this explicitly?
Or does it try to say that there are cases when the exact same line can be read within a different context?

I do not know what the highlighted part means.
Does it try to say that if there is a variable reference first found
in a deferred section it will not be expanded during the first phase,
but if the same variable reference is then found (later in the
Makefile) in an immediate context, that variable reference will be
expanded?
Something like this, but I hesitate to say "yes" because I'm not sure I fully understand you. Instead, I put it in my own words: the manual says that an expression with a deferred expansion is expanded immediately when it is evaluated as part of the value of an expression that is immediately expanded. Example:
INTRO := The messages are
DEFERRED = $(MESSAGE1) literal message
IMMEDIATE := $(INTRO) $(DEFERRED)
MESSAGE1 = deferred message,
demo:
#echo immediate: "$(IMMEDIATE)"
#echo deferred: "$(INTRO) $(DEFERRED)"
Demo:
$ make demo
immediate: The messages are literal message
deferred: The messages are deferred message, literal message
$
Note that variable DEFERRED is expanded immediately as part of the process of setting the value of immediately-expanded variable IMMEDIATE. You can see this from the difference in the output of the two echo commands. You can also see that this expansion does not stick to DEFERRED, which is one of the things that can be confusing.
Why would it say this explicitly?
Because one might suppose otherwise. Specifically, one might suppose that building the "demo" target in the example above would cause two identical lines to be printed. That would require a deferred expansion of DEFERRED being somehow symbolically encoded into the immediate expansion of IMMEDIATE, or else that DEFERRED be somehow converted into an immediately-expanded variable. Nothing along those lines happens.
Note, too, that the two expansions of DEFERRED are different in this case, which is not necessarily a possibility that is immediately evident.
Or does it try to say that there are cases when the exact same line
can be read within a different context?
Inasmuch as I differentiate between identical and exact same, the only way "the exact same" line can be evaluated in different contexts is if it is part of the expansion of a deferred-expansion expression. Then it can appear in both immediate and deferred context, as the text $(MESSAGE1) literal message in the example does. In that sense, yes, the manual is talking about that; it's not different from your other alternative.
It is also possible for distinct but identical text to appear in different contexts, but this is not as interesting.

Related

How do I do jumps to a label in an enclosing function in LLVM IR?

I want to do an LLVM compiler for a very old language, PL/M. This has some peculiar features, not least of which is having nested functions with the ability to jump out of an enclosing function. In pseudocode:
toplevel() {
nested() {
if (something)
goto label;
}
nested();
label:
print("finished!");
}
The constraints here are:
you can only jump into the top-level function, luckily
the stack does get unwound (the language does not support destructors, so this is easy)
you do not have to have executed the statement at label before jumping (so the naive setjmp/longjmp method doesn't work).
code at label can be executed normally, i.e. it's not like catch
LLVM has a number of non-local jump mechanisms, such as the exception handling system, but I've never used that. Can this be implemented using LLVM exceptions, or are they not suitable for this? Is there an easier way?
If you want the stack to get unwound, you'll likely want it to be in a separate function, at least a separate LLVM IR function. (The only real exception is if your language does not have a construct like C's "alloca()" and you don't allow calling a nested function by address in which case you could inline it.)
That part of the problem you mentioned, jumping out of an enclosing function, is best handled by having some way for the callee to communicate "how it exited" to the caller, and the caller having a "switch()" on that value. You could stick it in the return value (if it already returns a value, make it a struct of both values), you could add a pointer parameter that it writes to, you could add it a thread-local global variable and fill that in before calling longjmp, or you could use exceptions.
Exceptions, they're complex (I can't describe how to make them work offhand but the docs are here: https://llvm.org/docs/ExceptionHandling.html ) and slow when the exception path is taken, and really intended for exceptional situations, not for normal code. Setjmp/longjmp does the same thing as exceptions except simpler to use and without the performance trade-off when executed, but unfortunately there are miscompiles in LLVM which you need will be the one to fix if you start using them in earnest (see the postscript at the end of the answer).
Those two options cover the ways you can do it without changing the function signature, which may be necessary if your language allows the address to be taken then called later.
If you do need to take the address of nested, then LLVM supports trampolines. See https://llvm.org/docs/LangRef.html#trampoline-intrinsics . Trampolines solve the problem of accessing the local variables of the calling function from the callee, even when the function is called by address.
PS. LLVM miscompiles setjmp/longjmp today. The current model is that a call to setjmp may return twice, and only functions with the returns_twice attribute may return twice. Note that this doesn't affect the whole call stack, only the direct caller of a function that returns twice has to deal with the twice-returning call-- just because function F calls setjmp does not mean that F itself can return twice. So far, so good.
The problem is that in a function with a setjmp, all function calls may themselves call longjmp. I'd say "unless proven otherwise" as with all things in optimizers, but there is no attribute in LLVM doesnotlongjmp or any code within LLVM that attempts to answer the question of whether a function could call longjmp. Adding that would be a good optimization, but it's a separate issue from the miscompile.
If you have code like this pseudo-code:
%entry block:
allocate val
val <- 0
setjmpret <- call setjmp
br i1 setjmpret, %first setjmp return block, %second setjmp return block
%first setjmp return block:
val <- 1;
call foo();
goto after;
%second setjmp return block:
call print(val);
goto after;
%after:
return
The control flow graph shows that is no path from val <- 0 to val <- 1 to print(val). The only path with "print(val)" has "val <- 0" before it therefore constant propagation may turn print(val) into print(0). The problem here is a missing control flow edge from foo() back to the %second setjmp return block. In a function that contains a setjmp, all calls which may call longjmp must have a CFG edge to the second setjmp return block. In LLVM that control flow edge is missing and LLVM miscompiles code because of it.
This problem also manifests in the backend. The first time I heard of this problem it was in the context of the backend losing track of the placement of variables on the stack, and this issue was the underlying root cause.
For the most part setjmp/longjmp seems to work because LLVM isn't usually able to analyze what calling foo() might do and can't perform the optimization. For instance if val was not a fresh allocation but was a pointer, then who's to say that foo() doesn't have access to the same pointer, and then performs "val <- 1" on it? If LLVM can't prove that impossible, that precludes the transform to print(0). Secondly, setjmp/longjmp are just not used often in real code.

Why do we use [1] behind an order by clause in xquery expressions?

SELECT xText.query (' let $planes := /planes/plane
return <results>
{
for $x in $planes
where $x/year >= 1970
order by ($x/year)[1]
return ($x/make, $x/model,$x/year )
}
</results>
')
FROM planes
In this code, what is the purpose of [1] in line order by ($x/year)[1]
I have tried to execute this code without using [1] behind order by clause. Then this error has occurred.
XQuery [planes.xtext.query()]: 'order by' requires a singleton (or empty sequence), found operand of type 'xtd:untypedAtomic*'
XQuery 1.0 defined an option called "static type checking": if this option is in force, you need to write queries in such a way that the compiler can tell in advance ("statically") that the result will not be a type error. The operand of "order by" needs to be a singleton, and with static type checking in force, the compiler needs to be able to verify that it will be a singleton, which is why the [1] has been added. It would have been better to write exactly-one($x/year) because this doesn't only keep the compiler happy, it also demands a run-time check that $x/year is actually a singleton.
Very few XQuery vendors chose to implement static type checking, for very good reasons in my view: it makes queries harder to write, and it actually encourages you to write things like this example that do LESS checking than a system without this "feature".
In fact, as far as I know the only mainstream (non-academic) implementation that does static type checking is Microsoft's SQL Server.
Static type checking should not be confused with optimistic type checking where the compiler tells you about things that are bound to fail, but defers checking until run-time for things that might or might not be correct.
Actually the above is a bit of a guess. It's also possible that some <plane> elements have more than one child called <year>, and that you want to sort on the first of these. That would justify the [1] even on products that don't do static type checking.
The [1] is a predicate that is selecting the first item in the sequence. It is equivalent to the expression [position() = 1]. A predicate in XPath acts kind of like a WHERE clause in SQL. The filter is applied, and anything that returns true is selected, the things that return false are not.
When you don't apply the predicate, you get the error. That error is saying that the order by expects a single item, or nothing (an empty sequence).
At least one of the plane has multiple year, so the predicate ensures that only the first one is used for the order by expression.

Why window.getComputedStyle in Flow returns `any` type?

According to MDN getComputedStyle(element) returns CSSStyleDeclaration object. But Flow tells that return type of method is any. Can I fix this without writing own type declaration?
It doesn't look like there is any particular reason, just that it hasn't yet been given a better type. You can see in the DOM libdef file that it is declared as returning any, and that line hasn't been touched in over four years.
This would be an easy first PR, if you are interested in improving it.

How to test if an expression is a proper lvalue without changing its value?

I write some script, that act as a middle man between user and the R session. User inputs two fields: lvalue and expression with intention of executing lvalue<-eval(parse(text=expression)). Among other things the script needs to do, is to verify, that in this actual assignment the lvalue is a proper lvalue without doing the actual assignment.
Is it possible?
I want to make sure, that there are no side effects whatsoever after checking it (think about stream handlers, where assignments could have a lot of side effects).
I understand, that I can only be 100% sure the assignment worked only after it has be actually made; but can I do anything better than testing the proper evaluation of eval(parse(text=lvalue)) (lvalue is input as string)?
I want to catch cases, when user supply a lvalue in the form of
incorrect-var-name
function(call)
sin(x)
But I want the test to pass stuff like:
variable[indexing]
double[[brackets]]
even[complex[indexing]]
update: I asked a much narrower version of this question: How to test, if the given object foo has a assignment operator defined, so foo<-value has a chance to success?.

Navigating along rapid.xml nodes

This question slightly differs from check for variable number of sibling nodes & different siblings in Rapidxml. In most of the examples I have found on the web I see hard coded keys, for example:
xml_node<>* root = doc.first_node("rootnode");
Here "rootnode" is hard coded. My situation is slightly different, in the sense that parsing and tagging is already done by rapidxml. I need to know the names as read by the parser by iterating over nodes and their sibling without knowing the hard coded name and the depth of the node. I am looking for the suggestion/solution on some kind of recursive navigation along rapidxml tree.
Thank you.
According to RapidXml's documentation (see here) the node name parameter in first_node() method is optional. You can just omit that parameter and you will get the first child node, regardless of its name:
xml_node<>* root = doc.first_node();
Then you can just get node's name by calling its name() method.

Resources