YAP 7.1.0
fli_absmi_insts.h
1/************************************************************************\
2 * Call C predicates instructions *
3\************************************************************************/
4
5#include <YapTerm.h>
6
7
8#ifdef INDENT_CODE
9{
10 {
11 {
12#endif /* INDENT_CODE */
13
14 BOp(call_cpred, Osbpp);
15#if __ANDROID__ && STRONG_DEBUG
16 char *s;
17 Atom name;
18 if (PREG->y_u.Osbpp.p->ArityOfPE) {
19 Functor f = PREG->y_u.Osbpp.p->FunctorOfPred;
20 name = f->NameOfFE;
21 } else {
22 name = (Atom)(PREG->y_u.Osbpp.p->FunctorOfPred);
23 }
24 s = name->StrOfAE;
25
26 LOG(" %s ", s);
27#endif
28 check_trail(TR);
29 if (!(PREG->y_u.Osbpp.p->PredFlags &
30 (SafePredFlag | NoTracePredFlag | HiddenPredFlag))) {
31 CACHE_Y_AS_ENV(YREG);
32 check_stack(NoStackCCall, HR);
33 ENDCACHE_Y_AS_ENV();
34 }
35 //do_c_call :
36 SET_ASP(YREG, AS_CELLS(PREG->y_u.Osbpp.s) );
37 /* for slots to work */
38#ifdef LOW_LEVEL_TRACER
39 if (Yap_do_low_level_trace)
40 low_level_trace(enter_pred, PREG->y_u.Osbpp.p, XREGS + 1);
41#endif /* LOW_LEVEL_TRACE */
42 BEGD(d0);
43 CPredicate f = PREG->y_u.Osbpp.p->cs.f_code;
44 PREG = NEXTOP(PREG, Osbpp);
45 saveregs();
46 d0 = (f)(PASS_REGS1);
47 setregs();
48#ifdef SHADOW_S
49 SREG = Yap_REGS.S_;
50#endif
51 if (!d0) {
52 FAIL();
53 }
54 ENDD(d0);
55 CACHE_A1();
56 JMPNext();
57
58 NoStackCCall:
59 PROCESS_INT(interrupt_c_call, do_c_call);
60 JMPNext();
61 ENDBOp();
62
63 /* execute Label */
64 BOp(execute_cpred, Osbpp);
65 check_trail(TR);
66 {
67 PredEntry *pt0;
68
69 BEGD(d0);
70 CACHE_Y_AS_ENV(YREG);
71#ifndef NO_CHECKING
72 check_stack(NoStackExecuteC, HR);
73#endif
74#ifdef FROZEN_STACKS
75 {
76 choiceptr top_b = PROTECT_FROZEN_B(B);
77
78#ifdef YAPOR_SBA
79 if (YREG > (CELL *)top_b || YREG < HR)
80 ASP = (CELL *)top_b;
81#else
82 if (YREG > (CELL *)top_b)
83 ASP = (CELL *)top_b;
84#endif /* YAPOR_SBA */
85 else
86 ASP = YREG + E_CB;
87 }
88#else
89 SET_ASP(YREG, E_CB );
90/* for slots to work */
91#endif /* FROZEN_STACKS */
92 pt0 = PREG->y_u.Osbpp.p;
93#ifdef LOW_LEVEL_TRACER
94 if (Yap_do_low_level_trace) {
95 low_level_trace(enter_pred, pt0, XREGS + 1);
96 }
97#endif /* LOW_LEVEL_TRACE */
98 CACHE_A1();
99 BEGD(d0);
100 d0 = (CELL)B;
101 /* for profiler */
102 save_pc();
103 ENV_YREG[E_CB] = d0;
104 ENDD(d0);
105#ifdef DEPTH_LIMIT
106 if (DEPTH <= MkIntTerm(1)) { /* I assume Module==0 is prolog */
107 if (pt0->ModuleOfPred) {
108 if (DEPTH == MkIntTerm(0)) {
109 FAIL();
110 } else {
111 DEPTH = RESET_DEPTH();
112 }
113 }
114 } else if (pt0->ModuleOfPred) {
115 DEPTH -= MkIntConstant(2);
116 }
117#endif /* DEPTH_LIMIT */
118 /* now call C-Code */
119 {
120 CPredicate f = PREG->y_u.Osbpp.p->cs.f_code;
121
122 yamop *oldPREG = PREG;
123 saveregs();
124 d0 = f(PASS_REGS1);
125 setregs();
126#ifdef SHADOW_S
127 SREG = Yap_REGS.S_;
128#endif
129 if (!d0) {
130 FAIL();
131 }
132 if (oldPREG == PREG) {
133 /* we did not update PREG */
134 /* we can proceed */
135 PREG = CPREG;
136 ENV_YREG = ENV;
137#ifdef DEPTH_LIMIT
138 DEPTH = ENV_YREG[E_DEPTH];
139#endif
140 WRITEBACK_Y_AS_ENV();
141 } else {
142 /* call the new code */
143 CACHE_A1();
144 }
145 }
146 JMPNext();
147 ENDCACHE_Y_AS_ENV();
148 ENDD(d0);
149 }
150
151 NoStackExecuteC:
152 PROCESS_INT(interrupt_executec, do_executec);
153 //do_executec :
154 JMPNext();
155 ENDBOp();
156
157 /* Like previous, the only difference is that we do not */
158 /* trust the C-function we are calling and hence we must */
159 /* guarantee that *all* machine registers are saved and */
160 /* restored */
161 BOp(call_usercpred, Osbpp);
162 CACHE_Y_AS_ENV(YREG);
163 check_stack(NoStackUserCall, HR);
164 ENDCACHE_Y_AS_ENV();
165 //do_user_call:
166#ifdef LOW_LEVEL_TRACER
167 if (Yap_do_low_level_trace) {
168 low_level_trace(enter_pred, PREG->y_u.Osbpp.p, XREGS + 1);
169 }
170#endif /* LOW_LEVEL_TRACE */
171#ifdef FROZEN_STACKS
172 {
173 choiceptr top_b = PROTECT_FROZEN_B(B);
174#ifdef YAPOR_SBA
175 if (YREG > (CELL *)top_b || YREG < HR)
176 ASP = (CELL *)top_b;
177#else
178 if (YREG > (CELL *)top_b)
179 ASP = (CELL *)top_b;
180#endif /* YAPOR_SBA */
181 else
182 ASP = (CELL *)(((char *)YREG) + PREG->y_u.Osbpp.s);
183 }
184#else
185 SET_ASP(YREG, AS_CELLS(PREG->y_u.Osbpp.s) );
186/* for slots to work */
187#endif /* FROZEN_STACKS */
188 {
189 /* make sure that we can still have access to our old PREG after calling
190 * user defined goals and backtracking or failing */
191 yamop *savedP;
192
193 LOCAL_PrologMode |= UserCCallMode;
194 {
195 PredEntry *p = PREG->y_u.Osbpp.p;
196
197 PREG = NEXTOP(PREG, Osbpp);
198 savedP = PREG;
199 saveregs();
200 save_machine_regs();
201
202 SREG = (CELL *)YAP_Execute(p, p->cs.f_code);
203 }
204 setregs();
205 LOCAL_PrologMode &= ~UserCCallMode;
206 restore_machine_regs();
207 PREG = savedP;
208 }
209 if (Yap_HasException()) {
210bool Yap_RaiseException();
211 SREG = NULL;
212 }
213 if (!SREG) {
214 FAIL();
215 }
216 /* in case we call Execute */
217 YENV = ENV;
218 YREG = ENV;
219 JMPNext();
220
221 NoStackUserCall:
222 PROCESS_INT(interrupt_user_call, do_user_call);
223 JMPNext();
224 ENDBOp();
225
226 BOp(call_c_wfail, slpp);
227#ifdef LOW_LEVEL_TRACER
228 if (Yap_do_low_level_trace) {
229 low_level_trace(enter_pred, PREG->y_u.slpp.p, XREGS + 1);
230 }
231#endif /* LOW_LEVEL_TRACE */
232#ifdef FROZEN_STACKS
233 {
234 choiceptr top_b = PROTECT_FROZEN_B(B);
235#ifdef YAPOR_SBA
236 if (YREG > (CELL *)top_b || YREG < HR)
237 ASP = (CELL *)top_b;
238#else
239 if (YREG > (CELL *)top_b)
240 ASP = (CELL *)top_b;
241#endif /* YAPOR_SBA */
242 else {
243 BEGD(d0);
244 d0 = PREG->y_u.slpp.s;
245 ASP = ((CELL *)YREG) + d0;
246 ENDD(d0);
247 }
248 }
249#else
250 if (YREG > (CELL *)B)
251 ASP = (CELL *)B;
252 else {
253 BEGD(d0);
254 d0 = PREG->y_u.slpp.s;
255 ASP = ((CELL *)YREG) + d0;
256 ENDD(d0);
257 }
258#endif /* FROZEN_STACKS */
259 {
260 CPredicate f = PREG->y_u.slpp.p->cs.f_code;
261 saveregs();
262 SREG = (CELL *)((f)(PASS_REGS1));
263 setregs();
264 }
265 if (!SREG) {
266 /* be careful about error handling */
267 if (PREG != FAILCODE)
268 PREG = PREG->y_u.slpp.l;
269 } else {
270 PREG = NEXTOP(PREG, slpp);
271 }
272 CACHE_A1();
273 JMPNext();
274 ENDBOp();
275
276 BOp(try_c, OtapFs);
277#ifdef YAPOR
278 CUT_wait_leftmost();
279#endif /* YAPOR */
280 CACHE_Y(YREG);
281 /* Alocate space for the cut_c structure*/
282 CUT_C_PUSH(NEXTOP(NEXTOP(PREG, OtapFs), OtapFs), S_YREG);
283 S_YREG = S_YREG - PREG->y_u.OtapFs.extra;
284 store_args(PREG->y_u.OtapFs.s);
285 store_yaam_regs(NEXTOP(P, OtapFs), 0);
286 B = B_YREG;
287#ifdef YAPOR
288 SCH_set_load(B_YREG);
289#endif /* YAPOR */
290 SET_BB(B_YREG);
291 ENDCACHE_Y();
292
293 TRYCC:
294 ASP = (CELL *)B;
295 {
296 CPredicate f = (CPredicate)(PREG->y_u.OtapFs.f);
297 saveregs();
298 SREG = (CELL *)((f)(PASS_REGS1));
299 /* This last instruction changes B B*/
300 while (POP_CHOICE_POINT(B)) {
301 cut_c_pop();
302 }
303 setregs();
304 }
305 if (!SREG) {
306 /* Removes the cut functions from the stack
307 without executing them because we have fail
308 and not cuted the predicate*/
309 while (POP_CHOICE_POINT(B))
310 cut_c_pop();
311 FAIL();
312 }
313 if ((CELL *)B == YREG && ASP != (CELL *)B) {
314 /* as Luis says, the predicate that did the try C might
315 * have left some data on the stack. We should preserve
316 * it, unless the builtin also did cut */
317 YREG = ASP;
318 HBREG = PROTECT_FROZEN_H(B);
319 SET_BB(B);
320 }
321 PREG = CPREG;
322 YREG = ENV;
323 JMPNext();
324 ENDBOp();
325
326 BOp(retry_c, OtapFs);
327#ifdef YAPOR
328 CUT_wait_leftmost();
329#endif /* YAPOR */
330 CACHE_Y(B);
331 CPREG = B_YREG->cp_cp;
332 ENV = B_YREG->cp_env;
333 HR = PROTECT_FROZEN_H(B);
334#ifdef DEPTH_LIMIT
335 DEPTH = B->cp_depth;
336#endif
337 HBREG = HR;
338 restore_args(PREG->y_u.OtapFs.s);
339 ENDCACHE_Y();
340 goto TRYCC;
341 ENDBOp();
342
343 BOp(cut_c, OtapFs);
344/*This is a phantom instruction. This is not executed by the WAM*/
345#ifdef DEBUG
346 /*If WAM executes this instruction, probably there's an error
347 when we put this instruction, cut_c, after retry_c*/
348 printf("ERROR: Should not print this message FILE: absmi.c %d\n",
349 __LINE__);
350#endif /*DEBUG*/
351 ENDBOp();
352
353 BOp(try_userc, OtapFs);
354#ifdef YAPOR
355 CUT_wait_leftmost();
356#endif /* YAPOR */
357 CACHE_Y(YREG);
358 /* Alocate space for the cut_c structure*/
359 CUT_C_PUSH(NEXTOP(NEXTOP(PREG, OtapFs), OtapFs), S_YREG);
360 S_YREG = S_YREG - PREG->y_u.OtapFs.extra;
361 store_args(PREG->y_u.OtapFs.s);
362 store_yaam_regs(NEXTOP(PREG, OtapFs), 0);
363 B = B_YREG;
364#ifdef YAPOR
365 SCH_set_load(B_YREG);
366#endif
367 SET_BB(B_YREG);
368 ENDCACHE_Y();
369 LOCAL_PrologMode = UserCCallMode;
370 ASP = YREG;
371 saveregs();
372 save_machine_regs();
373 SREG = (CELL *)YAP_ExecuteFirst(PREG->y_u.OtapFs.p,
374 (CPredicate)(PREG->y_u.OtapFs.f));
375 restore_machine_regs();
376 setregs();
377 LOCAL_PrologMode &= UserMode;
378 if (!SREG) {
379 FAIL();
380 }
381 if ((CELL *)B == YREG && ASP != (CELL *)B) {
382 /* as Luis says, the predicate that did the try C might
383 * have left some data on the stack. We should preserve
384 * it, unless the builtin also did cut */
385 YREG = ASP;
386 HBREG = PROTECT_FROZEN_H(B);
387 }
388 PREG = CPREG;
389 YREG = ENV;
390 CACHE_A1();
391 JMPNext();
392 ENDBOp();
393
394 BOp(retry_userc, OtapFs);
395#ifdef YAPOR
396 CUT_wait_leftmost();
397#endif /* YAPOR */
398 CACHE_Y(B);
399 CPREG = B_YREG->cp_cp;
400 ENV = B_YREG->cp_env;
401 HR = PROTECT_FROZEN_H(B);
402#ifdef DEPTH_LIMIT
403 DEPTH = B->cp_depth;
404#endif
405 HBREG = HR;
406 restore_args(PREG->y_u.OtapFs.s);
407 ENDCACHE_Y();
408
409 LOCAL_PrologMode |= UserCCallMode;
410 SET_ASP(YREG, E_CB);
411 saveregs();
412 save_machine_regs();
413 SREG = (CELL *)YAP_ExecuteNext(PREG->y_u.OtapFs.p,
414 (CPredicate)(PREG->y_u.OtapFs.f));
415 restore_machine_regs();
416 setregs();
417 LOCAL_PrologMode &= ~UserCCallMode;
418 if (!SREG) {
419 /* Removes the cut functions from the stack
420 without executing them because we have fail
421 and not cuted the predicate*/
422 while (POP_CHOICE_POINT(B))
423 cut_c_pop();
424 FAIL();
425 }
426 if ((CELL *)B == YREG && ASP != (CELL *)B) {
427 /* as Luis says, the predicate that did the try C might
428 * have left some data on the stack. We should preserve
429 * it, unless the builtin also did cut */
430 YREG = ASP;
431 HBREG = PROTECT_FROZEN_H(B);
432 }
433 PREG = CPREG;
434 YREG = ENV;
435 CACHE_A1();
436 JMPNext();
437 ENDBOp();
438
439 BOp(cut_userc, OtapFs);
440/*This is a phantom instruction. This is not executed by the WAM*/
441#ifdef DEBUG
442 /*If WAM executes this instruction, probably there's an error
443 when we put this instruction, cut_userc, after retry_userc*/
444 printf("ERROR: Should not print this message FILE: absmi.c %d\n",
445 __LINE__);
446#endif /*DEBUG*/
447 CACHE_A1();
448 JMPNext();
449 ENDBOp();
450
451 /************************************************************************\
452 * support instructions *
453\************************************************************************/
454
455 BOp(lock_pred, e);
456 {
457 PredEntry *ap = PredFromDefCode(PREG);
458 PELOCK(10, ap);
459 PP = ap;
460 if (!ap->cs.p_code.NOfClauses) {
461 UNLOCKPE(11, ap);
462 FAIL();
463 }
464 /*
465 we do not lock access to the predicate,
466 we must take extra care here
467 */
468 if (ap->cs.p_code.NOfClauses > 1 &&
469 !(ap->PredFlags & IndexedPredFlag)) {
470 /* update ASP before calling IPred */
471 SET_ASP(YREG, E_CB );
472 saveregs();
473 Yap_IPred(ap, 0, CP);
474 /* IPred can generate errors, it thus must get rid of the lock itself
475 */
476 setregs();
477 CACHE_A1();
478 /* for profiler */
479 save_pc();
480 }
481 PREG = ap->cs.p_code.TrueCodeOfPred;
482 }
483 JMPNext();
484 ENDBOp();
485
486 BOp(index_pred, e);
487 {
488 PredEntry *ap = PredFromDefCode(PREG);
489#if defined(YAPOR) || defined(THREADS)
490 /*
491 we do not lock access to the predicate,
492 we must take extra care here
493 */
494 if (!PP) {
495 PELOCK(11, ap);
496 }
497 if (ap->OpcodeOfPred != INDEX_OPCODE) {
498 /* someone was here before we were */
499 if (!PP) {
500 UNLOCKPE(11, ap);
501 }
502 PREG = ap->CodeOfPred;
503 /* for profiler */
504 save_pc();
505 JMPNext();
506 }
507#endif
508 /* update ASP before calling IPred */
509 SET_ASP(YREG, E_CB);
510 saveregs();
511 Yap_IPred(ap, 0, CP);
512 /* IPred can generate errors, it thus must get rid of the lock itself */
513 setregs();
514 CACHE_A1();
515 PREG = ap->CodeOfPred;
516 /* for profiler */
517 save_pc();
518#if defined(YAPOR) || defined(THREADS)
519 if (!PP)
520#endif
521 UNLOCKPE(14, ap);
522 }
523 JMPNext();
524 ENDBOp();
525
526#if THREADS
527 BOp(thread_local, e);
528 {
529 PredEntry *ap = PredFromDefCode(PREG);
530 ap = Yap_GetThreadPred(ap PASS_REGS);
531 PREG = ap->CodeOfPred;
532 /* for profiler */
533 save_pc();
534 }
535 JMPNext();
536 ENDBOp();
537#endif
538
539 BOp(expand_index, e);
540 {
541 PredEntry *pe = PredFromExpandCode(PREG);
542 yamop *pt0;
543
544 /* update ASP before calling IPred */
545 SET_ASP(YREG, E_CB);
546#if defined(YAPOR) || defined(THREADS)
547 if (!PP) {
548 PELOCK(12, pe);
549 }
550 if (!same_lu_block(PREG_ADDR, PREG)) {
551 PREG = *PREG_ADDR;
552 if (!PP) {
553 UNLOCKPE(15, pe);
554 }
555 JMPNext();
556 }
557#endif
558#ifdef SHADOW_S
559 S = SREG;
560#endif /* SHADOW_S */
561 saveregs();
562 pt0 = Yap_ExpandIndex(pe, 0);
563 /* restart index */
564 setregs();
565#ifdef SHADOW_S
566 SREG = S;
567#endif /* SHADOW_S */
568 PREG = pt0;
569#if defined(YAPOR) || defined(THREADS)
570 if (!PP) {
571 UNLOCKPE(12, pe);
572 }
573#endif
574 JMPNext();
575 }
576 ENDBOp();
577
578 BOp(expand_clauses, sssllp);
579 {
580 PredEntry *pe = PREG->y_u.sssllp.p;
581 yamop *pt0;
582
583 /* update ASP before calling IPred */
584 SET_ASP(YREG, E_CB);
585#if defined(YAPOR) || defined(THREADS)
586 if (PP == NULL) {
587 PELOCK(13, pe);
588 }
589 if (!same_lu_block(PREG_ADDR, PREG)) {
590 PREG = *PREG_ADDR;
591 if (!PP) {
592 UNLOCKPE(16, pe);
593 }
594 JMPNext();
595 }
596#endif
597 saveregs();
598 pt0 = Yap_ExpandIndex(pe, 0);
599 /* restart index */
600 setregs();
601 PREG = pt0;
602#if defined(YAPOR) || defined(THREADS)
603 if (!PP) {
604 UNLOCKPE(18, pe);
605 }
606#endif
607 JMPNext();
608 }
609 ENDBOp();
610
611 BOp(undef_p, e);
612 /* save S for module name */
613 {
614 PredEntry *pe = PredFromDefCode(PREG);
615 LOCAL_DoingUndefp = true;
616 saveregs();
617 undef_goal(pe PASS_REGS);
618 setregs();
619 /* for profiler */
620 LOCAL_DoingUndefp = false;
621 }
622 CACHE_A1();
623 JMPNext();
624 ENDBOp();
625
626 BOp(spy_pred, e);
627 saveregs();
628 spy_goal(PASS_REGS1);
629 setregs();
630 CACHE_A1();
631 JMPNext();
632 ENDBOp();
bool Yap_RaiseException()
let's go
Definition: errors.c:1410
Definition: Yatom.h:544
Definition: amidefs.h:264