js.core: Change vdl go codegen to emit __VDLInit funcs.

Fixes a subtle init-ordering issue in vdl-generated go code.  The
basic problem looks something like this; there are many variants
to this problem, this is just one simple example:

// User's file a.go
package foo
import "v.io/v23/vdl"
var myType := vdl.TypeOf(FooType{})

// Generated file foo.vdl.go
package foo
import "v.io/v23/vdl"
func init() {
vdl.RegisterNative(FooToNative, FooFromNative)
}

The problem is that the vdl.RegisterNative call must occur before
the vdl.TypeOf call, so that the vdl package knows about native
types, and can analyze the type correctly.  But init funcs are
always processed after all package-level variables have been
initialized, so we get the wrong order above.

We fix that by moving all initialization into a generated
__VDLInit func, with a trick to turn it into a var
initialization.  Note that we still haven't fixed the above
example, since the package-level vars in a.go are typically
processed before foo.vdl.go.  In the rare case where this
happens, the user can add a call to __VDLInit in a var
initializer early in their a.go file.

Similar problems existed with vom.RawBytesOf, and the
manually-generated types we were storing in package-level vars.

The new strategy is to put all ordering-dependent init logic in
__VDLInit, and to ensure that the order that we call things
within the function is correct.  We also sort types, consts and
interfaces in the compiler as best we can.  Note that sorting
types isn't strictly required (or meaningful), since we allow
cyclic types.  But it still might be nice for some generated
languages.

There are further cleanups possible; we can probably add
error-checking more methodically for cases like above where the
user needs to add a call to __VDLInit, and we should replace the
long hex hash for generated type names to a simple counter.  But
that'll occur in a separate CL; this is the more important one.

MultiPart: 4/6

Change-Id: I746ffa1db20fa8002f17f323d284e69803c02652
6 files changed
tree: ff4dd4ff7de012216f12267346d5f21ff4327908
  1. extension/
  2. go/
  3. jsdocs/
  4. src/
  5. test/
  6. .gitattributes
  7. .gitignore
  8. .jshintignore
  9. .jshintrc
  10. .npmignore
  11. AUTHORS
  12. CONTRIBUTING.md
  13. CONTRIBUTORS
  14. LICENSE
  15. Makefile
  16. package.json
  17. PATENTS
  18. README.md
  19. VERSION
README.md

Vanadium JavaScript

This repository defines the JavaScript API for Vanadium. The client and server APIs defined here work both in Node.js and the browser.

Install

npm install --save vanadium/js

Usage

The entry point to the API is through a module called vanadium, everything else is considered private and should not be accessed by the users of the API.

The vanadium module is exported as a global in the browser JavaScript library and for Browserify and Node.js the “main” property in the package.json points to /src/vanadium making it the index module and therefore Browserify and Node.js users can gain access to the API with:

var vanadium = require("vanadium");

One of the goals of this project is to only write the code once and have it run in both Node.js and browsers. Therefore, specific build and testing steps have been designed in the project to ensure this goal.

When run in a browser, vanadium.js expects that the vanadium extension will be installed.

Bugs and feature requests

Bugs and feature requests should be filed in the Vanadium issue tracker.

Building and testing

GNU Make is used to build and test Vanadium.

Build everything:

make build

Test everything:

make test

Run a specific test suite:

make test-unit
make test-unit-node
make test-unit-browser

make test-integration
make test-integration-node
make test-integration-browser

Remove all build and testing artifacts:

make clean