javascript嵌入式解釋器MuJS官方參考手冊

摘要:
MuJS 是一個輕量級的 JavaScript 解釋器,可用於嵌入式開發。使用可移植 C 編寫,實現了 ECMA-262 規定的 ECMAScript 標準。與 V8、SpiderMonkey 和 JavaScriptCore等相比,MuJS非常精簡。網絡上MuJS的相關說明很少,只有官網上有一些相對詳盡的資料。

參考手冊是官網扒過來的,而且是直譯
http://dev.mujs.com/docs/reference.html
受限於本人的英文水平以及對javascript和MuJS的熟悉程度,翻譯的不是很好,有可能存在錯誤,後續如果對MuJS有更深入的瞭解後再進行修正。歡迎留言指正。

1. Introduction

MuJS is a library, written in clean and simple C. Being an extension library, MuJS has no notion of a main program: it only works embedded in a host client program. The host program can invoke functions to execute Javascript code, read and write Javascript variables, and register C functions to be called by Javascript.

MuJS是用簡潔的c語言實現的庫。作爲擴展庫MuJS不打算作主程序來用,它只是嵌入到主機客戶端程序中。主程序可以在函數中執行javascript腳本,讀寫javascript變量,註冊由javascript調用的c函數。

The MuJS distribution includes a sample host program called “mujs”, which uses the MuJS library to offer a standalone Javascript interpreter for interactive or batch use.

MuJS包含一個簡單的可執行程序mujs,它通過調用MuJS庫提供一套標準的javascript解釋器,作爲javasript的交互終端或者批處理命令執行平臺。
如下圖,虛擬機中安裝的mujs
這裏寫圖片描述

This reference manual assumes that you are already familiar with the Javascript language, in particular the type system and object prototype mechanisms.

本手冊假定您已經熟悉了javascript語言,特別是類型系統和對象原型機制。

2.Basic Concepts
基本概念

Values and Types
值和類型

There are six basic types in Javascript: undefined, null, boolean, number, string and object.

javascript中有6種基本類型:undefined, null, boolean, number, string 和 object。

Each object also has a class: object, array, function, userdata, regular expression, etc.

每個Object對象都具有一個類,類型可以是:object, array, function, userdata, regular expression等等

Javascript can call functions written in C provided by the host program, as well as other Javascript functions.

Javascript既可以調用宿主程序提供的c函數,也可以調用其他的javascript腳本函數。

Objects with the userdata class are provided to allow arbitrary C data to be attached to Javascript objects. A userdata object has a pointer to a block of raw memory, which is managed by the host. Userdata values cannot be created or modified in Javascript, only through the C API. This guarantees the integrity of data owned by the host program.

具有 userdata類的Objects對象允許任意的c數據附加到javascript的objects上。userdata 對象有一個指針,它指向一塊由主程序管理的原始內存。關聯到Javascript腳本UserData對象的所有值只能通過c的api來創建和修改。這一策略保證了主程序數據的完整性。

Custom properties on userdata objects can be implemented using getter and setter property accessor functions.

userdata 對象的自定義屬性的對象可以使用getter和setter屬性訪問器函數來實現。

Numbers are represented using double precision floating point values.

Number使用雙精度的浮點數來表示

Strings in the C interface are zero-terminated byte arrays in CESU-8 encoding. CESU-8 is a variant of UTF-8 which encodes supplementary unicode characters as surrogate pairs. This maintains compatibility with the UTF-16 nature of JavaScript, but requires attention when passing strings using supplementary unicode characters to and from the MuJS library. It also means that you cannot have any JavaScript strings with a zero character value in MuJS.

c接口中的字符串是一串CESU-8編碼方式的以0結尾的字節序列。CESU-8是UTF-8的變種, 補充的unicode編碼作爲代理對。這種編碼方式保證能夠和javascript的utf-16編碼兼容,但從MuJS庫導入或者導出補充的unicode字符時需要留意;在MuJS中javascript腳本string不會有0字符。

Environments
環境(變量)

Each function executes within an environment which defines which variables are accessible. This is a chain of all environment records in scope, with the global environment at the top. Each environment record in MuJS is represented as an object with the null prototype, including the global environment object.

每個函數都在某種環境下執行,該環境定義了哪些變量是可用的。這是所有範圍內環境的集合鏈表,全局環境在頂端。在MuJS中的每個環境記錄都是以null原型對象呈現的,包括全局對象的環境。

