/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,final Source source,final ErrorManager errors,final boolean strict,final int lineOffset,final DebugLogger log) {
super(source,errors,strict,lineOffset);
this.env = env;
this.namespace = new Namespace(env.getNamespace());
this.scripting = env._scripting;
if (this.scripting) {
this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
@Override
public void lineInfo(final int receiverLine,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
private static String safeSourceName(final ScriptEnvironment env,final CodeInstaller<ScriptEnvironment> installer,final Source source) {
String baseName = new File(source.getName()).getName();
final int index = baseName.lastIndexOf(".js");
if (index != -1) {
baseName = baseName.substring(0,index);
}
baseName = baseName.replace('.','_').replace('-','_');
if (!env._loader_per_compile) {
baseName = baseName + installer.getUniqueScriptId();
}
// ASM's bytecode verifier does not allow JVM allowed safe escapes using '\' as escape char.
// While ASM accepts such escapes for method names,field names,it enforces Java identifier
// for class names. Workaround that ASM bug here by replacing JVM 'dangerous' chars with '_'
// rather than safe encoding using '\'.
final String mangled = env._verify_code? replaceDangerChars(baseName) : NameCodec.encode(baseName);
return mangled != null ? mangled : baseName;
}
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,don't compile a nested (not topmost) function.
if((ondemand || lazy) && lc.getoutermostFunction() != functionNode) {
return true;
}
// If lazy compiling with optimistic types,don't compile the program eagerly either. It will soon be
// invalidated anyway. In presence of a class cache,this further means that an obsoleted program version
// lingers around. Also,currently loading prevIoUsly persisted optimistic types information only works if
// we're on-demand compiling a function,so with this strategy the :program method can also have the warmup
// benefit of using prevIoUsly persisted types.
//
// NOTE that this means the first compiled class will effectively just have a :createProgramFunction method,and
// the RecompilableScriptFunctionData (RSFD) object in its constants array. It won't even have the :program
// method. This is by design. It does mean that we're wasting one compiler execution (and we Could minimize this
// by just running it up to scope depth calculation,which creates the RSFDs and then this limited codegen).
// We Could emit an initial separate compile unit with the initial version of :program in it to better utilize
// the compilation pipeline,but that would need more invasive changes,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,final OutputStream out,final OutputStream err,final String[] args) throws IOException {
final Context context = makeContext(in,out,err,args);
if (context == null) {
return COMMANDLINE_ERROR;
}
final Global global = context.createGlobal();
final ScriptEnvironment env = context.getEnv();
final List<String> files = env.getFiles();
if (files.isEmpty()) {
return readEvalPrint(context,global);
}
if (env._compile_only) {
return compileScripts(context,global,files);
}
if (env._fx) {
return runFXScripts(context,files);
}
return runScripts(context,files);
}
项目:openjdk-jdk10
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,lineOffset);
this.lc = new ParserContext();
this.defaultNames = new arraydeque<>();
this.env = env;
this.namespace = new Namespace(env.getNamespace());
this.scripting = env._scripting;
if (this.scripting) {
this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
@Override
public void lineInfo(final int receiverLine,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
项目:openjdk-jdk10
文件:CompilationPhase.java
@Override
FunctionNode transform(final Compiler compiler,final CompilationPhases phases,final FunctionNode fn) {
final FunctionNode newFunctionNode = transformFunction(fn,new LocalVariableTypesCalculator(compiler));
final ScriptEnvironment senv = compiler.getScriptEnvironment();
final PrintWriter err = senv.getErr();
//Todo separate phase for the debug printouts for abstraction and clarity
if (senv._print_lower_ast || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_AST)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new ASTWriter(newFunctionNode));
}
if (senv._print_lower_parse || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_PARSE)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new PrintVisitor(newFunctionNode));
}
return newFunctionNode;
}
项目:openjdk-jdk10
文件:CodeGenerator.java
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
项目:openjdk-jdk10
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:openjdk-jdk10
文件:NashornCompleter.java
private static Parser createParser(final ScriptEnvironment env) {
final List<String> args = new ArrayList<>();
if (env._const_as_var) {
args.add("--const-as-var");
}
if (env._no_Syntax_extensions) {
args.add("-nse");
}
if (env._scripting) {
args.add("-scripting");
}
if (env._strict) {
args.add("-strict");
}
if (env._es6) {
args.add("--language=es6");
}
return Parser.create(args.toArray(new String[0]));
}
项目:openjdk9
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
项目:openjdk9
文件:CompilationPhase.java
@Override
FunctionNode transform(final Compiler compiler,new LocalVariableTypesCalculator(compiler));
final ScriptEnvironment senv = compiler.getScriptEnvironment();
final PrintWriter err = senv.getErr();
//Todo separate phase for the debug printouts for abstraction and clarity
if (senv._print_lower_ast || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_AST)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new ASTWriter(newFunctionNode));
}
if (senv._print_lower_parse || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_PARSE)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new PrintVisitor(newFunctionNode));
}
return newFunctionNode;
}
项目:openjdk9
文件:CodeGenerator.java
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
项目:openjdk9
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:openjdk9
文件:NashornCompleter.java
private static Parser createParser(final ScriptEnvironment env) {
final List<String> args = new ArrayList<>();
if (env._const_as_var) {
args.add("--const-as-var");
}
if (env._no_Syntax_extensions) {
args.add("-nse");
}
if (env._scripting) {
args.add("-scripting");
}
if (env._strict) {
args.add("-strict");
}
return Parser.create(args.toArray(new String[0]));
}
项目:kaziranga
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
项目:kaziranga
文件:Compiler.java
private static String safeSourceName(final ScriptEnvironment env,it enforces Java identifier
// for class names. Workaround that ASM bug here by replacing JVM 'dangerous' chars with '_'
// rather than safe encoding using '\'.
final String mangled = env._verify_code? replaceDangerChars(baseName) : NameCodec.encode(baseName);
return mangled != null ? mangled : baseName;
}
项目:kaziranga
文件:CodeGenerator.java
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
项目:kaziranga
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:lookaside_java-1.8.0-openjdk
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
项目:lookaside_java-1.8.0-openjdk
文件:CompilationPhase.java
@Override
FunctionNode transform(final Compiler compiler,new LocalVariableTypesCalculator(compiler));
final ScriptEnvironment senv = compiler.getScriptEnvironment();
final PrintWriter err = senv.getErr();
//Todo separate phase for the debug printouts for abstraction and clarity
if (senv._print_lower_ast || fn.getFlag(FunctionNode.IS_PRINT_LOWER_AST)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new ASTWriter(newFunctionNode));
}
if (senv._print_lower_parse || fn.getFlag(FunctionNode.IS_PRINT_LOWER_PARSE)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new PrintVisitor(newFunctionNode));
}
return newFunctionNode;
}
项目:lookaside_java-1.8.0-openjdk
文件:CodeGenerator.java
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
项目:lookaside_java-1.8.0-openjdk
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:jdk8u_nashorn
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
项目:jdk8u_nashorn
文件:CompilationPhase.java
@Override
FunctionNode transform(final Compiler compiler,new LocalVariableTypesCalculator(compiler));
final ScriptEnvironment senv = compiler.getScriptEnvironment();
final PrintWriter err = senv.getErr();
//Todo separate phase for the debug printouts for abstraction and clarity
if (senv._print_lower_ast || fn.getFlag(FunctionNode.IS_PRINT_LOWER_AST)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new ASTWriter(newFunctionNode));
}
if (senv._print_lower_parse || fn.getFlag(FunctionNode.IS_PRINT_LOWER_PARSE)) {
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
err.println(new PrintVisitor(newFunctionNode));
}
return newFunctionNode;
}
项目:jdk8u_nashorn
文件:CodeGenerator.java
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
项目:jdk8u_nashorn
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:infobip-open-jdk-8
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
* @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
this.log = log == null ? DebugLogger.disABLED_LOGGER : log;
}
项目:infobip-open-jdk-8
文件:Compiler.java
private static String safeSourceName(final ScriptEnvironment env,it enforces Java identifier
// for class names. Workaround that ASM bug here by replacing JVM 'dangerous' chars with '_'
// rather than safe encoding using '\'.
final String mangled = env._verify_code? replaceDangerChars(baseName) : NameCodec.encode(baseName);
return mangled != null ? mangled : baseName;
}
项目:infobip-open-jdk-8
文件:CodeGenerator.java
private boolean skipFunction(final FunctionNode functionNode) {
final ScriptEnvironment env = compiler.getScriptEnvironment();
final boolean lazy = env._lazy_compilation;
final boolean ondemand = compiler.isondemandCompilation();
// If this is on-demand or lazy compilation,as currently the assumption that
// :program is emitted into the first compilation unit of the function lives in many places.
return !ondemand && lazy && env._optimistic_types && functionNode.isProgram();
}
项目:infobip-open-jdk-8
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:OLD-OpenJDK8
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
*/
public Parser(final ScriptEnvironment env,final boolean strict) {
super(source,strict);
this.env = env;
this.namespace = new Namespace(env.getNamespace());
this.scripting = env._scripting;
if (this.scripting) {
this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
@Override
public void lineInfo(final int receiverLine,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
}
项目:OLD-OpenJDK8
文件:ObjectClassGenerator.java
/**
* Collects the byte codes for a generated JavaScript class.
*
* @param classEmitter Open class emitter.
* @return Byte codes for the class.
*/
private byte[] toByteArray(final ClassEmitter classEmitter) {
classEmitter.end();
final byte[] code = classEmitter.toByteArray();
final ScriptEnvironment env = context.getEnv();
if (env._print_code) {
env.getErr().println(ClassEmitter.disassemble(code));
}
if (env._verify_code) {
context.verify(code);
}
return code;
}
项目:OLD-OpenJDK8
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,args);
if (context == null) {
return COMMANDLINE_ERROR;
}
final ScriptObject global = context.createGlobal();
final ScriptEnvironment env = context.getEnv();
final List<String> files = env.getFiles();
if (files.isEmpty()) {
return readEvalPrint(context,files);
}
项目:nashorn-backport
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
}
项目:nashorn-backport
文件:ObjectClassGenerator.java
/**
* Collects the byte codes for a generated JavaScript class.
*
* @param classEmitter Open class emitter.
* @return Byte codes for the class.
*/
private byte[] toByteArray(final ClassEmitter classEmitter) {
classEmitter.end();
final byte[] code = classEmitter.toByteArray();
final ScriptEnvironment env = context.getEnv();
if (env._print_code) {
env.getErr().println(ClassEmitter.disassemble(code));
}
if (env._verify_code) {
context.verify(code);
}
return code;
}
项目:nashorn-backport
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
项目:nashorn
文件:Parser.java
/**
* Construct a parser.
*
* @param env script environment
* @param source source to parse
* @param errors error manager
* @param strict parser created with strict mode enabled.
*/
public Parser(final ScriptEnvironment env,final int receiverLinePosition) {
// update the parser maintained line information
Parser.this.line = receiverLine;
Parser.this.linePosition = receiverLinePosition;
}
};
} else {
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
}
项目:nashorn
文件:ObjectClassGenerator.java
/**
* Collects the byte codes for a generated JavaScript class.
*
* @param classEmitter Open class emitter.
* @return Byte codes for the class.
*/
private byte[] toByteArray(final ClassEmitter classEmitter) {
classEmitter.end();
final byte[] code = classEmitter.toByteArray();
final ScriptEnvironment env = context.getEnv();
if (env._print_code) {
env.getErr().println(ClassEmitter.disassemble(code));
}
if (env._verify_code) {
context.verify(code);
}
return code;
}
项目:nashorn
文件:Shell.java
/**
* Run method logic.
*
* @param in input stream for Shell
* @param out output stream for Shell
* @param err error stream for Shell
* @param args arguments to Shell
*
* @return exit code
*
* @throws IOException if there's a problem setting up the streams
*/
protected final int run(final InputStream in,files);
}
private void initScripting(final ScriptEnvironment scriptEnv) {
Object value;
value = ScriptFunctionImpl.makeFunction("readLine",ScriptingFunctions.READLINE);
addOwnProperty("readLine",Attribute.NOT_ENUMERABLE,value);
value = ScriptFunctionImpl.makeFunction("readFully",ScriptingFunctions.READFULLY);
addOwnProperty("readFully",value);
final String execName = ScriptingFunctions.EXEC_NAME;
value = ScriptFunctionImpl.makeFunction(execName,ScriptingFunctions.EXEC);
addOwnProperty(execName,value);
// Nashorn extension: global.echo (scripting-mode-only)
// alias for "print"
value = get("print");
addOwnProperty("echo",value);
// Nashorn extension: global.$OPTIONS (scripting-mode-only)
final ScriptObject options = newObject();
copyOptions(options,scriptEnv);
addOwnProperty("$OPTIONS",options);
// Nashorn extension: global.$ENV (scripting-mode-only)
if (System.getSecurityManager() == null) {
// do not fill $ENV if we have a security manager around
// Retrieve current state of ENV variables.
final ScriptObject env = newObject();
env.putAll(System.getenv(),scriptEnv._strict);
addOwnProperty(ScriptingFunctions.ENV_NAME,env);
} else {
addOwnProperty(ScriptingFunctions.ENV_NAME,UNDEFINED);
}
// add other special properties for exec support
addOwnProperty(ScriptingFunctions.OUT_NAME,UNDEFINED);
addOwnProperty(ScriptingFunctions.ERR_NAME,UNDEFINED);
addOwnProperty(ScriptingFunctions.EXIT_NAME,UNDEFINED);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。