`
bellstar
  • 浏览: 150967 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JSI代码分析

阅读更多

一、$import流程图

 


二、doScriptImport流程图

 


 

三、JSI导入js关键代码分析

 

 function loadDependence(data,vars){
        loadScript(data[0],data[1],data[2]);
        var objectMap = data[0].objectMap;
        var names = data[5];
        var i = names.length;
        while(i--){
            var name = names[i];
            vars.push(name);//对于转载后依赖,我们使用重复设置了一次
            vars[name] = objectMap[name];
        }
}

function prepareScriptLoad(packageObject,loader){
        var name = loader.name;
        var deps = packageObject.dependenceMap[name];
        var varText = 'this.hook=function(n){return eval(n)}';
        var vars = [];
        var i = deps && deps.length;
        while(i--){
            var dep = deps[i];
            var key =  dep[3] || 0; //? 0
            if(dep[4]){//记录依赖,以待装载 dep[4]=> true 载入后依赖
                vars.push.apply(vars,dep[5]); //把dep[5]=>
                if(map){
                    if(map[key]){
                        map[key].push(dep);
                    }else{
                        map[key] = [dep]
                    }
                }else{
                    //函数内只有一次赋值(申明后置,也就你JavaScript够狠!! )
                    var map = loader.dependenceMap = {};
                    loader.initialize = scriptLoaderInitialize;
                    map[key] = [dep]
                }
            }else{//直接装载(只是装载到缓存对象,没有进入装载单元),无需记录
                //这里貌似有死循环的危险
                loadDependence(dep,vars);
                if(dep = packageObject.loaderMap[name]){
                    return dep;
                }
            }
        }
        if(vars.length){
            loader.varMap = vars;
            /**
             * this.hook = function(n){
             * 		return eval(n)
             * };
             * var obj1 = this.varMap.obj1, obj2 = this.varMap.obj2, obj3 = this.varMap.obj3
             */
            varText += ';var '+vars.join(',').replace(/([^,]+)/g,'$1 = this.varMap.$1');
        }
        loader.varText = varText;
    }

    function doScriptLoad(packageObject,loader){
        var name = loader.name;
        var packageName = packageObject.name;
        var cachedScript = getCachedScript(packageName,name);
        packageObject.loaderMap[name] = loader;
        try{
            if(cachedScript instanceof Function){
                //$JSI.preload(pkgName,name,'')
                cachedScripts[packageName][name]='';//clear cache
                return cachedScript.call(loader);
            }else{
                //不要清除文本缓存
                return freeEval.call(loader,'eval(this.varText);'+(cachedScript || loadTextByURL(packageObject.scriptBase+name)));
            }
        }catch(e){
            if(debugMode){
                if("org.xidea.jsi.boot:$log"){
                    $log.error("Load Error:\n"+loader.scriptBase + name+"\n\nException:"+e);
                }
            }
            throw e;
        }finally{
            delete loader.varMap ;
            delete loader.varText ;
            var names = packageObject.scriptObjectMap[name];
            var index = names.length;
            var objectMap = packageObject.objectMap;
            //此处优化不知有无作用
            if(index == 1){
                objectMap[names = names[0]] = loader.hook(names);
            }else{
                var values = loader.hook('['+names.join(',')+']');
                while(index--){
                    objectMap[names[index]] = values[index];
                }
            }
        }
    }

    function doScriptImport(packageObject,fileName,target){
        loadScript(packageObject,fileName);
        var objectNames = packageObject.scriptObjectMap[fileName];
        //null不可hack
        if(target != null){
            for(var i = 0; i<objectNames.length;i++){
                target[objectNames[i]]=packageObject.objectMap[objectNames[i]];
            }
        }
    }

   var $import = function(freeEval,cachedScripts){
       ...
   }(function(){eval(arguments[0]);},{});

 

第38行

loadDependence(dep,vars);

在这里JSI把待载入脚本[依赖]的对象存入vars,在第45赋值给了loader.varMap

第52行 对象名数组 => 对象声明语句

varText += ';var '+vars.join(',').replace(/([^,]+)/g,'$1 = this.varMap.$1');

16行

var  varText =  'this.hook=function(n){return eval(n)}' ;

这是JSI把载入脚本在loader下执行后能够获取引用到的关键技术

第69行 后台js文件---->前台---->call(loader,hook+js文件内容)

return freeEval.call(loader,'eval(this.varText);'+(cachedScript || loadTextByURL(packageObject.scriptBase+name)));

在这里JSI把js文件从后台通过xmlhttp从后台载入,然后在loader这个scope中执行(避免命名污染),此时loader.hook被放到了与执行js的同一个上下文中

第88-91行 loader => package

                var values = loader.hook('['+names.join(',')+']');
                while(index--){
                    objectMap[names[index]] = values[index];
                }

在这里JSI利用loader.hook提取出脚本在声明的对象并传给Package.objectMap

第102行

 target[objectNames[i]]=packageObject.objectMap[objectNames[i]];

把对象从package.objectMap传给Import中声明的target对象,或者Import执行时的scope对象

 

 

  • 大小: 31.7 KB
  • 大小: 35.7 KB
分享到:
评论
2 楼 jindw 2009-03-16  
你有一次修改是不对的:

if(debugMode){ 


源代码应该是:
if(":debug"){ 


大多数人一定会为后者疑惑。
这是JSA特征编译的手法,这种针对字符串常量的条件块,JSA都会自动清理,除非你指定了某个特征需求。
1 楼 jindw 2008-12-24  
图文并茂,分析到位。
我把这篇文章收录到JSI专栏了^_^

相关推荐

    JSI, java脚本开发工具

    JSI框架提供一个无侵入的脚本库管理解决方案,和一个全面的前端开发调试、文档解析、模版编译、打包导出环境支持。 作为一个开发期间的脚本管理工具,让开发者在开发期间享受JSI带来的种种便捷,也可以作为一个运行...

    JSI-full-2.0

    通过分析这些脚本,我们可以深入理解JSI-full-2.0的工作原理。 10. **template**:模板文件,可能用于生成动态内容,例如HTML模板引擎(如Handlebars或EJS),它们允许开发者使用特定语法创建可复用的HTML结构。 ...

    轻量系统JS-UI框架子系统

    ArkUI ACE Engine Lite是JS-UI框架的核心,它负责解析JS代码,执行UI逻辑,并将结果呈现到屏幕上。其主要功能包括: - **编译与运行时支持**:支持JS代码的编译和运行,提供高效的执行环境。 - **模板引擎**:...

    HDT-JSI01

    通过阅读和分析这些文件,你可以深入理解项目的工作原理,学习如何组织代码、如何实现特定功能,以及如何与其他开发者协作。此外,它还可能包含README文件,提供项目介绍、安装指南和使用说明。通过研究这样的项目,...

    JS文件加密工具,比较实用

    JS文件加密的主要目的是保护源代码不被轻易阅读和篡改,防止恶意用户逆向工程分析,确保知识产权的安全。JSA(JavaScript Obfuscator and Compressor)是一个实用的JS文件加密工具,它起源于JSI编译处理的小工具,...

    JAVA-VRML.rar_VRML_java vrml

    3. **Java Scripting Interface (JSI)**:VRML97引入了JSI,允许在VRML场景中嵌入脚本,包括Java代码。这使得开发者可以在VRML场景中直接使用Java,提高了灵活性和性能。 4. **X3D**:作为VRML的后续标准,X3D在...

    一个高效的JavaScript压缩工具下载集合

    JSA(JavaScript Analyzer)是另一种值得推荐的工具,它不仅提供代码压缩功能,还能进行代码格式化和脚本分析。脚本分析功能有助于开发者检测潜在问题,例如查看声明的函数和变量,以及使用到的外部变量等。JSA的...

    Geckofx基于火狐内核的浏览器

    此外,通过JavaScript接口(JSI)可以直接在.NET代码中调用JavaScript函数,反之亦然,实现了跨语言的双向交互。 **5. 示例项目** 压缩包中的"Test.Geckofx"文件可能是演示项目的源代码,包括了如何在.NET应用中...

    React-Native:React本机课程

    2. **JavaScript Native Interface (JSI)**:JSI是React-Native底层的一个关键组成部分,它提供了一个更高效的JavaScript引擎,使得JavaScript代码能更接近原生性能。理解JSI的工作原理有助于优化React-Native应用的...

    脚本分析、压缩、混淆工具 JSA新版本发布,压缩效率提高大约10%

    ### 脚本分析、压缩、混淆工具 JSA新版本发布 #### 概述 脚本分析、压缩、混淆工具 JSA(以下简称“JSA”)的新版本已正式发布。此次更新重点在于提升压缩效率,据官方数据表示,相较于旧版本,新版本的压缩效率...

    MyoToy:与 Myo 一起玩的 Android 应用程序

    3. **JavaScript 与 Android 交互**:可能使用了 JavaScript Interface(JSI)或通过 WebView 执行 JavaScript 代码,让 JavaScript 代码能够调用 Android 的原生方法,反之亦然。 4. **手势识别算法**:开发者需要...

    react-native-workshop-starterkit

    2. **JavaScript Interface (JSI)**:React Native通过JSI与原生平台交互,使得JavaScript代码能够调用原生模块,如访问设备硬件、网络通信等。 3. **Native Modules**:开发者可以使用Objective-C(iOS)或Java/...

Global site tag (gtag.js) - Google Analytics