The registry is a hidden environment record which is only accessible to C. This is where Javascript values and objects that should only be accessible to C functions may be stored.

註冊表是一個僅能被c訪問的隱藏的環境記錄。這些只能通過c函數訪問的javascript腳本的值和對象會存到註冊表中。

Error Handling
錯誤處理

All Javascript actions start from C code in the host program calling a function from the MuJS library. Whenever an exception is thrown during the compilation or execution of Javascript, control returns to the host, which can take appropriate measures (such as printing an error message). C code can also throw exceptions by calling functions to create an error object and return control to Javascript.

javascript腳本的所有操作都是從c編碼的主程序調用MuJS庫開始的。當編譯或者執行javascript腳本拋出異常時,控制權返回給主程序,主程序可以採取相應的處理措施(比如輸出一條錯誤信息)。也可以在c代碼中調用函數拋出異常來創建錯誤對象object,並將控制返回到javascript腳本中。

Internally, MuJS uses the C longjmp facility to handle errors. A protected environment uses setjmp to set a recovery point. The try statement in Javascript creates such a recovery point, as does calling js_dostring, js_dofile, js_ploadstring, js_ploadfile, js_pcall and js_pconstruct.

MuJS內部使用c語言的longjmp處理異常錯誤。使用setjmp將環境保護起來,設置爲一個恢復點(指針)。在javascript腳本“try”聲明裏創建這類可恢復點(指針),調用js_dostring, js_dofile, js_ploadstring, js_ploadfile, js_pcall和js_pconstruct需要做錯誤處理。

When an error occurs or an exception is thrown from Javascript, it does a long jump to the most recent active recovery point.

如果錯誤產生或者javasript拋出異常, 系統通過long jump的跳轉到最新的活動的恢復節點。

If an error occurs outside any protected environment, MuJS first calls the panic function and then calls abort, thus exiting the host application. Your panic function can avoid this exit by never returning (for example by doing a long jump to your own recovery point outside MuJS).

如果錯誤發生在受保護的環境變量外部, MuJS首先調用panic函數,然後調用abort退出進程,從而退出主程序。你的panic函數如果沒有返回則可以避免退出(比如通過long jump到你自己的MuJS外部的可恢復指針)。

Garbage Collection
垃圾回收

MuJS performs automatic memory management using a basic mark-and-sweep collector. Collection is automatically triggered when enough allocations have accumulated. You can also force a collection pass from C.

MuJS使用基本的mark-and-sweep收集器來實現內存的自我管理,當累計到足夠多的垃圾時收集器自動觸發,你也可以通過c來強制進行垃圾回收操作。

Userdata objects have an associated C finalizer function that is called when the correspending object is freed.

userdata對象有一個與c相關聯的終結函數,當對應的對象free時調用此函數回收資源。

The Stack
堆棧

MuJS uses a virtual stack to pass values to and from C. Each element in this stack represents a Javascript value (null, number, string, etc).

MuJS 使用虛擬的棧來與c進行值的交互。 棧中的每個元素都能體現javascript的值,如null, number, string等等。

Whenever Javascript calls C, the called function gets a new stack. This stack initially contains the this value and any arguments passed to the function. When the C function returns, the top value on the stack is passed back to the caller as the return value.

每當javascript調用c時, 所調用的函數獲得一個新的棧。 這個棧最初包含this value和函數參數。 當c函數return返回時,棧頂的值將作爲返回值傳給調用者。

The stack values are accessed using stack indices. Index 0 always contains the this value, and function arguments are index 1 and up. Negative indices count down from the top of the stack, so index -1 is the top of the index and index -2 is the one below that.

堆棧值使用堆棧索引訪問,索引0總是包含this value,而函數的參數則是索引1向上遞增。負索引是從棧頂倒數,所以-1對應的是棧頂,-2是棧頂的下面一個。

3.The Application Program Interface
應用程序接口

State

typedef struct js_State js_State;
The interpreter state is bundled up in the opaque struct js_State. This state contains the value stacks, protected environments, and environment records.

解釋器的state被捆綁到不透明結構體js_State,此state包含堆棧,受保護的環境變量以及環境變量記錄。注:mujs所有操作都是圍繞state進行的。

js_State *js_newstate(js_Alloc alloc, void *context, int flags);
Create a new state using the allocator function and allocator context. Pass NULL to use the default allocator.

