summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/builtin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/builtin.cc')
-rw-r--r--Build/source/utils/asymptote/builtin.cc111
1 files changed, 84 insertions, 27 deletions
diff --git a/Build/source/utils/asymptote/builtin.cc b/Build/source/utils/asymptote/builtin.cc
index 4a8ed9c2216..b5066061384 100644
--- a/Build/source/utils/asymptote/builtin.cc
+++ b/Build/source/utils/asymptote/builtin.cc
@@ -42,6 +42,11 @@
#include "builtin.symbols.h"
#endif
+namespace vm {
+ // Defined in stack.cc
+ extern vm::frame *make_dummyframe(string name);
+}
+
using namespace types;
using namespace camp;
using namespace vm;
@@ -90,7 +95,7 @@ void base_tenv(tenv &te)
const formal noformal(0);
-void addFunc(venv &ve, access *a, ty *result, symbol id,
+function *functionFromFormals(ty *result,
formal f1=noformal, formal f2=noformal, formal f3=noformal,
formal f4=noformal, formal f5=noformal, formal f6=noformal,
formal f7=noformal, formal f8=noformal, formal f9=noformal,
@@ -119,6 +124,20 @@ void addFunc(venv &ve, access *a, ty *result, symbol id,
if (fH.t) fun->add(fH);
if (fI.t) fun->add(fI);
+ return fun;
+}
+
+void addFunc(venv &ve, access *a, ty *result, symbol id,
+ formal f1=noformal, formal f2=noformal, formal f3=noformal,
+ formal f4=noformal, formal f5=noformal, formal f6=noformal,
+ formal f7=noformal, formal f8=noformal, formal f9=noformal,
+ formal fA=noformal, formal fB=noformal, formal fC=noformal,
+ formal fD=noformal, formal fE=noformal, formal fF=noformal,
+ formal fG=noformal, formal fH=noformal, formal fI=noformal)
+{
+ function *fun = functionFromFormals(result,f1,f2,f3,f4,f5,f6,f7,f8,f9,
+ fA,fB,fC,fD,fE,fF,fG,fH,fI);
+
// NOTE: If the function is a field, we should encode the defining record in
// the entry
varEntry *ent = new varEntry(fun, a, 0, position());
@@ -132,7 +151,25 @@ void addFunc(venv &ve, bltin f, ty *result, symbol name,
formal f7, formal f8, formal f9, formal fA, formal fB, formal fC,
formal fD, formal fE, formal fF, formal fG, formal fH, formal fI)
{
- REGISTER_BLTIN(f, name);
+#ifdef DEBUG_BLTIN
+ // If the function is an operator, print out the whole signature with the
+ // types, as operators are heavily overloaded. min and max are also heavily
+ // overloaded, so we check for them too. Many builtin functions have so
+ // many arguments that it is noise to print out their full signatures.
+ string s = name;
+ if (s.find("operator ", 0) == 0 || s == "min" || s == "max")
+ {
+ function *fun = functionFromFormals(result,f1,f2,f3,f4,f5,f6,f7,f8,f9,
+ fA,fB,fC,fD,fE,fF,fG,fH,fI);
+ ostringstream out;
+ fun->printVar(out, name);
+ REGISTER_BLTIN(f, out.str());
+ }
+ else {
+ REGISTER_BLTIN(f, name);
+ }
+#endif
+
access *a = new bltinAccess(f);
addFunc(ve,a,result,name,f1,f2,f3,f4,f5,f6,f7,f8,f9,
fA,fB,fC,fD,fE,fF,fG,fH,fI);
@@ -544,13 +581,11 @@ void addArrayOps(venv &ve, types::array *t)
{
ty *ct = t->celltype;
-#ifdef TEST_ADDED_OPS
// Check for the alias function to see if these operation have already been
// added, if they have, don't add them again.
static types::function aliasType(primBoolean(), primVoid(), primVoid());
aliasType.sig.formals[0].t = t;
aliasType.sig.formals[1].t = t;
-#endif
if (ve.lookByType(SYM(alias), &aliasType))
return;
@@ -559,17 +594,16 @@ void addArrayOps(venv &ve, types::array *t)
primBoolean(), SYM(alias), formal(t, SYM(a)), formal(t, SYM(b)));
size_t depth=(size_t) t->depth();
- typedef void (*stackFcn)(stack *Stack);
- static stackFcn routine[]={run::copyArray0,run::copyArray1,run::copyArray2};
-
- size_t ndepth=sizeof(routine)/sizeof(stackFcn);
-
- if(depth <= ndepth) {
- addFunc(ve, routine[depth-1],
- t, SYM(array), formal(primInt(), SYM(n)),
- formal(ct, SYM(value)),
- formal(primInt(), SYM(depth), true));
- }
+
+ // Define an array constructor. This needs to know the depth of the array,
+ // which may not be known at runtime. Therefore, the depth, which is known
+ // here at compile-time, is pushed on the stack beforehand by use of a
+ // thunk.
+ callable *copyFunc = new thunk(new vm::bfunc(run::copyArray),(Int) depth-1);
+ addFunc(ve, new callableAccess(copyFunc),
+ t, SYM(array), formal(primInt(), SYM(n)),
+ formal(ct, SYM(value)),
+ formal(primInt(), SYM(depth), true));
switch (depth) {
case 1:
@@ -614,14 +648,7 @@ void addRecordOps(venv &ve, record *r)
void addFunctionOps(venv &ve, function *f)
{
-#ifdef NO_FUNC_OPS
// No function ops.
-#else
- addFunc(ve, run::boolFuncEq, primBoolean(), SYM_EQ, formal(f, SYM(a)),
- formal(f, SYM(b)));
- addFunc(ve, run::boolFuncNeq, primBoolean(), SYM_NEQ, formal(f, SYM(a)),
- formal(f, SYM(b)));
-#endif
}
@@ -702,11 +729,7 @@ void addOperators(venv &ve)
dummyRecord *createDummyRecord(venv &ve, symbol name)
{
dummyRecord *r=new dummyRecord(name);
-#ifdef DEBUG_FRAME
- vm::frame *f = new vm::frame("dummy record " + string(name), 0);
-#else
- vm::frame *f = new vm::frame(0);
-#endif
+ vm::frame *f = make_dummyframe(name);
addConstant(ve, f, r, name);
addRecordOps(ve, r);
return r;
@@ -728,9 +751,41 @@ void openFunc(stack *Stack)
}
#endif
+// A function accessible in asy code print the bytecode of a function.
+void printBytecode(stack *Stack)
+{
+ // As arbitrary addresses can be sent to printBytecode, it should not be run
+ // in safe mode.
+ if (settings::safe) {
+ cerr << "use -nosafe flag to enable printBytecode" << endl;
+ return;
+ }
+
+ vm::array *a=vm::pop<vm::array *>(Stack);
+ size_t numArgs=checkArray(a);
+ if (numArgs != 1)
+ cerr << "printBytecode takes one argument" << endl;
+
+ // TODO: Add a reliable test for the object being a func.
+ callable *c = a->read<callable *>(0);
+ if (func *f = dynamic_cast<func *>(c))
+ print(cout, f->body->code);
+ else
+ cout << "callable is not a standard function";
+}
+
+
+
+
// NOTE: We should move all of these into a "builtin" module.
void base_venv(venv &ve)
{
+ // Register the name of arrayDeleteHelper for debugging in "asy -s" mode.
+ // This is done automatically for other function, but because
+ // arrayDeleteHelper is not defined in the usual way, it must be done
+ // explicitly, and here is as good a place as any.
+ REGISTER_BLTIN(arrayDeleteHelper, "arrayDeleteHelper");
+
addInitializers(ve);
addCasts(ve);
addOperators(ve);
@@ -807,6 +862,8 @@ void base_venv(venv &ve)
addOpenFunc(ve, openFunc, primInt(), SYM(openFunc));
#endif
+ addOpenFunc(ve, printBytecode, primVoid(), SYM(printBytecode));
+
gen_runtime_venv(ve);
gen_runbacktrace_venv(ve);
gen_runpicture_venv(ve);