package php.runtime.ext.core.classes;
import php.runtime.Memory;
import php.runtime.common.AbstractCompiler;
import php.runtime.common.HintType;
import php.runtime.env.*;
import php.runtime.ext.core.classes.stream.Stream;
import php.runtime.lang.BaseObject;
import php.runtime.loader.dump.ModuleDumper;
import php.runtime.memory.ArrayMemory;
import php.runtime.reflection.ClassEntity;
import php.runtime.reflection.ModuleEntity;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static php.runtime.annotation.Reflection.*;
@Name("php\\lang\\Module")
public class WrapModule extends BaseObject {
protected ModuleEntity module;
protected boolean registered = false;
public WrapModule(Environment env, ModuleEntity module) {
super(env);
this.module = module;
}
public WrapModule(Environment env, ClassEntity clazz) {
super(env, clazz);
}
@Signature({
@Arg("source"),
@Arg(value = "compiled", optional = @Optional("false")),
@Arg(value = "debugInformation", optional = @Optional("true"))
})
public Memory __construct(Environment env, Memory... args) throws Throwable {
InputStream is = Stream.getInputStream(env, args[0]);
try {
Context context = new Context(is, Stream.getPath(args[0]), env.getDefaultCharset());
if (args[1].toBoolean()) {
ModuleDumper moduleDumper = new ModuleDumper(context, env, args[2].toBoolean());
module = moduleDumper.load(context.getInputStream(env.getDefaultCharset()));
} else {
AbstractCompiler compiler = env.scope.createCompiler(env, context);
module = compiler.compile(false);
}
register(env);
} finally {
Stream.closeStream(env, is);
}
return Memory.NULL;
}
protected void loadModule(Environment env) {
if (!module.isLoaded()) {
synchronized (env.scope) {
if (!module.isLoaded()) {
env.scope.loadModule(module);
env.scope.addUserModule(module);
}
}
}
}
protected void register(Environment env, Memory... args) {
if (registered)
return;
loadModule(env);
env.registerModule(module);
registered = true;
}
@Signature
public String getName() {
return module.getName();
}
@Signature(@Arg(value = "variables", type = HintType.ARRAY, optional = @Optional("NULL")))
public Memory call(Environment env, Memory... args) throws Throwable {
if (!registered)
register(env);
if (args[0].isNull())
return module.include(env);
else
return module.include(env, args[0].toImmutable().toValue(ArrayMemory.class));
}
@Signature({
@Arg("target"),
@Arg(value = "saveDebugInfo", optional = @Optional("true"))
})
public Memory dump(Environment env, Memory... args) throws IOException {
ModuleDumper moduleDumper = new ModuleDumper(module.getContext(), env, args[1].toBoolean());
OutputStream os = Stream.getOutputStream(env, args[0]);
try {
moduleDumper.save(module, os);
} finally {
Stream.closeStream(env, os);
}
return Memory.NULL;
}
}