創建一個新的js_State變量state對象,使用 allocator函數和allocator對應的上下文。如果使用默認的allocator則寫入NULL。

The available flags:
JS_STRICT: compile and run code using ES5 strict mode.

flag可用參數:JS_STRICT,執行ES5的strict模式(唯一宏選項)
附上ES5 strict mode介紹:
https://www.cnblogs.com/fuheng01/articles/JS.html

void js_freestate(js_State *J);
Destroy the state and free all dynamic memory used by the state.

刪除state並釋放所佔用的動態內存

Allocator
分配器

The interpreter uses a host provided function for all memory allocation needs:

解釋器使用主程序提供的函數來按需分配內存。

typedef void *(*js_Alloc)(void *memctx, void *ptr, int size);
When size is zero, the allocator should behave like free and return NULL. When size is not zero, the allocator should behave like realloc. The allocator should return NULL if it cannot fulfill the request. The default allocator uses malloc, realloc and free.

如果參數size爲0, allocator分配器類似free功能,並返回NULL。如果size非0,分配器則類似於realloc內存分配函數。如果無法滿足內存分配需求,分配器返回NULL。默認的內存分配器使用的是malloc, realloc和free。

Panic

typedef void (*js_Panic)(js_State *J);
js_Panic js_atpanic(js_State *J, js_Panic panic);
Set a new panic function, and return the old one.

設置新的panic函數,同時返回老的panic

Report

typedef void (*js_Report)(js_State *J, const char *message);
void js_setreport(js_State *J, js_Report report);
Set a callback function for reporting various warnings and garbage collection

statistics. 設置回調函數report用於上報warnings和垃圾回收統計結果

Garbage collection
垃圾回收

js_gc(js_State *J, int report);
Force a garbage collection pass. If the report argument is non-zero, send a summary of garbage collection statistics to the report callback function.

強制垃圾回收,如果report的值爲非0,則發送垃圾回收統計的概要給report回調函數。

Loading and compiling scripts
加載和編譯scrpts腳本

A script is compiled by calling js_loadstring or js_loadfile. The result of a successful compilation is a function on the top of the stack. This function can then be executed with js_call.

通過調用js_loadstring或者js_loadfile接口編譯script腳本,編譯成功後的結果作爲函數保存在棧頂,此函數可以使用js_call來執行。

void js_loadstring(js_State *J, const char *filename, const char *source);
void js_loadfile(js_State *J, const char *filename);
Compile the script and push the resulting function.

編譯加載javascript腳本
J爲js_newstate創建的js_State指針,filename指定的js腳本,source腳本命令

int js_ploadstring(js_State *J, const char *filename, const char *source);
int js_ploadfile(js_State *J, const char *filename);
Like js_loadstring/js_loadfile but in a protected environment. In case of success, return 0 with the result as a function on the stack. In case of failure, return 1 with the error object on the stack.

這些接口函數類似於js_loadstring/js_loadfile,只在受保護的環境變量中。 如果執行成功,返回0,同樣作爲函數放在棧裏。如果失敗,返回1錯誤object放到棧裏。

Calling functions
函數調用

void js_call(js_State *J, int n);
To call a function, you must use the following protocol: 1) push the function to call onto the stack, 2) push the this value to be used by the function, 3) push the arguments to the function in order, 4) finally, call js_call with the number of arguments pushed in step 3.

爲了調用js腳本里的函數,你必須先執行下面的操作:
1)將需調用的函數壓入到棧裏–js_getglobal
2)將函數需要的this value壓入棧裏–js_pushxx,一般爲js_pushnull
3)按順序壓入函數參數–js_pushxx
4)最後,調用js_call指定第3步壓入參數的數量n

Pop the function, the this value, and all arguments; execute the function; then push the return value from the function.

調用js_call,在函數中包含這些操作
1、彈出函數,this value和所有參數;
2、執行函數;
3、將函數執行返回值壓棧。

void js_construct(js_State *J, int n);
The construct function implements the ‘new’ expression in Javascript. This is similar to js_call, but without pushing a this value: 1) push the constructor function to call onto the stack, 2) push the arguments to the constructor function in order, 3) finally, call js_construct with the number of arguments pushed in step 2.

此構造函數實現javascript中的new表達式; 類似js_call, 但無需壓入this value。步驟如下
1)將構造函數壓棧
2)將參數按需壓棧
3)最後,調用js_construct帶入參數個數n

