1摘要编译Javascript源码得到的字节码流(BytecodeArray)不能直接执行,绑定了入口(Entry)和上下文(Context)的字节码流才能被解释器(Ignition)执行,绑定了“入口+上下文”的字码流称为JSFunction,JSFunction是Ignition可以执行的实例。读懂JSFunction,可以深入了解Igntion的工作原理,更有助于在脑海中、在演草纸上擘画出字节码的解释(interpreter)过程。本文以SharedFunction(字节码流的表示方法)为输入,讲解JSFuncition源码和重要功能函数,分析JSFunction创建(new)、绑定入口和上下文的过程(章节2);最后,分析JSFunction内存布局,讲解读/写(getter/setter)方法(章节3)。2JSFunction分析一段C语言程序要经过编译(Compilation)、汇编(Assembly)和链接(Linking)之后才能执行。不太严谨但很形象的类比:字节码流类似汇编之后的结果(V8称之为SharedFunction),JSFunction类似链接之后的程序,所以说JSFunction是可以执行的实例。下面来看JSFunction源码:
1.classJSFunction:publicJSObject{2.public:3.DECL_ACCESSORS(prototype_or_initial_map,HeapObject)4.DECL_ACCESSORS(shared,SharedFunctionInfo)5.staticconstintkLengthDescriptorIndex=0;6.staticconstintkNameDescriptorIndex=1;7.staticconstintkMaybeHomeObjectDescriptorIndex=2;8.inlineContextcontext();9.inlineboolhas_context()const;10.inlinevoidset_context(HeapObjectcontext);11.inlineJSGlobalProxyglobal_proxy();12.inlineNativeContextnative_context();13.inlineintlength();14.staticHandleObjectGetName(Isolate*isolate,HandleJSFunctionfunction);15.staticHandleNativeContextGetFunctionRealm(HandleJSFunctionfunction);16.inlineCodecode()const;17.inlinevoidset_code(Codecode);18.inlinevoidset_code_no_write_barrier(Codecode);19.inlineAbstractCodeabstract_code();20.inlineboolIsInterpreted();21.inlineboolChecksOptimizationMarker();22.inlineboolIsOptimized();23.inlineboolHasOptimizedCode();24.inlineboolHasOptimizationMarker();25.voidMarkForOptimization(ConcurrencyModemode);26.inlineboolIsMarkedForOptimization();27.inlineboolIsMarkedForConcurrentOptimization();28.inlineboolIsInOptimizationQueue();29.inlinevoidClearOptimizedCodeSlot(constchar*reason);30.inlinevoidSetOptimizationMarker(OptimizationMarkermarker);31.inlinevoidClearOptimizationMarker();32.intComputeInstanceSizeWithMinSlack(Isolate*isolate);33.inlinevoidCompleteInobjectSlackTrackingIfActive();34.DECL_ACCESSORS(raw_feedback_cell,FeedbackCell)35.inlineFeedbackVectorfeedback_vector()const;36.inlineboolhas_feedback_vector()const;37.V8_EXPORT_PRIVATEstaticvoidEnsureFeedbackVector(38.HandleJSFunctionfunction);39.inlineboolhas_closure_feedback_cell_array()const;40.inlineClosureFeedbackCellArrayclosure_feedback_cell_array()const;41.staticvoidEnsureClosureFeedbackCellArray(HandleJSFunctionfunction);42.staticvoidInitializeFeedbackCell(HandleJSFunctionfunction);43.voidClearTypeFeedbackInfo();44.inlineboolNeedsResetDueToFlushedBytecode();45.inlinevoidResetIfBytecodeFlushed();46.DECL_GETTER(has_prototype_slot,bool)47.DECL_GETTER(initial_map,Map)48.staticvoidSetInitialMap(HandleJSFunctionfunction,HandleMapmap,49.HandleHeapObjectprototype);50.DECL_GETTER(has_initial_map,bool)51.V8_EXPORT_PRIVATEstaticvoidEnsureHasInitialMap(52.HandleJSFunctionfunction);53.staticV8_WARN_UNUSED_RESULTMaybeHandleMapGetDerivedMap(54.Isolate*isolate,HandleJSFunctionconstructor,55.HandleJSReceivernew_target);56.DECL_GETTER(has_prototype,bool)57.DECL_GETTER(has_instance_prototype,bool)58.DECL_GETTER(prototype,Object)59.DECL_GETTER(instance_prototype,HeapObject)60.DECL_GETTER(has_prototype_property,bool)61.DECL_GETTER(PrototypeRequiresRuntimeLookup,bool)62.staticvoidSetPrototype(HandleJSFunctionfunction,HandleObjectvalue);63.inlineboolis_