package org.dynjs.runtime;
import java.util.Collections;
import java.util.List;
import org.dynjs.parser.ast.FunctionDeclaration;
import org.dynjs.parser.ast.VariableDeclaration;
public abstract class AbstractNativeFunction extends AbstractFunction {
protected String filename;
public AbstractNativeFunction(GlobalContext globalContext, String... formalParameters) {
super(globalContext, LexicalEnvironment.newObjectEnvironment(globalContext.getObject(), false, null), true, formalParameters);
setupDebugContext();
setFileName();
}
public AbstractNativeFunction(GlobalContext globalContext, boolean strict, String... formalParameters) {
super(globalContext, LexicalEnvironment.newObjectEnvironment(globalContext.getObject(), false, null), strict, formalParameters);
setupDebugContext();
setFileName();
}
public AbstractNativeFunction(final GlobalContext globalContext, final LexicalEnvironment scope, final boolean strict, final String... formalParameters) {
super(globalContext, scope, strict, formalParameters);
setupDebugContext();
setFileName();
}
@Override
public List<FunctionDeclaration> getFunctionDeclarations() {
return Collections.emptyList();
}
@Override
public List<VariableDeclaration> getVariableDeclarations() {
return Collections.emptyList();
}
@Override
public Object call(ExecutionContext context) {
Object self = context.getThisBinding();
Arguments argsObj = (Arguments) context.resolve("arguments").getValue(context);
int numArgs = (int) argsObj.get(context, "length");
int paramsLen = getFormalParameters().length;
Object[] args = new Object[numArgs < paramsLen ? paramsLen : numArgs];
for (int i = 0; i < numArgs; ++i) {
Object v = argsObj.get(context, "" + i);
if (v instanceof Reference) {
if (((Reference) v).isUnresolvableReference()) {
v = Types.UNDEFINED;
} else {
v = ((Reference) v).getValue(context);
}
}
args[i] = v;
}
for (int i = numArgs; i < paramsLen; ++i) {
args[i] = Types.UNDEFINED;
}
return call(context, self, args);
}
public abstract Object call(ExecutionContext context, Object self, Object... args);
public String getFileName() {
return this.filename;
}
public void setFileName() {
this.filename = getClass().getName().replace(".", "/") + ".java";
}
public void setupDebugContext() {
this.debugContext = "<native function: " + getClass().getSimpleName() + ">";
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("function(" );
String[] params = getFormalParameters();
for (int i = 0; i < params.length; ++i) {
if (i > 0) {
buffer.append(", ");
}
buffer.append(params[i]);
}
buffer.append("){\n");
buffer.append(" <native code in: " ).append( getClass().getName() ).append( ">\n" );
buffer.append("}");
return buffer.toString();
}
}