int js_pcall(js_State *J, int n);
int js_pconstruct(js_State *J, int n);
Like js_call and js_construct but in a protected environment. In case of success, return 0 with the result on the stack. In case of failure, return 1 with the error object on the stack.

類似js_call和js_construct,包含異常處理。如果成功返回0,作爲結果放到棧中;如果失敗返回1,錯誤信息object放到棧中。

Script helpers
腳本幫助

There are two convenience functions for loading and executing code.

有兩種便利的函數用於加載和執行代碼

int js_dostring(js_State *J, const char *source);
Compile and execute the script in the zero-terminated string in source argument. If any errors occur, call the report callback function and return 1. Return 0 on success.

編譯和執行script腳本,source爲javascript腳本命令,是以0結尾的字符串。如果發生錯誤,此函數調用report上報異常,並返回1; 返回0表示成功。

int js_dofile(js_State *J, const char *filename);
Load the script from the file with the given filename, then compile and execute it. If any errors occur, call the report callback function and return 1. Return 0 on success.

加載filename指定的script腳本, 然後編譯並執行。如果發生錯誤,則調用report回調函數上報錯誤信息並返回1,成功返回0.
filename:指定的js腳本文件

Protected environments
受保護的環境

The js_try macro pushes a new protected environment and calls setjmp. If it returns true, an error has occurred. The protected environment has been popped and the error object is located on the top of the stack.

js_try宏函數將新的protected enviroment壓棧並調用setjmp跳轉。如果返回true時則有錯誤發生,那麼protected environment會被彈出,錯誤對象object保存在棧頂位置。

At the end of the code you want to run in the protected environment you must call js_endtry in order to pop the protected environment. Note: you should not call js_endtry when an error has occurred and you are in the true-branch of js_try.

在代碼的最後你想回到protected environment, 你必須調用js_endtry來彈出protected environment. 備註:如果有錯誤生成,你不能調用js_endtry並且你已經進入到js_try的true分支中。

Since the macro is a wrapper around setjmp, the usual restrictions apply. Use the following example as a guide for how to use js_try:

由於這個宏是圍繞setjmp進行封裝的, 所以一般的限制作用。舉個例子來看看如何使用js_try

if (js_try(J)) {
fprintf(stderr, “error: %s”, js_tostring(J, -1));
js_pop(J, 1);
return;
}
do_some_stuff();
js_endtry(J);

Most of the time you shouldn’t need to worry about protected environments. The functions prefixed with ‘p’ (js_pcall, js_ploadstring, etc) handle setting up the protected environment and return simple error codes.

大部分時間,你無需擔心protected environments這個環境變量,帶’p’的函數如js_pcall js_ploadstring等,會處理封裝這個處理功能並返回簡單的錯誤編碼。
請看js_pcall函數,中已經做過js_try處理。

int js_pcall(js_State *J, int n)
{
    int savetop = TOP - n - 2;
    if (js_try(J)) {
        /* clean up the stack to only hold the error object */
        STACK[savetop] = STACK[TOP-1];
        TOP = savetop + 1;
        return 1;
    }
    js_call(J, n);
    js_endtry(J);
    return 0;
}

Errors
錯誤處理

void js_throw(js_State *J);
Pop the error object on the top of the stack and return control flow to the most recent protected environment.

彈出錯誤棧頂的對象error object,返回控制流程到最新的protected environment

void js_newerror(js_State *J, const char *message);
void js_newevalerror(js_State *J, const char *message);
void js_newrangeerror(js_State *J, const char *message);
void js_newreferenceerror(js_State *J, const char *message);
void js_newsyntaxerror(js_State *J, const char *message);
void js_newtypeerror(js_State *J, const char *message);
void js_newurierror(js_State *J, const char *message);

Push a new error object on the stack. 將新的error object壓棧

void js_error(js_State *J, const char *fmt, …);
void js_evalerror(js_State *J, const char *fmt, …);
void js_rangeerror(js_State *J, const char *fmt, …);
void js_referenceerror(js_State *J, const char *fmt, …);
void js_syntaxerror(js_State *J, const char *fmt, …);
void js_typeerror(js_State *J, const char *fmt, …);
void js_urierror(js_State *J, const char *fmt, …);
Wrapper to push a new error object on the stack using a printf formatting string and call js_throw.

函數封裝,將錯誤對象error object壓棧同時格式化輸出string並調用js_throw

Stack manipulation
棧操作

