if(!ctx->callParent) naModUnlock();
return result;
}
+
+static void logError(naContext ctx)
+{
+ int i;
+ printf("logError\n");
+ printf("Nasal runtime error: %s\n", naGetError(ctx));
+ printf(" at %s\n", naStr_data(naGetSourceFile(ctx, 0)));
+ printf(", line %d\n", naGetLine(ctx, 0));
+ for(i = 1; i < naStackDepth(ctx); ++i )
+ printf( " called from: %s, line %d",
+ naStr_data(naGetSourceFile(ctx, i)),
+ naGetLine(ctx, i));
+}
+
+static naErrorHandler error_handler = &logError;
+naErrorHandler naSetErrorHandler(naErrorHandler cb)
+{
+ naErrorHandler old_handler = error_handler;
+ error_handler = cb;
+ return old_handler;
+}
+
+static int call_count = 0;
+naRef naCallMethodCtx( naContext ctx,
+ naRef code,
+ naRef self,
+ int argc,
+ naRef* args,
+ naRef locals )
+{
+ naRef result;
+ if(call_count) naModUnlock();
+ call_count++;
+ result = naCall(ctx, code, argc, args, self, locals);
+ if(naGetError(ctx) && error_handler)
+ error_handler(ctx);
+ call_count--;
+ if(call_count) naModLock();
+ return result;
+}
+
+naRef naCallMethod(naRef code, naRef self, int argc, naRef* args, naRef locals)
+{
+ naContext ctx = naNewContext();
+ naRef result = naCallMethodCtx(ctx, code, self, argc, args, locals);
+ naFreeContext(ctx);
+ return result;
+}
// naModUnlock() first if the lock is already held.
naRef naContinue(naContext ctx);
+// Does a naCall() in a given context. Wrapped here to make lock
+// tracking easier. Extension functions are called with the lock, but
+// we have to release it before making a new naCall(). So rather than
+// drop the lock in every extension function that might call back into
+// Nasal, we keep a stack depth counter here and only unlock/lock
+// around the naCall if it isn't the first one.
+naRef naCallMethodCtx( naContext ctx,
+ naRef code,
+ naRef self,
+ int argc,
+ naRef* args,
+ naRef locals );
+
+// Same as naCallMethodCtx but creates (and afterwards destroyes) a new context
+naRef naCallMethod(naRef code, naRef self, int argc, naRef* args, naRef locals);
+
+typedef void (*naErrorHandler)(naContext);
+
+// Register a handler to be called if an error is raised during the execution of
+// naCallMethodCtx or naCallMethod.
+naErrorHandler naSetErrorHandler(naErrorHandler cb);
+
// Throw an error from the current call stack. This function makes a
// longjmp call to a handler in naCall() and DOES NOT RETURN. It is
// intended for use in library code that cannot otherwise report an