- /** perform this trap -- arg.length == 0 if this is a get; otherwise it contains a single element to be put */
- public Object perform(Object[] arg) {
- TrapContext tc = TrapContext.get();
-
- // save both thread-locals on the stack and update their values
- Trap save_currentTrap = tc.currentTrap;
- tc.currentTrap = this;
-
- boolean save_putCascadeHappened = tc.putCascadeHappened;
- tc.putCascadeHappened = false;
-
- // invoke the trap function
- try {
- if (!isreadtrap && arg.length == 0) return cascadeFunction.call(null, null, null, arg);
-
- if (f == null) {
- if (Log.verbose) Log.log(this, "debug: reclaimed a dangling trap on property " + name);
- Object ret = cascadeFunction.call(null, null, null, arg);
- delete();
- return ret;
- }
-
- Object ret = f.call(Context.enter(), f.getParentScope(), f.getParentScope(), arg);
-
- // autocascade if required
- if (arg.length > 0 && !isreadtrap && !tc.putCascadeHappened) cascadeFunction.call(null, null, null, arg);
-
- return ret;
-
- } catch (EcmaError e) {
- if (Log.on) Log.log(this, "WARNING: uncaught interpreter exception: " + e.getMessage());
- if (Log.on) Log.log(this, " thrown from within trap '" + name + "' at " + e.getSourceName() + ":" + e.getLineNumber());
- } catch (JavaScriptException e) {
- if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage());
- if (Log.on) Log.log(this, " thrown from within trap '" + name + "' at " + e.sourceFile + ":" + e.line);
- } finally {
- // restore the thread-locals
- tc.putCascadeHappened = save_putCascadeHappened;
- tc.currentTrap = save_currentTrap;
- tc.trapDepth--;
- }
- return null;