int js_gettop(js_State *J);
void js_settop(js_State *J, int idx); – not implemented yet
void js_pop(js_State *J, int n); //n 彈出堆棧元素的數量
void js_rot(js_State *J, int n);
void js_copy(js_State *J, int idx); // idx 拷貝idx應的元素
void js_remove(js_State *J, int idx);
void js_insert(js_State *J, int idx); – not implemented yet
void js_replace(js_State* J, int idx); – not implemented yet

:idx如果爲正,則從棧底開始數,如果爲負責從棧頂開始數。所有mujs的idx參數都遵循這個原則,而且作用都是定位堆棧中對應序號的元素。
請看源碼

static js_Value *stackidx(js_State *J, int idx)
{
    static js_Value undefined = { {0}, {0}, JS_TUNDEFINED };
    idx = idx < 0 ? TOP + idx : BOT + idx; // 根據idx正負判斷起始
    if (idx < 0 || idx >= TOP)
        return &undefined;
    return STACK + idx;
}

Comparisons and arithmetic
比較和計算

void js_concat(js_State *J);
int js_compare(js_State *J, int *okay);
int js_equal(js_State *J);
int js_strictequal(js_State *J);
int js_instanceof(js_State *J);
The equivalent of the ‘+’, comparison, and instanceof operators. The okay argument to js_compare is set to 0 if any of the values are NaN, otherwise it is set to 1.

concat等價於’+’、compare、equal、strictequal是比較和instanceof operators。如果有值爲NaN參數okay被賦值爲0,否則爲1。

Primitive values
原始值(元值),(與wrapper values相對)

void js_pushundefined(js_State *J);
void js_pushnull(js_State *J);
void js_pushboolean(js_State *J, int v);
void js_pushnumber(js_State *J, double v);
void js_pushstring(js_State *J, const char *v);
void js_pushliteral(js_State *J, const char *v);
Push primitive values. js_pushstring makes a copy of the string, so it may be freed or changed after passing it in. js_pushliteral keeps a pointer to the string, so it must not be changed or freed after passing it in.

壓入元值(未封裝的值,即基本單元值)。js_pushstring函數賦值一份string的拷貝,因此當string壓棧後可以刪除或者修改。
js_pushliteral則保持指向string的指針,所以即使在壓入後也不能改動或者釋放,
注:類似c語言的指針傳參,在函數內部可以修改傳入參數的值。
Primitive 和 Wrapper說明:
http://blog.csdn.net/zt_soft/article/details/1437249

int js_isdefined(js_State *J, int idx);
int js_isundefined(js_State *J, int idx);
int js_isnull(js_State *J, int idx);
int js_isboolean(js_State *J, int idx);
int js_isnumber(js_State *J, int idx);
int js_isstring(js_State *J, int idx);
int js_isprimitive(js_State *J, int idx);
Test if a primitive value is of a given type.

檢查,判斷一個原始值是否爲給定的數據類型。

int js_toboolean(js_State *J, int idx);
double js_tonumber(js_State *J, int idx);
double js_tointeger(js_State *J, int idx);
int js_toint32(js_State *J, int idx);
unsigned int js_touint32(js_State *J, int idx);
short js_toint16(js_State *J, int idx);
unsigned short js_touint16(js_State *J, int idx);
const char *js_tostring(js_State *J, int idx);
Convert the value at the given index into a C value. If the value is an object, invoke the toString and/or valueOf methods to do the conversion.

類型轉換,將給定的類型轉換爲c值類型。如果值的類型是對象object,則調用toString以及(或者)valueOf的方法來執行轉換。

注:關於對象object的toString和valueOf函數,請參考鏈接
https://www.cnblogs.com/peakleo/p/6248242.html

The conversion may change the actual value in the stack!

轉換可能會改變棧中的實際值!

There is no guarantee that the pointer returned by js_tostring will be valid after the
corresponding value is removed from the stack.

如果棧中某一個值被移除,則無法保證調用js_tostring返回的字符串指針是有效的

Objects
對象
enum {
JS_REGEXP_G = 1,
JS_REGEXP_I = 2,
JS_REGEXP_M = 4,
};

void js_newobject(js_State *J);
void js_newarray(js_State *J);
void js_newboolean(js_State *J, int v);
void js_newnumber(js_State *J, double v);
void js_newstring(js_State *J, const char *v);
void js_newregexp(js_State *J, const char *pattern, int flags);
Creat and push objects on the stack.

創建並壓入對象到棧中,留意與js_pushnumber等的區別,這些都是作爲object來封裝壓入的,比如i=10 和t={i:10},都包含number,但後者是個object。

int js_isobject(js_State *J, int idx);
int js_isarray(js_State *J, int idx);
int js_iscallable(js_State *J, int idx);
int js_isregexp(js_State *J, int idx);
Test the type and class of an object on the stack.

測試棧中某一對象的類型

Properties
屬性(名值對)

The property functions all work on an object. If the stack slot referenced by the index does not contain an object, they will throw an error.
屬性相關函數都是針對object對象的,如果棧中的“槽位”沒有包含object對象,則會拋出異常。

enum {
JS_READONLY = 1,
JS_DONTENUM = 2,
JS_DONTCONF = 4,
};
Property attribute bit-mask values.

成員屬性對應的bit-mask值。

int js_hasproperty(js_State *J, int idx, const char *name);
If the object has a property with the given name, return 1 and push the value of the property; otherwise return 0 and leave the stack untouched.

在object的屬性列表中查找name的屬性,如果存在將對應的值壓入當前stack堆棧中並返回1;否則返回0,不對棧做任何操作並退出。
注:在查詢property後,如果返回1,我們可以直接通過js_toxxx(J, -1)獲得該property。

void js_getproperty(js_State *J, int idx, const char *name);
Push the value of the named property of the object. If the object does not have the named property, push undefined instead.

獲取object的名字爲name的屬性,將其壓入到stack堆棧中,如果對象不具備這個屬性,則壓入undefined代替。
注:這個函數一般與js_getglobal配套使用,由js_getglobal獲取object,object壓棧。
調用js_getproperty獲得object的屬性,idx取值:取第1個屬性時 idx = -1, 繼續取第2個時,idx=-2,第3個以此類推。原因是沒取一個屬性,就會將當前屬性壓棧,而object就會下沉一次。

void js_setproperty(js_State *J, int idx, const char *name);
Pop a value from the top of the stack and set the value of the named property of the object.

找到堆棧中idx的object,從棧頂彈出value值,將其與name綁定並加入到object的屬性鏈表中。
注:一般是先壓入需要設置的屬性值,比如js_pushnumber(J, 100), 再調用js_setproperty來設置屬性。idx一般爲-2,即棧頂爲value,下一個棧元素爲要設置屬性的object。

void js_defproperty(js_State *J, int idx, const char *name, int atts);
Pop a value from the top of the stack and set the value of the named property of the object. Also define the property attributes.

從棧頂彈出值,設置對象的屬性爲name對應的值,同時定義屬性

void js_defaccessor(js_State *J, int idx, const char *name, int atts);
Define the getter and setter attributes of a property on the object. Pop the two getter and setter functions from the stack. Use null instead of a function object if you want to leave any of the functions unset.

定義對象特性的getter和setter屬性, 從棧中彈出兩個getter和setter函數。如果你想從未設置的函數中離開則使用null來代替object

void js_delproperty(js_State *J, int idx, const char *name);
Delete the named property from the object.

刪除對象的name屬性。

Array properties
數組屬性

int js_getlength(js_State *J, int idx);
void js_setlength(js_State *J, int idx, int len);
Wrappers to get and set the “length” property of an object.

對象get和set length

int js_hasindex(js_State *J, int idx, int i);
void js_getindex(js_State *J, int idx, int i);
void js_setindex(js_State *J, int idx, int i);
void js_delindex(js_State *J, int idx, int i);
These array index functions functions are simple wrappers around the equivalent property functions. They convert the numeric index to a string to use as the property name.

這些帶序號的數組函數是對等價屬性函數的一種簡單封裝,他們將數組序號轉換爲string,轉換後的 string作爲屬性名稱來使用

Globals
全局global

void js_pushglobal(js_State *J);
Push the object representing the global environment record.

壓入對象object代表全局環境記錄

void js_getglobal(js_State *J, const char *name);
void js_setglobal(js_State *J, const char *name);
void js_defglobal(js_State *J, const char *name, int atts);
Wrappers around js_pushglobal and js_get/set/defproperty to read and write the values of global variables.

圍繞js_pushglobal進行封裝,js_get/set/defproperty讀寫全局變量的值,建議閱讀另一篇《MuJS官網示例講解–linux》

C Functions
c函數
封裝c函數,使得在javascript腳本中可以直接調用

void js_newcfunction(js_State *J, js_CFunction fun, const char *name, int length);
Push a function object wrapping a C function pointer.

壓入函數對象封裝爲c函數指針
參數說明
J–state對象
fun—函數指針,遵照js_CFunction定義來編寫
name–在javascript腳本對應的函數名稱
length–函數參數個數

The length argument is the number of arguments to the function. If the function is called with fewer arguments, the argument list will be padded with undefined.

參數的長度是函數參數的個數,如果函數的參數少於長度,則參數列表用undefined不全。

void js_newcconstructor(js_State *J,
js_CFunction fun, js_CFunction con,
const char *name, int length);
Pop the object to set as the “prototype” property for the constructor function object. Push a function object wrapping a C function pointer, allowing for separate function pointers for regular calls and ‘new’ operator calls.

彈出對象,以便爲構造函數對象設置“標準”屬性。壓入函數對象封裝成c函數指針,爲常規調用以及“new”對象操作而進行分離函數指針

void js_currentfunction(js_State *J);
Push the currently executing function object.

壓入當前正執行的函數對象

Userdata

typedef void (*js_Finalize)(js_State *J, void *data);
typedef int (*js_HasProperty)(js_State *J, void *data, const char *name);
typedef int (*js_Put)(js_State *J, void *data, const char *name);
typedef int (*js_Delete)(js_State *J, void *data, const char *name);

void js_newuserdata(js_State *J, const char *tag, void *data,
js_Finalize finalize);

void js_newuserdatax(js_State *J, const char *tag, void *data,
js_HasProperty has,
js_Put put,
js_Delete delete,
js_Finalize finalize);
Pop an object from the top of the stack to use as the internal prototype property for the new object. Push a new userdata object wrapping a pointer to C memory. The userdata object is tagged using a string, to represent the type of the C memory.

從棧頂彈出一個對象作爲一個新對象的內部標準屬性使用。壓入新的userdata對象封裝成指向c內存的指針。userdata對象用字符串作爲標籤,代表着c內存的某個類型

The finalize callback, if it is not NULL, will be called when the object is freed by the garbage collector.

finalize的回調,如果是NULL,則在對象被垃圾回收器釋放後會被調用

The extended function also has callback functions for overriding property accesses. If these are set, they can be used to override accesses to certain properties. Any property accesses that are not overridden will be handled as usual in the runtime. The “HasProperty” callback should push a value and return true if it wants to handle the property, otherwise it should do nothing and return false. “Put” should pop a value and return true if it wants to handle the property. Likewise, “Delete” should return true if it wants to handle the property.

擴展函數擁有一些回調函數,可以重寫原來的屬性。如果設置了回調,它們可以用來修改某些屬性。任何未覆蓋的屬性訪問會作一般的處理。”HasProperty”回調函數如果想要處理屬性,則需要壓入值並返回true,否則不做任何處理並返回false.”put”函數如果需要操作屬性則要彈出值成功返回true。同樣的,”Delete”函數如果要處理屬性也要返回true。

int js_isuserdata(js_State *J, int idx, const char *tag);
Test if an object is a userdata object with the given type tag string.

測試某一對象object是否爲給定string標籤的usedata對象

void *js_touserdata(js_State *J, int idx, const char *tag);
Return the wrapped pointer from a userdata object. If the object is undefined or null, return NULL. If the object is not a userdata object with the given type tag string, throw a type error.

返回已經封裝成指針的userdata對象。如果對象是undefined或者null,返回NULL。如果對象不是給定類型標籤的userdata,則拋出異常。

Registry
註冊表

The registry can be used to store references to Javascript objects accessible from C, but hidden from Javascript to prevent tampering.

註冊表可用於存儲對C可訪問的JavaScript對象的引用,但隱藏在JavaScript中以防止篡改

void js_getregistry(js_State *J, const char *name);
void js_setregistry(js_State *J, const char *name);
void js_delregistry(js_State *J, const char *name);
Access properties on the hidden registry object.

在隱藏註冊表對象上訪問屬性

const char *js_ref(js_State *J);
WIP: Pop a value from the stack and store it in the registry using a new unique property name. Return the property name.

從棧中彈出值,使用一個新的唯一屬性保存到註冊表。 返回屬性名稱。

void js_unref(js_State *J, const char *ref);
WIP: Delete the reference from the registry.

刪除註冊表中的引用

想繼續學習MuJS,可以看看下一篇的官網示例講解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章